3
3
* Copyright (c) 2004-2007 Michael Niedermayer
5
* This file is part of FFmpeg.
5
* This file is part of Libav.
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.
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.
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
240
242
nut->frame_code['N'].flags= FLAG_INVALID;
244
* Gets the length in bytes which is needed to store val as v.
246
static int get_length(uint64_t val){
255
static void put_v(ByteIOContext *bc, uint64_t val){
256
int i= get_length(val);
259
put_byte(bc, 128 | (val>>(7*i)));
261
put_byte(bc, val&127);
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;
247
val += time_base - nut->time_base;
271
* Stores a string as vb.
252
* Store a string as vb.
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);
277
put_buffer(bc, string, len);
258
avio_write(bc, string, len);
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));
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);
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);
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__)
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;
306
287
if(forw_ptr > 4096)
307
init_checksum(bc, ff_crc04C11DB7_update, 0);
308
put_be64(bc, startcode);
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));
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));
319
300
av_free(dyn_buf);
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;
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);
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);
373
354
if(j != tmp_mul - tmp_size) tmp_fields=6;
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);
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]);
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;
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;
403
385
if (codec->codec_tag){
404
put_le32(bc, codec->codec_tag);
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 */
414
put_v(bc, codec->extradata_size);
415
put_buffer(bc, codec->extradata, codec->extradata_size);
386
avio_wl32(bc, codec->codec_tag);
388
av_log(avctx, AV_LOG_ERROR, "No codec tag defined for stream %d\n", i);
389
return AVERROR(EINVAL);
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 */
398
ff_put_v(bc, codec->extradata_size);
399
avio_write(bc, codec->extradata, codec->extradata_size);
417
401
switch(codec->codec_type){
418
402
case AVMEDIA_TYPE_AUDIO:
419
put_v(bc, codec->sample_rate);
421
put_v(bc, codec->channels);
403
ff_put_v(bc, codec->sample_rate);
405
ff_put_v(bc, codec->channels);
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);
427
411
if(st->sample_aspect_ratio.num<=0 || st->sample_aspect_ratio.den<=0){
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);
434
put_v(bc, 0); /* csp type -- unknown */
418
ff_put_v(bc, 0); /* csp type -- unknown */
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);
445
429
put_str(bc, value);
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;
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);
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);
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
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
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);
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;
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);
486
470
if (st->disposition & ff_nut_dispositions[i].flag)
487
471
count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str);
489
dyn_size = url_close_dyn_buf(dyn_bc, &dyn_buf);
473
dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
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
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
483
avio_write(bc, dyn_buf, dyn_size);
502
486
av_free(dyn_buf);
506
static int write_headers(NUTContext *nut, ByteIOContext *bc){
507
ByteIOContext *dyn_bc;
490
static int write_chapter(NUTContext *nut, AVIOContext *bc, int id)
493
uint8_t *dyn_buf = NULL;
494
AVMetadataTag *t = NULL;
495
AVChapter *ch = nut->avf->chapters[id];
496
int ret, dyn_size, count = 0;
498
ret = avio_open_dyn_buf(&dyn_bc);
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
507
while ((t = av_metadata_get(ch->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
508
count += add_info(dyn_bc, t->key, t->value);
512
dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
513
avio_write(bc, dyn_buf, dyn_size);
518
static int write_headers(AVFormatContext *avctx, AVIOContext *bc){
519
NUTContext *nut = avctx->priv_data;
510
ret = url_open_dyn_buf(&dyn_bc);
523
ff_metadata_conv_ctx(avctx, ff_nut_metadata_conv, NULL);
525
ret = avio_open_dyn_buf(&dyn_bc);
513
528
write_mainheader(nut, dyn_bc);
514
529
put_packet(nut, bc, dyn_bc, 1, MAIN_STARTCODE);
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);
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)
521
537
put_packet(nut, bc, dyn_bc, 1, STREAM_STARTCODE);
524
ret = url_open_dyn_buf(&dyn_bc);
540
ret = avio_open_dyn_buf(&dyn_bc);
527
543
write_globalinfo(nut, dyn_bc);
528
544
put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
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);
534
550
ret = write_streaminfo(nut, dyn_bc, i);
760
807
needed_flags= get_needed_flags(nut, nus, fc, pkt);
761
808
header_idx= fc->header_idx;
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;
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);
774
if(flags & FLAG_CHECKSUM) put_le32(bc, get_checksum(bc));
775
else get_checksum(bc);
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);
821
if(flags & FLAG_CHECKSUM) avio_wl32(bc, ffio_get_checksum(bc));
822
else ffio_get_checksum(bc);
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;