~ubuntu-branches/ubuntu/oneiric/libav/oneiric

« back to all changes in this revision

Viewing changes to libavformat/nutenc.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2011-04-30 14:27:42 UTC
  • mfrom: (1.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20110430142742-quvblxk1tj6adlh5
Tags: 4:0.7~b1-1ubuntu1
* Merge from debian. Remaining changes:
  - don't build against libfaad, libdirac, librtmp and libopenjpeg
    (all in universe)
  - explicitly --enable-pic on powerpc, cf. LP #654666
  - different arm configure bits that should probably better be
    merged into debian
* Cherry-picked from git: 
  - install doc/APIChanges and refer to them in NEWS.Debian (Closes: #623682)
  - don't try to install non-existing documentation, fixes FTBFS on powerpc

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * nut muxer
3
3
 * Copyright (c) 2004-2007 Michael Niedermayer
4
4
 *
5
 
 * This file is part of FFmpeg.
 
5
 * This file is part of Libav.
6
6
 *
7
 
 * FFmpeg is free software; you can redistribute it and/or
 
7
 * Libav is free software; you can redistribute it and/or
8
8
 * modify it under the terms of the GNU Lesser General Public
9
9
 * License as published by the Free Software Foundation; either
10
10
 * version 2.1 of the License, or (at your option) any later version.
11
11
 *
12
 
 * FFmpeg is distributed in the hope that it will be useful,
 
12
 * Libav is distributed in the hope that it will be useful,
13
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
15
 * Lesser General Public License for more details.
16
16
 *
17
17
 * You should have received a copy of the GNU Lesser General Public
18
 
 * License along with FFmpeg; if not, write to the Free Software
 
18
 * License along with Libav; if not, write to the Free Software
19
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
20
 */
21
21
 
23
23
#include "libavutil/tree.h"
24
24
#include "libavcodec/mpegaudiodata.h"
25
25
#include "nut.h"
 
26
#include "internal.h"
 
27
#include "avio_internal.h"
26
28
 
27
29
static int find_expected_header(AVCodecContext *c, int size, int key_frame, uint8_t out[64]){
28
30
    int sample_rate= c->sample_rate;
240
242
    nut->frame_code['N'].flags= FLAG_INVALID;
241
243
}
242
244
 
243
 
/**
244
 
 * Gets the length in bytes which is needed to store val as v.
245
 
 */
246
 
static int get_length(uint64_t val){
247
 
    int i=1;
248
 
 
249
 
    while(val>>=7)
250
 
        i++;
251
 
 
252
 
    return i;
253
 
}
254
 
 
255
 
static void put_v(ByteIOContext *bc, uint64_t val){
256
 
    int i= get_length(val);
257
 
 
258
 
    while(--i>0)
259
 
        put_byte(bc, 128 | (val>>(7*i)));
260
 
 
261
 
    put_byte(bc, val&127);
262
 
}
263
 
 
264
 
static void put_tt(NUTContext *nut, StreamContext *nus, ByteIOContext *bc, uint64_t val){
 
245
static void put_tt(NUTContext *nut, AVRational *time_base, AVIOContext *bc, uint64_t val){
265
246
    val *= nut->time_base_count;
266
 
    val += nus->time_base - nut->time_base;
267
 
    put_v(bc, val);
 
247
    val += time_base - nut->time_base;
 
248
    ff_put_v(bc, val);
268
249
}
269
250
 
270
251
/**
271
 
 * Stores a string as vb.
 
252
 * Store a string as vb.
272
253
 */
273
 
static void put_str(ByteIOContext *bc, const char *string){
 
254
static void put_str(AVIOContext *bc, const char *string){
274
255
    int len= strlen(string);
275
256
 
276
 
    put_v(bc, len);
277
 
    put_buffer(bc, string, len);
 
257
    ff_put_v(bc, len);
 
258
    avio_write(bc, string, len);
278
259
}
279
260
 
280
 
static void put_s(ByteIOContext *bc, int64_t val){
281
 
    put_v(bc, 2*FFABS(val) - (val>0));
 
261
static void put_s(AVIOContext *bc, int64_t val){
 
262
    ff_put_v(bc, 2*FFABS(val) - (val>0));
282
263
}
283
264
 
284
265
#ifdef TRACE
285
 
static inline void put_v_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){
286
 
    av_log(NULL, AV_LOG_DEBUG, "put_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
 
266
static inline void ff_put_v_trace(AVIOContext *bc, uint64_t v, char *file, char *func, int line){
 
267
    av_log(NULL, AV_LOG_DEBUG, "ff_put_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
287
268
 
288
 
    put_v(bc, v);
 
269
    ff_put_v(bc, v);
289
270
}
290
271
 
291
 
static inline void put_s_trace(ByteIOContext *bc, int64_t v, char *file, char *func, int line){
 
272
static inline void put_s_trace(AVIOContext *bc, int64_t v, char *file, char *func, int line){
292
273
    av_log(NULL, AV_LOG_DEBUG, "put_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line);
293
274
 
294
275
    put_s(bc, v);
295
276
}
296
 
#define put_v(bc, v)  put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 
277
#define ff_put_v(bc, v)  ff_put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
297
278
#define put_s(bc, v)  put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
298
279
#endif
299
280
 
300
281
//FIXME remove calculate_checksum
301
 
static void put_packet(NUTContext *nut, ByteIOContext *bc, ByteIOContext *dyn_bc, int calculate_checksum, uint64_t startcode){
 
282
static void put_packet(NUTContext *nut, AVIOContext *bc, AVIOContext *dyn_bc, int calculate_checksum, uint64_t startcode){
302
283
    uint8_t *dyn_buf=NULL;
303
 
    int dyn_size= url_close_dyn_buf(dyn_bc, &dyn_buf);
 
284
    int dyn_size= avio_close_dyn_buf(dyn_bc, &dyn_buf);
304
285
    int forw_ptr= dyn_size + 4*calculate_checksum;
305
286
 
306
287
    if(forw_ptr > 4096)
307
 
        init_checksum(bc, ff_crc04C11DB7_update, 0);
308
 
    put_be64(bc, startcode);
309
 
    put_v(bc, forw_ptr);
 
288
        ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
 
289
    avio_wb64(bc, startcode);
 
290
    ff_put_v(bc, forw_ptr);
310
291
    if(forw_ptr > 4096)
311
 
        put_le32(bc, get_checksum(bc));
 
292
        avio_wl32(bc, ffio_get_checksum(bc));
312
293
 
313
294
    if(calculate_checksum)
314
 
        init_checksum(bc, ff_crc04C11DB7_update, 0);
315
 
    put_buffer(bc, dyn_buf, dyn_size);
 
295
        ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
 
296
    avio_write(bc, dyn_buf, dyn_size);
316
297
    if(calculate_checksum)
317
 
        put_le32(bc, get_checksum(bc));
 
298
        avio_wl32(bc, ffio_get_checksum(bc));
318
299
 
319
300
    av_free(dyn_buf);
320
301
}
321
302
 
322
 
static void write_mainheader(NUTContext *nut, ByteIOContext *bc){
 
303
static void write_mainheader(NUTContext *nut, AVIOContext *bc){
323
304
    int i, j, tmp_pts, tmp_flags, tmp_stream, tmp_mul, tmp_size, tmp_fields, tmp_head_idx;
324
305
    int64_t tmp_match;
325
306
 
326
 
    put_v(bc, 3); /* version */
327
 
    put_v(bc, nut->avf->nb_streams);
328
 
    put_v(bc, nut->max_distance);
329
 
    put_v(bc, nut->time_base_count);
 
307
    ff_put_v(bc, 3); /* version */
 
308
    ff_put_v(bc, nut->avf->nb_streams);
 
309
    ff_put_v(bc, nut->max_distance);
 
310
    ff_put_v(bc, nut->time_base_count);
330
311
 
331
312
    for(i=0; i<nut->time_base_count; i++){
332
 
        put_v(bc, nut->time_base[i].num);
333
 
        put_v(bc, nut->time_base[i].den);
 
313
        ff_put_v(bc, nut->time_base[i].num);
 
314
        ff_put_v(bc, nut->time_base[i].den);
334
315
    }
335
316
 
336
317
    tmp_pts=0;
372
353
        }
373
354
        if(j != tmp_mul - tmp_size) tmp_fields=6;
374
355
 
375
 
        put_v(bc, tmp_flags);
376
 
        put_v(bc, tmp_fields);
 
356
        ff_put_v(bc, tmp_flags);
 
357
        ff_put_v(bc, tmp_fields);
377
358
        if(tmp_fields>0) put_s(bc, tmp_pts);
378
 
        if(tmp_fields>1) put_v(bc, tmp_mul);
379
 
        if(tmp_fields>2) put_v(bc, tmp_stream);
380
 
        if(tmp_fields>3) put_v(bc, tmp_size);
381
 
        if(tmp_fields>4) put_v(bc, 0 /*tmp_res*/);
382
 
        if(tmp_fields>5) put_v(bc, j);
383
 
        if(tmp_fields>6) put_v(bc, tmp_match);
384
 
        if(tmp_fields>7) put_v(bc, tmp_head_idx);
 
359
        if(tmp_fields>1) ff_put_v(bc, tmp_mul);
 
360
        if(tmp_fields>2) ff_put_v(bc, tmp_stream);
 
361
        if(tmp_fields>3) ff_put_v(bc, tmp_size);
 
362
        if(tmp_fields>4) ff_put_v(bc, 0 /*tmp_res*/);
 
363
        if(tmp_fields>5) ff_put_v(bc, j);
 
364
        if(tmp_fields>6) ff_put_v(bc, tmp_match);
 
365
        if(tmp_fields>7) ff_put_v(bc, tmp_head_idx);
385
366
    }
386
 
    put_v(bc, nut->header_count-1);
 
367
    ff_put_v(bc, nut->header_count-1);
387
368
    for(i=1; i<nut->header_count; i++){
388
 
        put_v(bc, nut->header_len[i]);
389
 
        put_buffer(bc, nut->header[i], nut->header_len[i]);
 
369
        ff_put_v(bc, nut->header_len[i]);
 
370
        avio_write(bc, nut->header[i], nut->header_len[i]);
390
371
    }
391
372
}
392
373
 
393
 
static int write_streamheader(NUTContext *nut, ByteIOContext *bc, AVStream *st, int i){
 
374
static int write_streamheader(AVFormatContext *avctx, AVIOContext *bc, AVStream *st, int i){
 
375
    NUTContext *nut = avctx->priv_data;
394
376
    AVCodecContext *codec = st->codec;
395
 
    put_v(bc, i);
 
377
    ff_put_v(bc, i);
396
378
    switch(codec->codec_type){
397
 
    case AVMEDIA_TYPE_VIDEO: put_v(bc, 0); break;
398
 
    case AVMEDIA_TYPE_AUDIO: put_v(bc, 1); break;
399
 
    case AVMEDIA_TYPE_SUBTITLE: put_v(bc, 2); break;
400
 
    default              : put_v(bc, 3); break;
 
379
    case AVMEDIA_TYPE_VIDEO: ff_put_v(bc, 0); break;
 
380
    case AVMEDIA_TYPE_AUDIO: ff_put_v(bc, 1); break;
 
381
    case AVMEDIA_TYPE_SUBTITLE: ff_put_v(bc, 2); break;
 
382
    default              : ff_put_v(bc, 3); break;
401
383
    }
402
 
    put_v(bc, 4);
 
384
    ff_put_v(bc, 4);
403
385
    if (codec->codec_tag){
404
 
        put_le32(bc, codec->codec_tag);
405
 
    }else
406
 
        return -1;
407
 
 
408
 
    put_v(bc, nut->stream[i].time_base - nut->time_base);
409
 
    put_v(bc, nut->stream[i].msb_pts_shift);
410
 
    put_v(bc, nut->stream[i].max_pts_distance);
411
 
    put_v(bc, codec->has_b_frames);
412
 
    put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
413
 
 
414
 
    put_v(bc, codec->extradata_size);
415
 
    put_buffer(bc, codec->extradata, codec->extradata_size);
 
386
        avio_wl32(bc, codec->codec_tag);
 
387
    } else {
 
388
        av_log(avctx, AV_LOG_ERROR, "No codec tag defined for stream %d\n", i);
 
389
        return AVERROR(EINVAL);
 
390
    }
 
391
 
 
392
    ff_put_v(bc, nut->stream[i].time_base - nut->time_base);
 
393
    ff_put_v(bc, nut->stream[i].msb_pts_shift);
 
394
    ff_put_v(bc, nut->stream[i].max_pts_distance);
 
395
    ff_put_v(bc, codec->has_b_frames);
 
396
    avio_w8(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
 
397
 
 
398
    ff_put_v(bc, codec->extradata_size);
 
399
    avio_write(bc, codec->extradata, codec->extradata_size);
416
400
 
417
401
    switch(codec->codec_type){
418
402
    case AVMEDIA_TYPE_AUDIO:
419
 
        put_v(bc, codec->sample_rate);
420
 
        put_v(bc, 1);
421
 
        put_v(bc, codec->channels);
 
403
        ff_put_v(bc, codec->sample_rate);
 
404
        ff_put_v(bc, 1);
 
405
        ff_put_v(bc, codec->channels);
422
406
        break;
423
407
    case AVMEDIA_TYPE_VIDEO:
424
 
        put_v(bc, codec->width);
425
 
        put_v(bc, codec->height);
 
408
        ff_put_v(bc, codec->width);
 
409
        ff_put_v(bc, codec->height);
426
410
 
427
411
        if(st->sample_aspect_ratio.num<=0 || st->sample_aspect_ratio.den<=0){
428
 
            put_v(bc, 0);
429
 
            put_v(bc, 0);
 
412
            ff_put_v(bc, 0);
 
413
            ff_put_v(bc, 0);
430
414
        }else{
431
 
            put_v(bc, st->sample_aspect_ratio.num);
432
 
            put_v(bc, st->sample_aspect_ratio.den);
 
415
            ff_put_v(bc, st->sample_aspect_ratio.num);
 
416
            ff_put_v(bc, st->sample_aspect_ratio.den);
433
417
        }
434
 
        put_v(bc, 0); /* csp type -- unknown */
 
418
        ff_put_v(bc, 0); /* csp type -- unknown */
435
419
        break;
436
420
    default:
437
421
        break;
439
423
    return 0;
440
424
}
441
425
 
442
 
static int add_info(ByteIOContext *bc, const char *type, const char *value){
 
426
static int add_info(AVIOContext *bc, const char *type, const char *value){
443
427
    put_str(bc, type);
444
428
    put_s(bc, -1);
445
429
    put_str(bc, value);
446
430
    return 1;
447
431
}
448
432
 
449
 
static int write_globalinfo(NUTContext *nut, ByteIOContext *bc){
 
433
static int write_globalinfo(NUTContext *nut, AVIOContext *bc){
450
434
    AVFormatContext *s= nut->avf;
451
435
    AVMetadataTag *t = NULL;
452
 
    ByteIOContext *dyn_bc;
 
436
    AVIOContext *dyn_bc;
453
437
    uint8_t *dyn_buf=NULL;
454
438
    int count=0, dyn_size;
455
 
    int ret = url_open_dyn_buf(&dyn_bc);
 
439
    int ret = avio_open_dyn_buf(&dyn_bc);
456
440
    if(ret < 0)
457
441
        return ret;
458
442
 
459
443
    while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
460
444
        count += add_info(dyn_bc, t->key, t->value);
461
445
 
462
 
    put_v(bc, 0); //stream_if_plus1
463
 
    put_v(bc, 0); //chapter_id
464
 
    put_v(bc, 0); //timestamp_start
465
 
    put_v(bc, 0); //length
466
 
 
467
 
    put_v(bc, count);
468
 
 
469
 
    dyn_size= url_close_dyn_buf(dyn_bc, &dyn_buf);
470
 
    put_buffer(bc, dyn_buf, dyn_size);
 
446
    ff_put_v(bc, 0); //stream_if_plus1
 
447
    ff_put_v(bc, 0); //chapter_id
 
448
    ff_put_v(bc, 0); //timestamp_start
 
449
    ff_put_v(bc, 0); //length
 
450
 
 
451
    ff_put_v(bc, count);
 
452
 
 
453
    dyn_size= avio_close_dyn_buf(dyn_bc, &dyn_buf);
 
454
    avio_write(bc, dyn_buf, dyn_size);
471
455
    av_free(dyn_buf);
472
456
    return 0;
473
457
}
474
458
 
475
 
static int write_streaminfo(NUTContext *nut, ByteIOContext *bc, int stream_id){
 
459
static int write_streaminfo(NUTContext *nut, AVIOContext *bc, int stream_id){
476
460
    AVFormatContext *s= nut->avf;
477
461
    AVStream* st = s->streams[stream_id];
478
 
    ByteIOContext *dyn_bc;
 
462
    AVIOContext *dyn_bc;
479
463
    uint8_t *dyn_buf=NULL;
480
464
    int count=0, dyn_size, i;
481
 
    int ret = url_open_dyn_buf(&dyn_bc);
 
465
    int ret = avio_open_dyn_buf(&dyn_bc);
482
466
    if(ret < 0)
483
467
        return ret;
484
468
 
486
470
        if (st->disposition & ff_nut_dispositions[i].flag)
487
471
            count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str);
488
472
    }
489
 
    dyn_size = url_close_dyn_buf(dyn_bc, &dyn_buf);
 
473
    dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
490
474
 
491
475
    if (count) {
492
 
        put_v(bc, stream_id + 1); //stream_id_plus1
493
 
        put_v(bc, 0); //chapter_id
494
 
        put_v(bc, 0); //timestamp_start
495
 
        put_v(bc, 0); //length
496
 
 
497
 
        put_v(bc, count);
498
 
 
499
 
        put_buffer(bc, dyn_buf, dyn_size);
 
476
        ff_put_v(bc, stream_id + 1); //stream_id_plus1
 
477
        ff_put_v(bc, 0); //chapter_id
 
478
        ff_put_v(bc, 0); //timestamp_start
 
479
        ff_put_v(bc, 0); //length
 
480
 
 
481
        ff_put_v(bc, count);
 
482
 
 
483
        avio_write(bc, dyn_buf, dyn_size);
500
484
    }
501
485
 
502
486
    av_free(dyn_buf);
503
487
    return count;
504
488
}
505
489
 
506
 
static int write_headers(NUTContext *nut, ByteIOContext *bc){
507
 
    ByteIOContext *dyn_bc;
 
490
static int write_chapter(NUTContext *nut, AVIOContext *bc, int id)
 
491
{
 
492
    AVIOContext *dyn_bc;
 
493
    uint8_t *dyn_buf = NULL;
 
494
    AVMetadataTag *t = NULL;
 
495
    AVChapter *ch    = nut->avf->chapters[id];
 
496
    int ret, dyn_size, count = 0;
 
497
 
 
498
    ret = avio_open_dyn_buf(&dyn_bc);
 
499
    if (ret < 0)
 
500
        return ret;
 
501
 
 
502
    ff_put_v(bc, 0);                                        // stream_id_plus1
 
503
    put_s(bc, id + 1);                                      // chapter_id
 
504
    put_tt(nut, nut->chapter[id].time_base, bc, ch->start); // chapter_start
 
505
    ff_put_v(bc, ch->end - ch->start);                      // chapter_len
 
506
 
 
507
    while ((t = av_metadata_get(ch->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
 
508
        count += add_info(dyn_bc, t->key, t->value);
 
509
 
 
510
    ff_put_v(bc, count);
 
511
 
 
512
    dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
 
513
    avio_write(bc, dyn_buf, dyn_size);
 
514
    av_freep(&dyn_buf);
 
515
    return 0;
 
516
}
 
517
 
 
518
static int write_headers(AVFormatContext *avctx, AVIOContext *bc){
 
519
    NUTContext *nut = avctx->priv_data;
 
520
    AVIOContext *dyn_bc;
508
521
    int i, ret;
509
522
 
510
 
    ret = url_open_dyn_buf(&dyn_bc);
 
523
    ff_metadata_conv_ctx(avctx, ff_nut_metadata_conv, NULL);
 
524
 
 
525
    ret = avio_open_dyn_buf(&dyn_bc);
511
526
    if(ret < 0)
512
527
        return ret;
513
528
    write_mainheader(nut, dyn_bc);
514
529
    put_packet(nut, bc, dyn_bc, 1, MAIN_STARTCODE);
515
530
 
516
531
    for (i=0; i < nut->avf->nb_streams; i++){
517
 
        ret = url_open_dyn_buf(&dyn_bc);
 
532
        ret = avio_open_dyn_buf(&dyn_bc);
518
533
        if(ret < 0)
519
534
            return ret;
520
 
        write_streamheader(nut, dyn_bc, nut->avf->streams[i], i);
 
535
        if ((ret = write_streamheader(avctx, dyn_bc, nut->avf->streams[i], i)) < 0)
 
536
            return ret;
521
537
        put_packet(nut, bc, dyn_bc, 1, STREAM_STARTCODE);
522
538
    }
523
539
 
524
 
    ret = url_open_dyn_buf(&dyn_bc);
 
540
    ret = avio_open_dyn_buf(&dyn_bc);
525
541
    if(ret < 0)
526
542
        return ret;
527
543
    write_globalinfo(nut, dyn_bc);
528
544
    put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
529
545
 
530
546
    for (i = 0; i < nut->avf->nb_streams; i++) {
531
 
        ret = url_open_dyn_buf(&dyn_bc);
 
547
        ret = avio_open_dyn_buf(&dyn_bc);
532
548
        if(ret < 0)
533
549
            return ret;
534
550
        ret = write_streaminfo(nut, dyn_bc, i);
538
554
            put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
539
555
        else {
540
556
            uint8_t* buf;
541
 
            url_close_dyn_buf(dyn_bc, &buf);
 
557
            avio_close_dyn_buf(dyn_bc, &buf);
542
558
            av_free(buf);
543
559
        }
544
560
    }
545
561
 
 
562
    for (i = 0; i < nut->avf->nb_chapters; i++) {
 
563
        ret = avio_open_dyn_buf(&dyn_bc);
 
564
        if (ret < 0)
 
565
            return ret;
 
566
        ret = write_chapter(nut, dyn_bc, i);
 
567
        if (ret < 0) {
 
568
            uint8_t *buf;
 
569
            avio_close_dyn_buf(dyn_bc, &buf);
 
570
            av_freep(&buf);
 
571
            return ret;
 
572
        }
 
573
        put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
 
574
    }
 
575
 
546
576
    nut->last_syncpoint_pos= INT_MIN;
547
577
    nut->header_count++;
548
578
    return 0;
550
580
 
551
581
static int write_header(AVFormatContext *s){
552
582
    NUTContext *nut = s->priv_data;
553
 
    ByteIOContext *bc = s->pb;
554
 
    int i, j;
 
583
    AVIOContext *bc = s->pb;
 
584
    int i, j, ret;
555
585
 
556
586
    nut->avf= s;
557
587
 
558
588
    nut->stream   = av_mallocz(sizeof(StreamContext)*s->nb_streams);
559
 
    nut->time_base= av_mallocz(sizeof(AVRational   )*s->nb_streams);
 
589
    nut->chapter  = av_mallocz(sizeof(ChapterContext)*s->nb_chapters);
 
590
    nut->time_base= av_mallocz(sizeof(AVRational   )*(s->nb_streams +
 
591
                                                      s->nb_chapters));
560
592
 
561
593
    for(i=0; i<s->nb_streams; i++){
562
594
        AVStream *st= s->streams[i];
576
608
        if(j==nut->time_base_count)
577
609
            nut->time_base_count++;
578
610
 
579
 
        if(av_q2d(time_base) >= 0.001)
 
611
        if(INT64_C(1000) * time_base.num >= time_base.den)
580
612
            nut->stream[i].msb_pts_shift = 7;
581
613
        else
582
614
            nut->stream[i].msb_pts_shift = 14;
583
 
        nut->stream[i].max_pts_distance= FFMAX(1/av_q2d(time_base), 1);
 
615
        nut->stream[i].max_pts_distance= FFMAX(time_base.den, time_base.num) / time_base.num;
 
616
    }
 
617
 
 
618
    for (i = 0; i < s->nb_chapters; i++) {
 
619
        AVChapter *ch = s->chapters[i];
 
620
 
 
621
        for (j = 0; j < nut->time_base_count; j++) {
 
622
            if (!memcmp(&ch->time_base, &nut->time_base[j], sizeof(AVRational)))
 
623
                break;
 
624
        }
 
625
 
 
626
        nut->time_base[j] = ch->time_base;
 
627
        nut->chapter[i].time_base = &nut->time_base[j];
 
628
        if(j == nut->time_base_count)
 
629
            nut->time_base_count++;
584
630
    }
585
631
 
586
632
    nut->max_distance = MAX_DISTANCE;
588
634
    build_frame_code(s);
589
635
    assert(nut->frame_code['N'].flags == FLAG_INVALID);
590
636
 
591
 
    put_buffer(bc, ID_STRING, strlen(ID_STRING));
592
 
    put_byte(bc, 0);
593
 
 
594
 
    write_headers(nut, bc);
595
 
 
596
 
    put_flush_packet(bc);
 
637
    avio_write(bc, ID_STRING, strlen(ID_STRING));
 
638
    avio_w8(bc, 0);
 
639
 
 
640
    if ((ret = write_headers(s, bc)) < 0)
 
641
        return ret;
 
642
 
 
643
    avio_flush(bc);
597
644
 
598
645
    //FIXME index
599
646
 
640
687
static int write_packet(AVFormatContext *s, AVPacket *pkt){
641
688
    NUTContext *nut = s->priv_data;
642
689
    StreamContext *nus= &nut->stream[pkt->stream_index];
643
 
    ByteIOContext *bc = s->pb, *dyn_bc;
 
690
    AVIOContext *bc = s->pb, *dyn_bc;
644
691
    FrameCode *fc;
645
692
    int64_t coded_pts;
646
693
    int best_length, frame_code, flags, needed_flags, i, header_idx, best_header_idx;
651
698
    if(pkt->pts < 0)
652
699
        return -1;
653
700
 
654
 
    if(1LL<<(20+3*nut->header_count) <= url_ftell(bc))
655
 
        write_headers(nut, bc);
 
701
    if(1LL<<(20+3*nut->header_count) <= avio_tell(bc))
 
702
        write_headers(s, bc);
656
703
 
657
704
    if(key_frame && !(nus->last_flags & FLAG_KEY))
658
705
        store_sp= 1;
659
706
 
660
 
    if(pkt->size + 30/*FIXME check*/ + url_ftell(bc) >= nut->last_syncpoint_pos + nut->max_distance)
 
707
    if(pkt->size + 30/*FIXME check*/ + avio_tell(bc) >= nut->last_syncpoint_pos + nut->max_distance)
661
708
        store_sp= 1;
662
709
 
663
710
//FIXME: Ensure store_sp is 1 in the first place.
680
727
        sp= av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
681
728
                         NULL);
682
729
 
683
 
        nut->last_syncpoint_pos= url_ftell(bc);
684
 
        ret = url_open_dyn_buf(&dyn_bc);
 
730
        nut->last_syncpoint_pos= avio_tell(bc);
 
731
        ret = avio_open_dyn_buf(&dyn_bc);
685
732
        if(ret < 0)
686
733
            return ret;
687
 
        put_tt(nut, nus, dyn_bc, pkt->dts);
688
 
        put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos)>>4 : 0);
 
734
        put_tt(nut, nus->time_base, dyn_bc, pkt->dts);
 
735
        ff_put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos)>>4 : 0);
689
736
        put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE);
690
737
 
691
738
        ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0/*unused*/, pkt->dts);
721
768
            continue;
722
769
 
723
770
        if(flags & FLAG_STREAM_ID)
724
 
            length+= get_length(pkt->stream_index);
 
771
            length+= ff_get_v_length(pkt->stream_index);
725
772
 
726
773
        if(pkt->size % fc->size_mul != fc->size_lsb)
727
774
            continue;
728
775
        if(flags & FLAG_SIZE_MSB)
729
 
            length += get_length(pkt->size / fc->size_mul);
 
776
            length += ff_get_v_length(pkt->size / fc->size_mul);
730
777
 
731
778
        if(flags & FLAG_CHECKSUM)
732
779
            length+=4;
733
780
 
734
781
        if(flags & FLAG_CODED_PTS)
735
 
            length += get_length(coded_pts);
 
782
            length += ff_get_v_length(coded_pts);
736
783
 
737
784
        if(   (flags & FLAG_CODED)
738
785
           && nut->header_len[best_header_idx] > nut->header_len[fc->header_idx]+1){
760
807
    needed_flags= get_needed_flags(nut, nus, fc, pkt);
761
808
    header_idx= fc->header_idx;
762
809
 
763
 
    init_checksum(bc, ff_crc04C11DB7_update, 0);
764
 
    put_byte(bc, frame_code);
 
810
    ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);
 
811
    avio_w8(bc, frame_code);
765
812
    if(flags & FLAG_CODED){
766
 
        put_v(bc, (flags^needed_flags) & ~(FLAG_CODED));
 
813
        ff_put_v(bc, (flags^needed_flags) & ~(FLAG_CODED));
767
814
        flags = needed_flags;
768
815
    }
769
 
    if(flags & FLAG_STREAM_ID)  put_v(bc, pkt->stream_index);
770
 
    if(flags & FLAG_CODED_PTS)  put_v(bc, coded_pts);
771
 
    if(flags & FLAG_SIZE_MSB)   put_v(bc, pkt->size / fc->size_mul);
772
 
    if(flags & FLAG_HEADER_IDX) put_v(bc, header_idx= best_header_idx);
773
 
 
774
 
    if(flags & FLAG_CHECKSUM)   put_le32(bc, get_checksum(bc));
775
 
    else                        get_checksum(bc);
776
 
 
777
 
    put_buffer(bc, pkt->data + nut->header_len[header_idx], pkt->size - nut->header_len[header_idx]);
 
816
    if(flags & FLAG_STREAM_ID)  ff_put_v(bc, pkt->stream_index);
 
817
    if(flags & FLAG_CODED_PTS)  ff_put_v(bc, coded_pts);
 
818
    if(flags & FLAG_SIZE_MSB)   ff_put_v(bc, pkt->size / fc->size_mul);
 
819
    if(flags & FLAG_HEADER_IDX) ff_put_v(bc, header_idx= best_header_idx);
 
820
 
 
821
    if(flags & FLAG_CHECKSUM)   avio_wl32(bc, ffio_get_checksum(bc));
 
822
    else                        ffio_get_checksum(bc);
 
823
 
 
824
    avio_write(bc, pkt->data + nut->header_len[header_idx], pkt->size - nut->header_len[header_idx]);
778
825
    nus->last_flags= flags;
779
826
    nus->last_pts= pkt->pts;
780
827
 
793
840
 
794
841
static int write_trailer(AVFormatContext *s){
795
842
    NUTContext *nut= s->priv_data;
796
 
    ByteIOContext *bc= s->pb;
 
843
    AVIOContext *bc= s->pb;
797
844
 
798
845
    while(nut->header_count<3)
799
 
        write_headers(nut, bc);
800
 
    put_flush_packet(bc);
 
846
        write_headers(s, bc);
 
847
    avio_flush(bc);
801
848
    ff_nut_free_sp(nut);
802
849
    av_freep(&nut->stream);
 
850
    av_freep(&nut->chapter);
803
851
    av_freep(&nut->time_base);
804
852
 
805
853
    return 0;
806
854
}
807
855
 
808
 
AVOutputFormat nut_muxer = {
 
856
AVOutputFormat ff_nut_muxer = {
809
857
    "nut",
810
858
    NULL_IF_CONFIG_SMALL("NUT format"),
811
859
    "video/x-nut",
823
871
    write_packet,
824
872
    write_trailer,
825
873
    .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
826
 
    .codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0},
827
 
    .metadata_conv = ff_nut_metadata_conv,
 
874
    .codec_tag = (const AVCodecTag * const []){ ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags, ff_nut_subtitle_tags, 0 },
828
875
};