3 * Copyright (c) 2004-2007 Michael Niedermayer
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
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,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
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
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/mathematics.h"
26 #include "libavutil/tree.h"
27 #include "libavutil/dict.h"
28 #include "libavutil/avassert.h"
29 #include "libavutil/time.h"
30 #include "libavutil/opt.h"
31 #include "libavcodec/bytestream.h"
32 #include "libavcodec/mpegaudiodata.h"
35 #include "avio_internal.h"
38 static int find_expected_header(AVCodecContext
*c
, int size
, int key_frame
,
41 int sample_rate
= c
->sample_rate
;
48 if (c
->codec_id
== AV_CODEC_ID_MPEG4
) {
55 } else if (c
->codec_id
== AV_CODEC_ID_MPEG1VIDEO
||
56 c
->codec_id
== AV_CODEC_ID_MPEG2VIDEO
) {
58 } else if (c
->codec_id
== AV_CODEC_ID_H264
) {
60 } else if (c
->codec_id
== AV_CODEC_ID_MP3
||
61 c
->codec_id
== AV_CODEC_ID_MP2
) {
62 int lsf
, mpeg25
, sample_rate_index
, bitrate_index
, frame_size
;
63 int layer
= c
->codec_id
== AV_CODEC_ID_MP3
? 3 : 2;
64 unsigned int header
= 0xFFF00000;
66 lsf
= sample_rate
< (24000 + 32000) / 2;
67 mpeg25
= sample_rate
< (12000 + 16000) / 2;
68 sample_rate
<<= lsf
+ mpeg25
;
69 if (sample_rate
< (32000 + 44100) / 2) sample_rate_index
= 2;
70 else if (sample_rate
< (44100 + 48000) / 2) sample_rate_index
= 0;
71 else sample_rate_index
= 1;
73 sample_rate
= avpriv_mpa_freq_tab
[sample_rate_index
] >> (lsf
+ mpeg25
);
75 for (bitrate_index
= 2; bitrate_index
< 30; bitrate_index
++) {
77 avpriv_mpa_bitrate_tab
[lsf
][layer
- 1][bitrate_index
>> 1];
78 frame_size
= (frame_size
* 144000) / (sample_rate
<< lsf
) +
81 if (frame_size
== size
)
85 header
|= (!lsf
) << 19;
86 header
|= (4 - layer
) << 17;
87 header
|= 1 << 16; //no crc
90 return 2; //we guess there is no crc, if there is one the user clearly does not care about overhead
91 if (bitrate_index
== 30)
92 return -1; //something is wrong ...
94 header
|= (bitrate_index
>> 1) << 12;
95 header
|= sample_rate_index
<< 10;
96 header
|= (bitrate_index
& 1) << 9;
98 return 2; //FIXME actually put the needed ones in build_elision_headers()
99 //return 3; //we guess that the private bit is not set
100 //FIXME the above assumptions should be checked, if these turn out false too often something should be done
105 static int find_header_idx(AVFormatContext
*s
, AVCodecContext
*c
, int size
, int frame_type
)
107 NUTContext
*nut
= s
->priv_data
;
110 int len
= find_expected_header(c
, size
, frame_type
, out
);
112 for (i
= 1; i
< nut
->header_count
; i
++) {
113 if (len
== nut
->header_len
[i
] && !memcmp(out
, nut
->header
[i
], len
)) {
121 static void build_elision_headers(AVFormatContext
*s
)
123 NUTContext
*nut
= s
->priv_data
;
126 //FIXME write a 2pass mode to find the maximal headers
127 static const uint8_t headers
[][5] = {
128 { 3, 0x00, 0x00, 0x01 },
129 { 4, 0x00, 0x00, 0x01, 0xB6},
130 { 2, 0xFF, 0xFA }, //mp3+crc
131 { 2, 0xFF, 0xFB }, //mp3
132 { 2, 0xFF, 0xFC }, //mp2+crc
133 { 2, 0xFF, 0xFD }, //mp2
136 nut
->header_count
= 7;
137 for (i
= 1; i
< nut
->header_count
; i
++) {
138 nut
->header_len
[i
] = headers
[i
- 1][0];
139 nut
->header
[i
] = &headers
[i
- 1][1];
143 static void build_frame_code(AVFormatContext
*s
)
145 NUTContext
*nut
= s
->priv_data
;
146 int key_frame
, index
, pred
, stream_id
;
149 int keyframe_0_esc
= s
->nb_streams
> 2;
153 ft
= &nut
->frame_code
[start
];
154 ft
->flags
= FLAG_CODED
;
159 if (keyframe_0_esc
) {
160 /* keyframe = 0 escape */
161 FrameCode
*ft
= &nut
->frame_code
[start
];
162 ft
->flags
= FLAG_STREAM_ID
| FLAG_SIZE_MSB
| FLAG_CODED_PTS
;
167 for (stream_id
= 0; stream_id
< s
->nb_streams
; stream_id
++) {
168 int start2
= start
+ (end
- start
) * stream_id
/ s
->nb_streams
;
169 int end2
= start
+ (end
- start
) * (stream_id
+ 1) / s
->nb_streams
;
170 AVCodecContext
*codec
= s
->streams
[stream_id
]->codec
;
171 int is_audio
= codec
->codec_type
== AVMEDIA_TYPE_AUDIO
;
172 int intra_only
= /*codec->intra_only || */ is_audio
;
176 if (codec
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
177 frame_size
= av_get_audio_frame_duration(codec
, 0);
178 if (codec
->codec_id
== AV_CODEC_ID_VORBIS
&& !frame_size
)
181 AVRational f
= av_div_q(codec
->time_base
, *nut
->stream
[stream_id
].time_base
);
182 if (f
.den
== 1 && f
.num
>0)
188 for (key_frame
= 0; key_frame
< 2; key_frame
++) {
189 if (!intra_only
|| !keyframe_0_esc
|| key_frame
!= 0) {
190 FrameCode
*ft
= &nut
->frame_code
[start2
];
191 ft
->flags
= FLAG_KEY
* key_frame
;
192 ft
->flags
|= FLAG_SIZE_MSB
| FLAG_CODED_PTS
;
193 ft
->stream_id
= stream_id
;
196 ft
->header_idx
= find_header_idx(s
, codec
, -1, key_frame
);
201 key_frame
= intra_only
;
204 int frame_bytes
= codec
->frame_size
* (int64_t)codec
->bit_rate
/
205 (8 * codec
->sample_rate
);
207 for (pts
= 0; pts
< 2; pts
++) {
208 for (pred
= 0; pred
< 2; pred
++) {
209 FrameCode
*ft
= &nut
->frame_code
[start2
];
210 ft
->flags
= FLAG_KEY
* key_frame
;
211 ft
->stream_id
= stream_id
;
212 ft
->size_mul
= frame_bytes
+ 2;
213 ft
->size_lsb
= frame_bytes
+ pred
;
214 ft
->pts_delta
= pts
* frame_size
;
215 ft
->header_idx
= find_header_idx(s
, codec
, frame_bytes
+ pred
, key_frame
);
220 FrameCode
*ft
= &nut
->frame_code
[start2
];
221 ft
->flags
= FLAG_KEY
| FLAG_SIZE_MSB
;
222 ft
->stream_id
= stream_id
;
224 ft
->pts_delta
= frame_size
;
229 if (codec
->has_b_frames
) {
236 } else if (codec
->codec_id
== AV_CODEC_ID_VORBIS
) {
246 for (pred
= 0; pred
< pred_count
; pred
++) {
247 int start3
= start2
+ (end2
- start2
) * pred
/ pred_count
;
248 int end3
= start2
+ (end2
- start2
) * (pred
+ 1) / pred_count
;
250 pred_table
[pred
] *= frame_size
;
252 for (index
= start3
; index
< end3
; index
++) {
253 FrameCode
*ft
= &nut
->frame_code
[index
];
254 ft
->flags
= FLAG_KEY
* key_frame
;
255 ft
->flags
|= FLAG_SIZE_MSB
;
256 ft
->stream_id
= stream_id
;
257 //FIXME use single byte size and pred from last
258 ft
->size_mul
= end3
- start3
;
259 ft
->size_lsb
= index
- start3
;
260 ft
->pts_delta
= pred_table
[pred
];
262 ft
->header_idx
= find_header_idx(s
, codec
, -1, key_frame
);
266 memmove(&nut
->frame_code
['N' + 1], &nut
->frame_code
['N'], sizeof(FrameCode
) * (255 - 'N'));
267 nut
->frame_code
[0].flags
=
268 nut
->frame_code
[255].flags
=
269 nut
->frame_code
['N'].flags
= FLAG_INVALID
;
272 static void put_tt(NUTContext
*nut
, AVRational
*time_base
, AVIOContext
*bc
, uint64_t val
)
274 val
*= nut
->time_base_count
;
275 val
+= time_base
- nut
->time_base
;
279 * Store a string as vb.
281 static void put_str(AVIOContext
*bc
, const char *string
)
283 int len
= strlen(string
);
286 avio_write(bc
, string
, len
);
289 static void put_s(AVIOContext
*bc
, int64_t val
)
291 ff_put_v(bc
, 2 * FFABS(val
) - (val
> 0));
295 static inline void ff_put_v_trace(AVIOContext
*bc
, uint64_t v
, const char *file
,
296 const char *func
, int line
)
298 av_log(NULL
, AV_LOG_DEBUG
, "ff_put_v %5"PRId64
" / %"PRIX64
" in %s %s:%d\n", v
, v
, file
, func
, line
);
303 static inline void put_s_trace(AVIOContext
*bc
, int64_t v
, const char *file
, const char *func
, int line
)
305 av_log(NULL
, AV_LOG_DEBUG
, "put_s %5"PRId64
" / %"PRIX64
" in %s %s:%d\n", v
, v
, file
, func
, line
);
309 #define ff_put_v(bc, v) ff_put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
310 #define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
313 //FIXME remove calculate_checksum
314 static void put_packet(NUTContext
*nut
, AVIOContext
*bc
, AVIOContext
*dyn_bc
,
315 int calculate_checksum
, uint64_t startcode
)
317 uint8_t *dyn_buf
= NULL
;
318 int dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
319 int forw_ptr
= dyn_size
+ 4 * calculate_checksum
;
322 ffio_init_checksum(bc
, ff_crc04C11DB7_update
, 0);
323 avio_wb64(bc
, startcode
);
324 ff_put_v(bc
, forw_ptr
);
326 avio_wl32(bc
, ffio_get_checksum(bc
));
328 if (calculate_checksum
)
329 ffio_init_checksum(bc
, ff_crc04C11DB7_update
, 0);
330 avio_write(bc
, dyn_buf
, dyn_size
);
331 if (calculate_checksum
)
332 avio_wl32(bc
, ffio_get_checksum(bc
));
337 static void write_mainheader(NUTContext
*nut
, AVIOContext
*bc
)
339 int i
, j
, tmp_pts
, tmp_flags
, tmp_stream
, tmp_mul
, tmp_size
, tmp_fields
,
343 ff_put_v(bc
, nut
->version
);
344 if (nut
->version
> 3)
345 ff_put_v(bc
, nut
->minor_version
= 1);
346 ff_put_v(bc
, nut
->avf
->nb_streams
);
347 ff_put_v(bc
, nut
->max_distance
);
348 ff_put_v(bc
, nut
->time_base_count
);
350 for (i
= 0; i
< nut
->time_base_count
; i
++) {
351 ff_put_v(bc
, nut
->time_base
[i
].num
);
352 ff_put_v(bc
, nut
->time_base
[i
].den
);
358 tmp_match
= 1 - (1LL << 62);
360 for (i
= 0; i
< 256; ) {
364 if (tmp_pts
!= nut
->frame_code
[i
].pts_delta
) tmp_fields
= 1;
365 if (tmp_mul
!= nut
->frame_code
[i
].size_mul
) tmp_fields
= 2;
366 if (tmp_stream
!= nut
->frame_code
[i
].stream_id
) tmp_fields
= 3;
367 if (tmp_size
!= nut
->frame_code
[i
].size_lsb
) tmp_fields
= 4;
368 // if (tmp_res != nut->frame_code[i].res ) tmp_fields=5;
369 if (tmp_head_idx
!= nut
->frame_code
[i
].header_idx
) tmp_fields
= 8;
371 tmp_pts
= nut
->frame_code
[i
].pts_delta
;
372 tmp_flags
= nut
->frame_code
[i
].flags
;
373 tmp_stream
= nut
->frame_code
[i
].stream_id
;
374 tmp_mul
= nut
->frame_code
[i
].size_mul
;
375 tmp_size
= nut
->frame_code
[i
].size_lsb
;
376 // tmp_res = nut->frame_code[i].res;
377 tmp_head_idx
= nut
->frame_code
[i
].header_idx
;
379 for (j
= 0; i
< 256; j
++, i
++) {
384 if (nut
->frame_code
[i
].pts_delta
!= tmp_pts
||
385 nut
->frame_code
[i
].flags
!= tmp_flags
||
386 nut
->frame_code
[i
].stream_id
!= tmp_stream
||
387 nut
->frame_code
[i
].size_mul
!= tmp_mul
||
388 nut
->frame_code
[i
].size_lsb
!= tmp_size
+ j
||
389 // nut->frame_code[i].res != tmp_res ||
390 nut
->frame_code
[i
].header_idx
!= tmp_head_idx
)
393 if (j
!= tmp_mul
- tmp_size
)
396 ff_put_v(bc
, tmp_flags
);
397 ff_put_v(bc
, tmp_fields
);
398 if (tmp_fields
> 0) put_s(bc
, tmp_pts
);
399 if (tmp_fields
> 1) ff_put_v(bc
, tmp_mul
);
400 if (tmp_fields
> 2) ff_put_v(bc
, tmp_stream
);
401 if (tmp_fields
> 3) ff_put_v(bc
, tmp_size
);
402 if (tmp_fields
> 4) ff_put_v(bc
, 0 /*tmp_res*/);
403 if (tmp_fields
> 5) ff_put_v(bc
, j
);
404 if (tmp_fields
> 6) ff_put_v(bc
, tmp_match
);
405 if (tmp_fields
> 7) ff_put_v(bc
, tmp_head_idx
);
407 ff_put_v(bc
, nut
->header_count
- 1);
408 for (i
= 1; i
< nut
->header_count
; i
++) {
409 ff_put_v(bc
, nut
->header_len
[i
]);
410 avio_write(bc
, nut
->header
[i
], nut
->header_len
[i
]);
412 // flags had been effectively introduced in version 4
413 if (nut
->version
> 3)
414 ff_put_v(bc
, nut
->flags
);
417 static int write_streamheader(AVFormatContext
*avctx
, AVIOContext
*bc
,
420 NUTContext
*nut
= avctx
->priv_data
;
421 AVCodecContext
*codec
= st
->codec
;
424 switch (codec
->codec_type
) {
425 case AVMEDIA_TYPE_VIDEO
: ff_put_v(bc
, 0); break;
426 case AVMEDIA_TYPE_AUDIO
: ff_put_v(bc
, 1); break;
427 case AVMEDIA_TYPE_SUBTITLE
: ff_put_v(bc
, 2); break;
428 default: ff_put_v(bc
, 3); break;
431 if (codec
->codec_tag
) {
432 avio_wl32(bc
, codec
->codec_tag
);
434 av_log(avctx
, AV_LOG_ERROR
, "No codec tag defined for stream %d\n", i
);
435 return AVERROR(EINVAL
);
438 ff_put_v(bc
, nut
->stream
[i
].time_base
- nut
->time_base
);
439 ff_put_v(bc
, nut
->stream
[i
].msb_pts_shift
);
440 ff_put_v(bc
, nut
->stream
[i
].max_pts_distance
);
441 ff_put_v(bc
, codec
->has_b_frames
);
442 avio_w8(bc
, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
444 ff_put_v(bc
, codec
->extradata_size
);
445 avio_write(bc
, codec
->extradata
, codec
->extradata_size
);
447 switch (codec
->codec_type
) {
448 case AVMEDIA_TYPE_AUDIO
:
449 ff_put_v(bc
, codec
->sample_rate
);
451 ff_put_v(bc
, codec
->channels
);
453 case AVMEDIA_TYPE_VIDEO
:
454 ff_put_v(bc
, codec
->width
);
455 ff_put_v(bc
, codec
->height
);
457 if (st
->sample_aspect_ratio
.num
<= 0 ||
458 st
->sample_aspect_ratio
.den
<= 0) {
462 ff_put_v(bc
, st
->sample_aspect_ratio
.num
);
463 ff_put_v(bc
, st
->sample_aspect_ratio
.den
);
465 ff_put_v(bc
, 0); /* csp type -- unknown */
473 static int add_info(AVIOContext
*bc
, const char *type
, const char *value
)
481 static int write_globalinfo(NUTContext
*nut
, AVIOContext
*bc
)
483 AVFormatContext
*s
= nut
->avf
;
484 AVDictionaryEntry
*t
= NULL
;
486 uint8_t *dyn_buf
= NULL
;
487 int count
= 0, dyn_size
;
488 int ret
= avio_open_dyn_buf(&dyn_bc
);
492 while ((t
= av_dict_get(s
->metadata
, "", t
, AV_DICT_IGNORE_SUFFIX
)))
493 count
+= add_info(dyn_bc
, t
->key
, t
->value
);
495 ff_put_v(bc
, 0); //stream_if_plus1
496 ff_put_v(bc
, 0); //chapter_id
497 ff_put_v(bc
, 0); //timestamp_start
498 ff_put_v(bc
, 0); //length
502 dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
503 avio_write(bc
, dyn_buf
, dyn_size
);
508 static int write_streaminfo(NUTContext
*nut
, AVIOContext
*bc
, int stream_id
) {
509 AVFormatContext
*s
= nut
->avf
;
510 AVStream
* st
= s
->streams
[stream_id
];
511 AVDictionaryEntry
*t
= NULL
;
513 uint8_t *dyn_buf
=NULL
;
514 int count
=0, dyn_size
, i
;
515 int ret
= avio_open_dyn_buf(&dyn_bc
);
519 while ((t
= av_dict_get(st
->metadata
, "", t
, AV_DICT_IGNORE_SUFFIX
)))
520 count
+= add_info(dyn_bc
, t
->key
, t
->value
);
521 for (i
=0; ff_nut_dispositions
[i
].flag
; ++i
) {
522 if (st
->disposition
& ff_nut_dispositions
[i
].flag
)
523 count
+= add_info(dyn_bc
, "Disposition", ff_nut_dispositions
[i
].str
);
525 if (st
->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
527 snprintf(buf
, sizeof(buf
), "%d/%d", st
->codec
->time_base
.den
, st
->codec
->time_base
.num
);
528 count
+= add_info(dyn_bc
, "r_frame_rate", buf
);
530 dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
533 ff_put_v(bc
, stream_id
+ 1); //stream_id_plus1
534 ff_put_v(bc
, 0); //chapter_id
535 ff_put_v(bc
, 0); //timestamp_start
536 ff_put_v(bc
, 0); //length
540 avio_write(bc
, dyn_buf
, dyn_size
);
547 static int write_chapter(NUTContext
*nut
, AVIOContext
*bc
, int id
)
550 uint8_t *dyn_buf
= NULL
;
551 AVDictionaryEntry
*t
= NULL
;
552 AVChapter
*ch
= nut
->avf
->chapters
[id
];
553 int ret
, dyn_size
, count
= 0;
555 ret
= avio_open_dyn_buf(&dyn_bc
);
559 ff_put_v(bc
, 0); // stream_id_plus1
560 put_s(bc
, id
+ 1); // chapter_id
561 put_tt(nut
, nut
->chapter
[id
].time_base
, bc
, ch
->start
); // chapter_start
562 ff_put_v(bc
, ch
->end
- ch
->start
); // chapter_len
564 while ((t
= av_dict_get(ch
->metadata
, "", t
, AV_DICT_IGNORE_SUFFIX
)))
565 count
+= add_info(dyn_bc
, t
->key
, t
->value
);
569 dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
570 avio_write(bc
, dyn_buf
, dyn_size
);
575 static int write_index(NUTContext
*nut
, AVIOContext
*bc
) {
577 Syncpoint dummy
= { .pos
= 0 };
578 Syncpoint
*next_node
[2] = { NULL
};
579 int64_t startpos
= avio_tell(bc
);
580 int64_t payload_size
;
582 put_tt(nut
, nut
->max_pts_tb
, bc
, nut
->max_pts
);
584 ff_put_v(bc
, nut
->sp_count
);
586 for (i
=0; i
<nut
->sp_count
; i
++) {
587 av_tree_find(nut
->syncpoints
, &dummy
, (void *) ff_nut_sp_pos_cmp
, (void**)next_node
);
588 ff_put_v(bc
, (next_node
[1]->pos
>> 4) - (dummy
.pos
>>4));
589 dummy
.pos
= next_node
[1]->pos
;
592 for (i
=0; i
<nut
->avf
->nb_streams
; i
++) {
593 StreamContext
*nus
= &nut
->stream
[i
];
594 int64_t last_pts
= -1;
596 for (j
=0; j
<nut
->sp_count
; j
++) {
600 if (j
&& nus
->keyframe_pts
[j
] == nus
->keyframe_pts
[j
-1]) {
601 av_log(nut
->avf
, AV_LOG_WARNING
, "Multiple keyframes with same PTS\n");
602 nus
->keyframe_pts
[j
] = AV_NOPTS_VALUE
;
605 flag
= (nus
->keyframe_pts
[j
] != AV_NOPTS_VALUE
) ^ (j
+1 == nut
->sp_count
);
606 for (; j
<nut
->sp_count
&& (nus
->keyframe_pts
[j
] != AV_NOPTS_VALUE
) == flag
; j
++)
609 ff_put_v(bc
, 1 + 2*flag
+ 4*n
);
610 for (k
= j
- n
; k
<=j
&& k
<nut
->sp_count
; k
++) {
611 if (nus
->keyframe_pts
[k
] == AV_NOPTS_VALUE
)
613 av_assert0(nus
->keyframe_pts
[k
] > last_pts
);
614 ff_put_v(bc
, nus
->keyframe_pts
[k
] - last_pts
);
615 last_pts
= nus
->keyframe_pts
[k
];
620 payload_size
= avio_tell(bc
) - startpos
+ 8 + 4;
622 avio_wb64(bc
, 8 + payload_size
+ av_log2(payload_size
) / 7 + 1 + 4*(payload_size
> 4096));
627 static int write_headers(AVFormatContext
*avctx
, AVIOContext
*bc
)
629 NUTContext
*nut
= avctx
->priv_data
;
633 ff_metadata_conv_ctx(avctx
, ff_nut_metadata_conv
, NULL
);
635 ret
= avio_open_dyn_buf(&dyn_bc
);
638 write_mainheader(nut
, dyn_bc
);
639 put_packet(nut
, bc
, dyn_bc
, 1, MAIN_STARTCODE
);
641 for (i
= 0; i
< nut
->avf
->nb_streams
; i
++) {
642 ret
= avio_open_dyn_buf(&dyn_bc
);
645 ret
= write_streamheader(avctx
, dyn_bc
, nut
->avf
->streams
[i
], i
);
648 put_packet(nut
, bc
, dyn_bc
, 1, STREAM_STARTCODE
);
651 ret
= avio_open_dyn_buf(&dyn_bc
);
654 write_globalinfo(nut
, dyn_bc
);
655 put_packet(nut
, bc
, dyn_bc
, 1, INFO_STARTCODE
);
657 for (i
= 0; i
< nut
->avf
->nb_streams
; i
++) {
658 ret
= avio_open_dyn_buf(&dyn_bc
);
661 ret
= write_streaminfo(nut
, dyn_bc
, i
);
665 put_packet(nut
, bc
, dyn_bc
, 1, INFO_STARTCODE
);
668 avio_close_dyn_buf(dyn_bc
, &buf
);
673 for (i
= 0; i
< nut
->avf
->nb_chapters
; i
++) {
674 ret
= avio_open_dyn_buf(&dyn_bc
);
677 ret
= write_chapter(nut
, dyn_bc
, i
);
680 avio_close_dyn_buf(dyn_bc
, &buf
);
684 put_packet(nut
, bc
, dyn_bc
, 1, INFO_STARTCODE
);
687 nut
->last_syncpoint_pos
= INT_MIN
;
692 static int nut_write_header(AVFormatContext
*s
)
694 NUTContext
*nut
= s
->priv_data
;
695 AVIOContext
*bc
= s
->pb
;
700 nut
->version
= FFMAX(NUT_STABLE_VERSION
, 3 + !!nut
->flags
);
701 if (nut
->version
> 3 && s
->strict_std_compliance
> FF_COMPLIANCE_EXPERIMENTAL
) {
702 av_log(s
, AV_LOG_ERROR
,
703 "The additional syncpoint modes require version %d, "
704 "that is currently not finalized, "
705 "please set -f_strict experimental in order to enable it.\n",
707 return AVERROR_EXPERIMENTAL
;
710 nut
->stream
= av_calloc(s
->nb_streams
, sizeof(*nut
->stream
));
711 nut
->chapter
= av_calloc(s
->nb_chapters
, sizeof(*nut
->chapter
));
712 nut
->time_base
= av_calloc(s
->nb_streams
+
713 s
->nb_chapters
, sizeof(*nut
->time_base
));
714 if (!nut
->stream
|| !nut
->chapter
|| !nut
->time_base
) {
715 av_freep(&nut
->stream
);
716 av_freep(&nut
->chapter
);
717 av_freep(&nut
->time_base
);
718 return AVERROR(ENOMEM
);
721 for (i
= 0; i
< s
->nb_streams
; i
++) {
722 AVStream
*st
= s
->streams
[i
];
724 AVRational time_base
;
725 ff_parse_specific_params(st
, &time_base
.den
, &ssize
, &time_base
.num
);
727 if (st
->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
&& st
->codec
->sample_rate
) {
728 time_base
= (AVRational
) {1, st
->codec
->sample_rate
};
730 time_base
= ff_choose_timebase(s
, st
, 48000);
733 avpriv_set_pts_info(st
, 64, time_base
.num
, time_base
.den
);
735 for (j
= 0; j
< nut
->time_base_count
; j
++)
736 if (!memcmp(&time_base
, &nut
->time_base
[j
], sizeof(AVRational
))) {
739 nut
->time_base
[j
] = time_base
;
740 nut
->stream
[i
].time_base
= &nut
->time_base
[j
];
741 if (j
== nut
->time_base_count
)
742 nut
->time_base_count
++;
744 if (INT64_C(1000) * time_base
.num
>= time_base
.den
)
745 nut
->stream
[i
].msb_pts_shift
= 7;
747 nut
->stream
[i
].msb_pts_shift
= 14;
748 nut
->stream
[i
].max_pts_distance
=
749 FFMAX(time_base
.den
, time_base
.num
) / time_base
.num
;
752 for (i
= 0; i
< s
->nb_chapters
; i
++) {
753 AVChapter
*ch
= s
->chapters
[i
];
755 for (j
= 0; j
< nut
->time_base_count
; j
++)
756 if (!memcmp(&ch
->time_base
, &nut
->time_base
[j
], sizeof(AVRational
)))
759 nut
->time_base
[j
] = ch
->time_base
;
760 nut
->chapter
[i
].time_base
= &nut
->time_base
[j
];
761 if (j
== nut
->time_base_count
)
762 nut
->time_base_count
++;
765 nut
->max_distance
= MAX_DISTANCE
;
766 build_elision_headers(s
);
768 av_assert0(nut
->frame_code
['N'].flags
== FLAG_INVALID
);
770 avio_write(bc
, ID_STRING
, strlen(ID_STRING
));
773 if ((ret
= write_headers(s
, bc
)) < 0)
776 if (s
->avoid_negative_ts
< 0)
777 s
->avoid_negative_ts
= 1;
784 static int get_needed_flags(NUTContext
*nut
, StreamContext
*nus
, FrameCode
*fc
,
789 if (pkt
->flags
& AV_PKT_FLAG_KEY
)
791 if (pkt
->stream_index
!= fc
->stream_id
)
792 flags
|= FLAG_STREAM_ID
;
793 if (pkt
->size
/ fc
->size_mul
)
794 flags
|= FLAG_SIZE_MSB
;
795 if (pkt
->pts
- nus
->last_pts
!= fc
->pts_delta
)
796 flags
|= FLAG_CODED_PTS
;
797 if (pkt
->side_data_elems
&& nut
->version
> 3)
798 flags
|= FLAG_SM_DATA
;
799 if (pkt
->size
> 2 * nut
->max_distance
)
800 flags
|= FLAG_CHECKSUM
;
801 if (FFABS(pkt
->pts
- nus
->last_pts
) > nus
->max_pts_distance
)
802 flags
|= FLAG_CHECKSUM
;
803 if (pkt
->size
< nut
->header_len
[fc
->header_idx
] ||
804 (pkt
->size
> 4096 && fc
->header_idx
) ||
805 memcmp(pkt
->data
, nut
->header
[fc
->header_idx
],
806 nut
->header_len
[fc
->header_idx
]))
807 flags
|= FLAG_HEADER_IDX
;
809 return flags
| (fc
->flags
& FLAG_CODED
);
812 static int find_best_header_idx(NUTContext
*nut
, AVPacket
*pkt
)
818 if (pkt
->size
> 4096)
821 for (i
= 1; i
< nut
->header_count
; i
++)
822 if (pkt
->size
>= nut
->header_len
[i
]
823 && nut
->header_len
[i
] > best_len
824 && !memcmp(pkt
->data
, nut
->header
[i
], nut
->header_len
[i
])) {
826 best_len
= nut
->header_len
[i
];
831 static int write_sm_data(AVFormatContext
*s
, AVIOContext
*bc
, AVPacket
*pkt
, int is_meta
)
833 int ret
, i
, dyn_size
;
836 int sm_data_count
= 0;
840 ret
= avio_open_dyn_buf(&dyn_bc
);
844 for (i
= 0; i
<pkt
->side_data_elems
; i
++) {
845 const uint8_t *data
= pkt
->side_data
[i
].data
;
846 int size
= pkt
->side_data
[i
].size
;
847 const uint8_t *data_end
= data
+ size
;
850 if ( pkt
->side_data
[i
].type
== AV_PKT_DATA_METADATA_UPDATE
851 || pkt
->side_data
[i
].type
== AV_PKT_DATA_STRINGS_METADATA
) {
852 if (!size
|| data
[size
-1]) {
853 ret
= AVERROR(EINVAL
);
856 while (data
< data_end
) {
857 const uint8_t *key
= data
;
858 const uint8_t *val
= data
+ strlen(key
) + 1;
860 if(val
>= data_end
) {
861 ret
= AVERROR(EINVAL
);
864 put_str(dyn_bc
, key
);
866 put_str(dyn_bc
, val
);
867 data
= val
+ strlen(val
) + 1;
872 switch (pkt
->side_data
[i
].type
) {
873 case AV_PKT_DATA_PALETTE
:
874 case AV_PKT_DATA_NEW_EXTRADATA
:
875 case AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL
:
877 if (pkt
->side_data
[i
].type
== AV_PKT_DATA_PALETTE
) {
878 put_str(dyn_bc
, "Palette");
879 } else if(pkt
->side_data
[i
].type
== AV_PKT_DATA_NEW_EXTRADATA
) {
880 put_str(dyn_bc
, "Extradata");
881 } else if(pkt
->side_data
[i
].type
== AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL
) {
882 snprintf(tmp
, sizeof(tmp
), "CodecSpecificSide%"PRId64
"", AV_RB64(data
));
883 put_str(dyn_bc
, tmp
);
885 snprintf(tmp
, sizeof(tmp
), "UserData%s-SD-%d",
886 (s
->flags
& AVFMT_FLAG_BITEXACT
) ? "Lavf" : LIBAVFORMAT_IDENT
,
887 pkt
->side_data
[i
].type
);
888 put_str(dyn_bc
, tmp
);
891 put_str(dyn_bc
, "bin");
892 ff_put_v(dyn_bc
, pkt
->side_data
[i
].size
);
893 avio_write(dyn_bc
, data
, pkt
->side_data
[i
].size
);
896 case AV_PKT_DATA_PARAM_CHANGE
:
897 flags
= bytestream_get_le32(&data
);
898 if (flags
& AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT
) {
899 put_str(dyn_bc
, "Channels");
900 put_s(dyn_bc
, bytestream_get_le32(&data
));
903 if (flags
& AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT
) {
904 put_str(dyn_bc
, "ChannelLayout");
906 put_str(dyn_bc
, "u64");
908 avio_write(dyn_bc
, data
, 8); data
+=8;
911 if (flags
& AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE
) {
912 put_str(dyn_bc
, "SampleRate");
913 put_s(dyn_bc
, bytestream_get_le32(&data
));
916 if (flags
& AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS
) {
917 put_str(dyn_bc
, "Width");
918 put_s(dyn_bc
, bytestream_get_le32(&data
));
919 put_str(dyn_bc
, "Height");
920 put_s(dyn_bc
, bytestream_get_le32(&data
));
924 case AV_PKT_DATA_SKIP_SAMPLES
:
926 put_str(dyn_bc
, "SkipStart");
927 put_s(dyn_bc
, (unsigned)AV_RL32(data
));
930 if (AV_RL32(data
+4)) {
931 put_str(dyn_bc
, "SkipEnd");
932 put_s(dyn_bc
, (unsigned)AV_RL32(data
+4));
936 case AV_PKT_DATA_METADATA_UPDATE
:
937 case AV_PKT_DATA_STRINGS_METADATA
:
938 // belongs into meta, not side data
945 ff_put_v(bc
, sm_data_count
);
946 dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
947 avio_write(bc
, dyn_buf
, dyn_size
);
953 static int nut_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
955 NUTContext
*nut
= s
->priv_data
;
956 StreamContext
*nus
= &nut
->stream
[pkt
->stream_index
];
957 AVIOContext
*bc
= s
->pb
, *dyn_bc
, *sm_bc
= NULL
;
960 int best_length
, frame_code
, flags
, needed_flags
, i
, header_idx
;
962 int key_frame
= !!(pkt
->flags
& AV_PKT_FLAG_KEY
);
966 int data_size
= pkt
->size
;
967 uint8_t *sm_buf
= NULL
;
970 av_log(s
, AV_LOG_ERROR
,
971 "Negative pts not supported stream %d, pts %"PRId64
"\n",
972 pkt
->stream_index
, pkt
->pts
);
973 if (pkt
->pts
== AV_NOPTS_VALUE
)
974 av_log(s
, AV_LOG_ERROR
, "Try to enable the genpts flag\n");
975 return AVERROR(EINVAL
);
978 if (pkt
->side_data_elems
&& nut
->version
> 3) {
979 ret
= avio_open_dyn_buf(&sm_bc
);
982 ret
= write_sm_data(s
, sm_bc
, pkt
, 0);
984 ret
= write_sm_data(s
, sm_bc
, pkt
, 1);
985 sm_size
= avio_close_dyn_buf(sm_bc
, &sm_buf
);
988 data_size
+= sm_size
;
991 if (1LL << (20 + 3 * nut
->header_count
) <= avio_tell(bc
))
992 write_headers(s
, bc
);
994 if (key_frame
&& !(nus
->last_flags
& FLAG_KEY
))
997 if (data_size
+ 30 /*FIXME check*/ + avio_tell(bc
) >= nut
->last_syncpoint_pos
+ nut
->max_distance
)
1000 //FIXME: Ensure store_sp is 1 in the first place.
1003 (!(nut
->flags
& NUT_PIPE
) || nut
->last_syncpoint_pos
== INT_MIN
)) {
1004 int64_t sp_pos
= INT64_MAX
;
1006 ff_nut_reset_ts(nut
, *nus
->time_base
, pkt
->dts
);
1007 for (i
= 0; i
< s
->nb_streams
; i
++) {
1008 AVStream
*st
= s
->streams
[i
];
1009 int64_t dts_tb
= av_rescale_rnd(pkt
->dts
,
1010 nus
->time_base
->num
* (int64_t)nut
->stream
[i
].time_base
->den
,
1011 nus
->time_base
->den
* (int64_t)nut
->stream
[i
].time_base
->num
,
1013 int index
= av_index_search_timestamp(st
, dts_tb
,
1014 AVSEEK_FLAG_BACKWARD
);
1016 sp_pos
= FFMIN(sp_pos
, st
->index_entries
[index
].pos
);
1017 if (!nut
->write_index
&& 2*index
> st
->nb_index_entries
) {
1018 memmove(st
->index_entries
,
1019 st
->index_entries
+ index
,
1020 sizeof(*st
->index_entries
) * (st
->nb_index_entries
- index
));
1021 st
->nb_index_entries
-= index
;
1026 nut
->last_syncpoint_pos
= avio_tell(bc
);
1027 ret
= avio_open_dyn_buf(&dyn_bc
);
1030 put_tt(nut
, nus
->time_base
, dyn_bc
, pkt
->dts
);
1031 ff_put_v(dyn_bc
, sp_pos
!= INT64_MAX
? (nut
->last_syncpoint_pos
- sp_pos
) >> 4 : 0);
1033 if (nut
->flags
& NUT_BROADCAST
) {
1034 put_tt(nut
, nus
->time_base
, dyn_bc
,
1035 av_rescale_q(av_gettime(), AV_TIME_BASE_Q
, *nus
->time_base
));
1037 put_packet(nut
, bc
, dyn_bc
, 1, SYNCPOINT_STARTCODE
);
1039 if (nut
->write_index
) {
1040 if ((ret
= ff_nut_add_sp(nut
, nut
->last_syncpoint_pos
, 0 /*unused*/, pkt
->dts
)) < 0)
1043 if ((1ll<<60) % nut
->sp_count
== 0)
1044 for (i
=0; i
<s
->nb_streams
; i
++) {
1046 StreamContext
*nus
= &nut
->stream
[i
];
1047 av_reallocp_array(&nus
->keyframe_pts
, 2*nut
->sp_count
, sizeof(*nus
->keyframe_pts
));
1048 if (!nus
->keyframe_pts
) {
1049 ret
= AVERROR(ENOMEM
);
1052 for (j
=nut
->sp_count
== 1 ? 0 : nut
->sp_count
; j
<2*nut
->sp_count
; j
++)
1053 nus
->keyframe_pts
[j
] = AV_NOPTS_VALUE
;
1057 av_assert0(nus
->last_pts
!= AV_NOPTS_VALUE
);
1059 coded_pts
= pkt
->pts
& ((1 << nus
->msb_pts_shift
) - 1);
1060 if (ff_lsb2full(nus
, coded_pts
) != pkt
->pts
)
1061 coded_pts
= pkt
->pts
+ (1 << nus
->msb_pts_shift
);
1063 best_header_idx
= find_best_header_idx(nut
, pkt
);
1065 best_length
= INT_MAX
;
1067 for (i
= 0; i
< 256; i
++) {
1069 FrameCode
*fc
= &nut
->frame_code
[i
];
1070 int flags
= fc
->flags
;
1072 if (flags
& FLAG_INVALID
)
1074 needed_flags
= get_needed_flags(nut
, nus
, fc
, pkt
);
1076 if (flags
& FLAG_CODED
) {
1078 flags
= needed_flags
;
1081 if ((flags
& needed_flags
) != needed_flags
)
1084 if ((flags
^ needed_flags
) & FLAG_KEY
)
1087 if (flags
& FLAG_STREAM_ID
)
1088 length
+= ff_get_v_length(pkt
->stream_index
);
1090 if (data_size
% fc
->size_mul
!= fc
->size_lsb
)
1092 if (flags
& FLAG_SIZE_MSB
)
1093 length
+= ff_get_v_length(data_size
/ fc
->size_mul
);
1095 if (flags
& FLAG_CHECKSUM
)
1098 if (flags
& FLAG_CODED_PTS
)
1099 length
+= ff_get_v_length(coded_pts
);
1101 if ( (flags
& FLAG_CODED
)
1102 && nut
->header_len
[best_header_idx
] > nut
->header_len
[fc
->header_idx
] + 1) {
1103 flags
|= FLAG_HEADER_IDX
;
1106 if (flags
& FLAG_HEADER_IDX
) {
1107 length
+= 1 - nut
->header_len
[best_header_idx
];
1109 length
-= nut
->header_len
[fc
->header_idx
];
1113 length
+= !(flags
& FLAG_CODED_PTS
);
1114 length
+= !(flags
& FLAG_CHECKSUM
);
1116 if (length
< best_length
) {
1117 best_length
= length
;
1121 av_assert0(frame_code
!= -1);
1123 fc
= &nut
->frame_code
[frame_code
];
1125 needed_flags
= get_needed_flags(nut
, nus
, fc
, pkt
);
1126 header_idx
= fc
->header_idx
;
1128 ffio_init_checksum(bc
, ff_crc04C11DB7_update
, 0);
1129 avio_w8(bc
, frame_code
);
1130 if (flags
& FLAG_CODED
) {
1131 ff_put_v(bc
, (flags
^ needed_flags
) & ~(FLAG_CODED
));
1132 flags
= needed_flags
;
1134 if (flags
& FLAG_STREAM_ID
) ff_put_v(bc
, pkt
->stream_index
);
1135 if (flags
& FLAG_CODED_PTS
) ff_put_v(bc
, coded_pts
);
1136 if (flags
& FLAG_SIZE_MSB
) ff_put_v(bc
, data_size
/ fc
->size_mul
);
1137 if (flags
& FLAG_HEADER_IDX
) ff_put_v(bc
, header_idx
= best_header_idx
);
1139 if (flags
& FLAG_CHECKSUM
) avio_wl32(bc
, ffio_get_checksum(bc
));
1140 else ffio_get_checksum(bc
);
1142 if (flags
& FLAG_SM_DATA
) {
1143 avio_write(bc
, sm_buf
, sm_size
);
1145 avio_write(bc
, pkt
->data
+ nut
->header_len
[header_idx
], pkt
->size
- nut
->header_len
[header_idx
]);
1147 nus
->last_flags
= flags
;
1148 nus
->last_pts
= pkt
->pts
;
1150 //FIXME just store one per syncpoint
1151 if (flags
& FLAG_KEY
&& !(nut
->flags
& NUT_PIPE
)) {
1153 s
->streams
[pkt
->stream_index
],
1154 nut
->last_syncpoint_pos
,
1159 if (nus
->keyframe_pts
&& nus
->keyframe_pts
[nut
->sp_count
] == AV_NOPTS_VALUE
)
1160 nus
->keyframe_pts
[nut
->sp_count
] = pkt
->pts
;
1163 if (!nut
->max_pts_tb
|| av_compare_ts(nut
->max_pts
, *nut
->max_pts_tb
, pkt
->pts
, *nus
->time_base
) < 0) {
1164 nut
->max_pts
= pkt
->pts
;
1165 nut
->max_pts_tb
= nus
->time_base
;
1174 static int nut_write_trailer(AVFormatContext
*s
)
1176 NUTContext
*nut
= s
->priv_data
;
1177 AVIOContext
*bc
= s
->pb
, *dyn_bc
;
1180 while (nut
->header_count
< 3)
1181 write_headers(s
, bc
);
1183 ret
= avio_open_dyn_buf(&dyn_bc
);
1184 if (ret
>= 0 && nut
->sp_count
) {
1185 av_assert1(nut
->write_index
);
1186 write_index(nut
, dyn_bc
);
1187 put_packet(nut
, bc
, dyn_bc
, 1, INDEX_STARTCODE
);
1190 ff_nut_free_sp(nut
);
1191 for (i
=0; i
<s
->nb_streams
; i
++)
1192 av_freep(&nut
->stream
[i
].keyframe_pts
);
1194 av_freep(&nut
->stream
);
1195 av_freep(&nut
->chapter
);
1196 av_freep(&nut
->time_base
);
1201 #define OFFSET(x) offsetof(NUTContext, x)
1202 #define E AV_OPT_FLAG_ENCODING_PARAM
1203 static const AVOption options
[] = {
1204 { "syncpoints", "NUT syncpoint behaviour", OFFSET(flags
), AV_OPT_TYPE_FLAGS
, {.i64
= 0}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
1205 { "default", "", 0, AV_OPT_TYPE_CONST
, {.i64
= 0}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
1206 { "none", "Disable syncpoints, low overhead and unseekable", 0, AV_OPT_TYPE_CONST
, {.i64
= NUT_PIPE
}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
1207 { "timestamped", "Extend syncpoints with a wallclock timestamp", 0, AV_OPT_TYPE_CONST
, {.i64
= NUT_BROADCAST
}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
1208 { "write_index", "Write index", OFFSET(write_index
), AV_OPT_TYPE_INT
, {.i64
= 1}, 0, 1, E
, },
1212 static const AVClass
class = {
1213 .class_name
= "nutenc",
1214 .item_name
= av_default_item_name
,
1216 .version
= LIBAVUTIL_VERSION_INT
,
1219 AVOutputFormat ff_nut_muxer
= {
1221 .long_name
= NULL_IF_CONFIG_SMALL("NUT"),
1222 .mime_type
= "video/x-nut",
1223 .extensions
= "nut",
1224 .priv_data_size
= sizeof(NUTContext
),
1225 .audio_codec
= CONFIG_LIBVORBIS
? AV_CODEC_ID_VORBIS
:
1226 CONFIG_LIBMP3LAME
? AV_CODEC_ID_MP3
: AV_CODEC_ID_MP2
,
1227 .video_codec
= AV_CODEC_ID_MPEG4
,
1228 .write_header
= nut_write_header
,
1229 .write_packet
= nut_write_packet
,
1230 .write_trailer
= nut_write_trailer
,
1231 .flags
= AVFMT_GLOBALHEADER
| AVFMT_VARIABLE_FPS
,
1232 .codec_tag
= ff_nut_codec_tags
,
1233 .priv_class
= &class,