3 * Copyright (c) 2004-2007 Michael Niedermayer
5 * This file is part of Libav.
7 * Libav 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 * Libav 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 Libav; 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/time.h"
29 #include "libavutil/opt.h"
30 #include "libavcodec/mpegaudiodata.h"
33 #include "avio_internal.h"
36 static int find_expected_header(AVCodecContext
*c
, int size
, int key_frame
,
39 int sample_rate
= c
->sample_rate
;
46 if (c
->codec_id
== AV_CODEC_ID_MPEG4
) {
53 } else if (c
->codec_id
== AV_CODEC_ID_MPEG1VIDEO
||
54 c
->codec_id
== AV_CODEC_ID_MPEG2VIDEO
) {
56 } else if (c
->codec_id
== AV_CODEC_ID_H264
) {
58 } else if (c
->codec_id
== AV_CODEC_ID_MP3
||
59 c
->codec_id
== AV_CODEC_ID_MP2
) {
60 int lsf
, mpeg25
, sample_rate_index
, bitrate_index
, frame_size
;
61 int layer
= c
->codec_id
== AV_CODEC_ID_MP3 ?
3 : 2;
62 unsigned int header
= 0xFFF00000;
64 lsf
= sample_rate
< (24000 + 32000) / 2;
65 mpeg25
= sample_rate
< (12000 + 16000) / 2;
66 sample_rate
<<= lsf
+ mpeg25
;
67 if (sample_rate
< (32000 + 44100) / 2)
68 sample_rate_index
= 2;
69 else if (sample_rate
< (44100 + 48000) / 2)
70 sample_rate_index
= 0;
72 sample_rate_index
= 1;
74 sample_rate
= avpriv_mpa_freq_tab
[sample_rate_index
] >> (lsf
+ mpeg25
);
76 for (bitrate_index
= 2; bitrate_index
< 30; bitrate_index
++) {
78 avpriv_mpa_bitrate_tab
[lsf
][layer
- 1][bitrate_index
>> 1];
79 frame_size
= (frame_size
* 144000) / (sample_rate
<< lsf
) +
82 if (frame_size
== size
)
86 header
|= (!lsf
) << 19;
87 header
|= (4 - layer
) << 17;
88 header
|= 1 << 16; //no crc
91 return 2; //we guess there is no crc, if there is one the user clearly does not care about overhead
92 if (bitrate_index
== 30)
93 return -1; //something is wrong ...
95 header
|= (bitrate_index
>> 1) << 12;
96 header
|= sample_rate_index
<< 10;
97 header
|= (bitrate_index
& 1) << 9;
99 return 2; //FIXME actually put the needed ones in build_elision_headers()
100 //return 3; //we guess that the private bit is not set
101 //FIXME the above assumptions should be checked, if these turn out false too often something should be done
106 static int find_header_idx(AVFormatContext
*s
, AVCodecContext
*c
, int size
,
109 NUTContext
*nut
= s
->priv_data
;
112 int len
= find_expected_header(c
, size
, frame_type
, out
);
114 for (i
= 1; i
< nut
->header_count
; i
++) {
115 if (len
== nut
->header_len
[i
] && !memcmp(out
, nut
->header
[i
], len
)) {
123 static void build_elision_headers(AVFormatContext
*s
)
125 NUTContext
*nut
= s
->priv_data
;
128 //FIXME write a 2pass mode to find the maximal headers
129 static const uint8_t headers
[][5] = {
130 { 3, 0x00, 0x00, 0x01 },
131 { 4, 0x00, 0x00, 0x01, 0xB6},
132 { 2, 0xFF, 0xFA }, //mp3+crc
133 { 2, 0xFF, 0xFB }, //mp3
134 { 2, 0xFF, 0xFC }, //mp2+crc
135 { 2, 0xFF, 0xFD }, //mp2
138 nut
->header_count
= 7;
139 for (i
= 1; i
< nut
->header_count
; i
++) {
140 nut
->header_len
[i
] = headers
[i
- 1][0];
141 nut
->header
[i
] = &headers
[i
- 1][1];
145 static void build_frame_code(AVFormatContext
*s
)
147 NUTContext
*nut
= s
->priv_data
;
148 int key_frame
, index
, pred
, stream_id
;
151 int keyframe_0_esc
= s
->nb_streams
> 2;
155 ft
= &nut
->frame_code
[start
];
156 ft
->flags
= FLAG_CODED
;
161 if (keyframe_0_esc
) {
162 /* keyframe = 0 escape */
163 FrameCode
*ft
= &nut
->frame_code
[start
];
164 ft
->flags
= FLAG_STREAM_ID
| FLAG_SIZE_MSB
| FLAG_CODED_PTS
;
169 for (stream_id
= 0; stream_id
< s
->nb_streams
; stream_id
++) {
170 int start2
= start
+ (end
- start
) * stream_id
/ s
->nb_streams
;
171 int end2
= start
+ (end
- start
) * (stream_id
+ 1) / s
->nb_streams
;
172 AVCodecContext
*codec
= s
->streams
[stream_id
]->codec
;
173 const AVCodecDescriptor
*desc
= avcodec_descriptor_get(codec
->codec_id
);
174 int is_audio
= codec
->codec_type
== AVMEDIA_TYPE_AUDIO
;
175 int intra_only
= /*codec->intra_only || */ is_audio
;
178 for (key_frame
= 0; key_frame
< 2; key_frame
++) {
179 if (!intra_only
|| !keyframe_0_esc
|| key_frame
!= 0) {
180 FrameCode
*ft
= &nut
->frame_code
[start2
];
181 ft
->flags
= FLAG_KEY
* key_frame
;
182 ft
->flags
|= FLAG_SIZE_MSB
| FLAG_CODED_PTS
;
183 ft
->stream_id
= stream_id
;
186 ft
->header_idx
= find_header_idx(s
, codec
, -1, key_frame
);
191 key_frame
= intra_only
;
193 int frame_bytes
= codec
->frame_size
* (int64_t)codec
->bit_rate
/
194 (8 * codec
->sample_rate
);
196 for (pts
= 0; pts
< 2; pts
++)
197 for (pred
= 0; pred
< 2; pred
++) {
198 FrameCode
*ft
= &nut
->frame_code
[start2
];
199 ft
->flags
= FLAG_KEY
* key_frame
;
200 ft
->stream_id
= stream_id
;
201 ft
->size_mul
= frame_bytes
+ 2;
202 ft
->size_lsb
= frame_bytes
+ pred
;
204 ft
->header_idx
= find_header_idx(s
, codec
, frame_bytes
+ pred
, key_frame
);
208 FrameCode
*ft
= &nut
->frame_code
[start2
];
209 ft
->flags
= FLAG_KEY
| FLAG_SIZE_MSB
;
210 ft
->stream_id
= stream_id
;
216 if (desc
&& desc
->props
& AV_CODEC_PROP_REORDER
) {
223 } else if (codec
->codec_id
== AV_CODEC_ID_VORBIS
) {
233 for (pred
= 0; pred
< pred_count
; pred
++) {
234 int start3
= start2
+ (end2
- start2
) * pred
/ pred_count
;
235 int end3
= start2
+ (end2
- start2
) * (pred
+ 1) / pred_count
;
237 for (index
= start3
; index
< end3
; index
++) {
238 FrameCode
*ft
= &nut
->frame_code
[index
];
239 ft
->flags
= FLAG_KEY
* key_frame
;
240 ft
->flags
|= FLAG_SIZE_MSB
;
241 ft
->stream_id
= stream_id
;
242 //FIXME use single byte size and pred from last
243 ft
->size_mul
= end3
- start3
;
244 ft
->size_lsb
= index
- start3
;
245 ft
->pts_delta
= pred_table
[pred
];
247 ft
->header_idx
= find_header_idx(s
, codec
, -1, key_frame
);
251 memmove(&nut
->frame_code
['N' + 1], &nut
->frame_code
['N'],
252 sizeof(FrameCode
) * (255 - 'N'));
253 nut
->frame_code
[0].flags
=
254 nut
->frame_code
[255].flags
=
255 nut
->frame_code
['N'].flags
= FLAG_INVALID
;
258 static void put_tt(NUTContext
*nut
, AVRational
*time_base
, AVIOContext
*bc
,
261 val
*= nut
->time_base_count
;
262 val
+= time_base
- nut
->time_base
;
266 * Store a string as vb.
268 static void put_str(AVIOContext
*bc
, const char *string
)
270 int len
= strlen(string
);
273 avio_write(bc
, string
, len
);
276 static void put_s(AVIOContext
*bc
, int64_t val
)
278 ff_put_v(bc
, 2 * FFABS(val
) - (val
> 0));
282 static inline void ff_put_v_trace(AVIOContext
*bc
, uint64_t v
, const char *file
,
283 const char *func
, int line
)
285 av_log(NULL
, AV_LOG_DEBUG
, "ff_put_v %5"PRId64
" / %"PRIX64
" in %s %s:%d\n", v
, v
, file
, func
, line
);
290 static inline void put_s_trace(AVIOContext
*bc
, int64_t v
, const char *file
,
291 const char *func
, int line
)
293 av_log(NULL
, AV_LOG_DEBUG
, "put_s %5"PRId64
" / %"PRIX64
" in %s %s:%d\n", v
, v
, file
, func
, line
);
297 #define ff_put_v(bc, v) ff_put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
298 #define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
301 //FIXME remove calculate_checksum
302 static void put_packet(NUTContext
*nut
, AVIOContext
*bc
, AVIOContext
*dyn_bc
,
303 int calculate_checksum
, uint64_t startcode
)
305 uint8_t *dyn_buf
= NULL
;
306 int dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
307 int forw_ptr
= dyn_size
+ 4 * calculate_checksum
;
310 ffio_init_checksum(bc
, ff_crc04C11DB7_update
, 0);
311 avio_wb64(bc
, startcode
);
312 ff_put_v(bc
, forw_ptr
);
314 avio_wl32(bc
, ffio_get_checksum(bc
));
316 if (calculate_checksum
)
317 ffio_init_checksum(bc
, ff_crc04C11DB7_update
, 0);
318 avio_write(bc
, dyn_buf
, dyn_size
);
319 if (calculate_checksum
)
320 avio_wl32(bc
, ffio_get_checksum(bc
));
325 static void write_mainheader(NUTContext
*nut
, AVIOContext
*bc
)
327 int i
, j
, tmp_pts
, tmp_flags
, tmp_stream
, tmp_mul
, tmp_size
, tmp_fields
,
331 ff_put_v(bc
, nut
->version
);
332 ff_put_v(bc
, nut
->avf
->nb_streams
);
333 ff_put_v(bc
, nut
->max_distance
);
334 ff_put_v(bc
, nut
->time_base_count
);
336 for (i
= 0; i
< nut
->time_base_count
; i
++) {
337 ff_put_v(bc
, nut
->time_base
[i
].num
);
338 ff_put_v(bc
, nut
->time_base
[i
].den
);
344 tmp_match
= 1 - (1LL << 62);
346 for (i
= 0; i
< 256; ) {
350 if (tmp_pts
!= nut
->frame_code
[i
].pts_delta
)
352 if (tmp_mul
!= nut
->frame_code
[i
].size_mul
)
354 if (tmp_stream
!= nut
->frame_code
[i
].stream_id
)
356 if (tmp_size
!= nut
->frame_code
[i
].size_lsb
)
358 // if(tmp_res != nut->frame_code[i].res ) tmp_fields=5;
359 if (tmp_head_idx
!= nut
->frame_code
[i
].header_idx
)
362 tmp_pts
= nut
->frame_code
[i
].pts_delta
;
363 tmp_flags
= nut
->frame_code
[i
].flags
;
364 tmp_stream
= nut
->frame_code
[i
].stream_id
;
365 tmp_mul
= nut
->frame_code
[i
].size_mul
;
366 tmp_size
= nut
->frame_code
[i
].size_lsb
;
367 // tmp_res = nut->frame_code[i].res;
368 tmp_head_idx
= nut
->frame_code
[i
].header_idx
;
370 for (j
= 0; i
< 256; j
++, i
++) {
375 if (nut
->frame_code
[i
].pts_delta
!= tmp_pts
||
376 nut
->frame_code
[i
].flags
!= tmp_flags
||
377 nut
->frame_code
[i
].stream_id
!= tmp_stream
||
378 nut
->frame_code
[i
].size_mul
!= tmp_mul
||
379 nut
->frame_code
[i
].size_lsb
!= tmp_size
+ j
||
380 // nut->frame_code[i].res != tmp_res ||
381 nut
->frame_code
[i
].header_idx
!= tmp_head_idx
)
384 if (j
!= tmp_mul
- tmp_size
)
387 ff_put_v(bc
, tmp_flags
);
388 ff_put_v(bc
, tmp_fields
);
392 ff_put_v(bc
, tmp_mul
);
394 ff_put_v(bc
, tmp_stream
);
396 ff_put_v(bc
, tmp_size
);
398 ff_put_v(bc
, 0 /*tmp_res*/);
402 ff_put_v(bc
, tmp_match
);
404 ff_put_v(bc
, tmp_head_idx
);
406 ff_put_v(bc
, nut
->header_count
- 1);
407 for (i
= 1; i
< nut
->header_count
; i
++) {
408 ff_put_v(bc
, nut
->header_len
[i
]);
409 avio_write(bc
, nut
->header
[i
], nut
->header_len
[i
]);
411 // flags had been effectively introduced in version 4
412 if (nut
->version
> NUT_STABLE_VERSION
)
413 ff_put_v(bc
, nut
->flags
);
416 static int write_streamheader(AVFormatContext
*avctx
, AVIOContext
*bc
,
419 NUTContext
*nut
= avctx
->priv_data
;
420 AVCodecContext
*codec
= st
->codec
;
421 const AVCodecDescriptor
*desc
= avcodec_descriptor_get(codec
->codec_id
);
422 unsigned codec_tag
= av_codec_get_tag(ff_nut_codec_tags
, codec
->codec_id
);
425 switch (codec
->codec_type
) {
426 case AVMEDIA_TYPE_VIDEO
:
429 case AVMEDIA_TYPE_AUDIO
:
432 case AVMEDIA_TYPE_SUBTITLE
:
441 if (av_codec_get_id(ff_nut_codec_tags
, codec
->codec_tag
) == codec
->codec_id
||
442 !codec_tag
|| codec
->codec_id
== AV_CODEC_ID_RAWVIDEO
)
443 codec_tag
= codec
->codec_tag
;
446 avio_wl32(bc
, codec_tag
);
448 av_log(avctx
, AV_LOG_ERROR
, "No codec tag defined for stream %d\n", i
);
449 return AVERROR(EINVAL
);
452 ff_put_v(bc
, nut
->stream
[i
].time_base
- nut
->time_base
);
453 ff_put_v(bc
, nut
->stream
[i
].msb_pts_shift
);
454 ff_put_v(bc
, nut
->stream
[i
].max_pts_distance
);
455 ff_put_v(bc
, (desc
&& desc
->props
& AV_CODEC_PROP_REORDER
) ?
16 : 0);
456 avio_w8(bc
, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
458 ff_put_v(bc
, codec
->extradata_size
);
459 avio_write(bc
, codec
->extradata
, codec
->extradata_size
);
461 switch (codec
->codec_type
) {
462 case AVMEDIA_TYPE_AUDIO
:
463 ff_put_v(bc
, codec
->sample_rate
);
465 ff_put_v(bc
, codec
->channels
);
467 case AVMEDIA_TYPE_VIDEO
:
468 ff_put_v(bc
, codec
->width
);
469 ff_put_v(bc
, codec
->height
);
471 if (st
->sample_aspect_ratio
.num
<= 0 ||
472 st
->sample_aspect_ratio
.den
<= 0) {
476 ff_put_v(bc
, st
->sample_aspect_ratio
.num
);
477 ff_put_v(bc
, st
->sample_aspect_ratio
.den
);
479 ff_put_v(bc
, 0); /* csp type -- unknown */
487 static int add_info(AVIOContext
*bc
, const char *type
, const char *value
)
495 static int write_globalinfo(NUTContext
*nut
, AVIOContext
*bc
)
497 AVFormatContext
*s
= nut
->avf
;
498 AVDictionaryEntry
*t
= NULL
;
500 uint8_t *dyn_buf
= NULL
;
501 int count
= 0, dyn_size
;
502 int ret
= avio_open_dyn_buf(&dyn_bc
);
506 while ((t
= av_dict_get(s
->metadata
, "", t
, AV_DICT_IGNORE_SUFFIX
)))
507 count
+= add_info(dyn_bc
, t
->key
, t
->value
);
509 ff_put_v(bc
, 0); //stream_if_plus1
510 ff_put_v(bc
, 0); //chapter_id
511 ff_put_v(bc
, 0); //timestamp_start
512 ff_put_v(bc
, 0); //length
516 dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
517 avio_write(bc
, dyn_buf
, dyn_size
);
522 static int write_streaminfo(NUTContext
*nut
, AVIOContext
*bc
, int stream_id
){
523 AVFormatContext
*s
= nut
->avf
;
524 AVStream
* st
= s
->streams
[stream_id
];
526 uint8_t *dyn_buf
=NULL
;
527 int count
=0, dyn_size
, i
;
528 int ret
= avio_open_dyn_buf(&dyn_bc
);
532 for (i
=0; ff_nut_dispositions
[i
].flag
; ++i
) {
533 if (st
->disposition
& ff_nut_dispositions
[i
].flag
)
534 count
+= add_info(dyn_bc
, "Disposition", ff_nut_dispositions
[i
].str
);
536 dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
539 ff_put_v(bc
, stream_id
+ 1); //stream_id_plus1
540 ff_put_v(bc
, 0); //chapter_id
541 ff_put_v(bc
, 0); //timestamp_start
542 ff_put_v(bc
, 0); //length
546 avio_write(bc
, dyn_buf
, dyn_size
);
553 static int write_chapter(NUTContext
*nut
, AVIOContext
*bc
, int id
)
556 uint8_t *dyn_buf
= NULL
;
557 AVDictionaryEntry
*t
= NULL
;
558 AVChapter
*ch
= nut
->avf
->chapters
[id
];
559 int ret
, dyn_size
, count
= 0;
561 ret
= avio_open_dyn_buf(&dyn_bc
);
565 ff_put_v(bc
, 0); // stream_id_plus1
566 put_s(bc
, id
+ 1); // chapter_id
567 put_tt(nut
, nut
->chapter
[id
].time_base
, bc
, ch
->start
); // chapter_start
568 ff_put_v(bc
, ch
->end
- ch
->start
); // chapter_len
570 while ((t
= av_dict_get(ch
->metadata
, "", t
, AV_DICT_IGNORE_SUFFIX
)))
571 count
+= add_info(dyn_bc
, t
->key
, t
->value
);
575 dyn_size
= avio_close_dyn_buf(dyn_bc
, &dyn_buf
);
576 avio_write(bc
, dyn_buf
, dyn_size
);
581 static int write_headers(AVFormatContext
*avctx
, AVIOContext
*bc
)
583 NUTContext
*nut
= avctx
->priv_data
;
587 ff_metadata_conv_ctx(avctx
, ff_nut_metadata_conv
, NULL
);
589 ret
= avio_open_dyn_buf(&dyn_bc
);
592 write_mainheader(nut
, dyn_bc
);
593 put_packet(nut
, bc
, dyn_bc
, 1, MAIN_STARTCODE
);
595 for (i
= 0; i
< nut
->avf
->nb_streams
; i
++) {
596 ret
= avio_open_dyn_buf(&dyn_bc
);
599 ret
= write_streamheader(avctx
, dyn_bc
, nut
->avf
->streams
[i
], i
);
602 put_packet(nut
, bc
, dyn_bc
, 1, STREAM_STARTCODE
);
605 ret
= avio_open_dyn_buf(&dyn_bc
);
608 write_globalinfo(nut
, dyn_bc
);
609 put_packet(nut
, bc
, dyn_bc
, 1, INFO_STARTCODE
);
611 for (i
= 0; i
< nut
->avf
->nb_streams
; i
++) {
612 ret
= avio_open_dyn_buf(&dyn_bc
);
615 ret
= write_streaminfo(nut
, dyn_bc
, i
);
619 put_packet(nut
, bc
, dyn_bc
, 1, INFO_STARTCODE
);
621 ffio_free_dyn_buf(&dyn_bc
);
624 for (i
= 0; i
< nut
->avf
->nb_chapters
; i
++) {
625 ret
= avio_open_dyn_buf(&dyn_bc
);
628 ret
= write_chapter(nut
, dyn_bc
, i
);
630 ffio_free_dyn_buf(&dyn_bc
);
633 put_packet(nut
, bc
, dyn_bc
, 1, INFO_STARTCODE
);
636 nut
->last_syncpoint_pos
= INT_MIN
;
641 static int nut_write_header(AVFormatContext
*s
)
643 NUTContext
*nut
= s
->priv_data
;
644 AVIOContext
*bc
= s
->pb
;
649 nut
->version
= NUT_STABLE_VERSION
+ !!nut
->flags
;
650 if (nut
->flags
&& s
->strict_std_compliance
> FF_COMPLIANCE_EXPERIMENTAL
) {
651 av_log(s
, AV_LOG_ERROR
,
652 "The additional syncpoint modes require version %d, "
653 "that is currently not finalized, "
654 "please set -f_strict experimental in order to enable it.\n",
656 return AVERROR_EXPERIMENTAL
;
659 nut
->stream
= av_mallocz(sizeof(StreamContext
) * s
->nb_streams
);
661 nut
->chapter
= av_mallocz(sizeof(ChapterContext
) * s
->nb_chapters
);
662 nut
->time_base
= av_mallocz(sizeof(AVRational
) * (s
->nb_streams
+
664 if (!nut
->stream
|| (s
->nb_chapters
&& !nut
->chapter
) || !nut
->time_base
) {
665 av_freep(&nut
->stream
);
666 av_freep(&nut
->chapter
);
667 av_freep(&nut
->time_base
);
668 return AVERROR(ENOMEM
);
671 for (i
= 0; i
< s
->nb_streams
; i
++) {
672 AVStream
*st
= s
->streams
[i
];
674 AVRational time_base
;
675 ff_parse_specific_params(st
, &time_base
.den
, &ssize
,
678 avpriv_set_pts_info(st
, 64, time_base
.num
, time_base
.den
);
680 for (j
= 0; j
< nut
->time_base_count
; j
++)
681 if (!memcmp(&time_base
, &nut
->time_base
[j
], sizeof(AVRational
))) {
684 nut
->time_base
[j
] = time_base
;
685 nut
->stream
[i
].time_base
= &nut
->time_base
[j
];
686 if (j
== nut
->time_base_count
)
687 nut
->time_base_count
++;
689 if (INT64_C(1000) * time_base
.num
>= time_base
.den
)
690 nut
->stream
[i
].msb_pts_shift
= 7;
692 nut
->stream
[i
].msb_pts_shift
= 14;
693 nut
->stream
[i
].max_pts_distance
=
694 FFMAX(time_base
.den
, time_base
.num
) / time_base
.num
;
697 for (i
= 0; i
< s
->nb_chapters
; i
++) {
698 AVChapter
*ch
= s
->chapters
[i
];
700 for (j
= 0; j
< nut
->time_base_count
; j
++)
701 if (!memcmp(&ch
->time_base
, &nut
->time_base
[j
], sizeof(AVRational
)))
704 nut
->time_base
[j
] = ch
->time_base
;
705 nut
->chapter
[i
].time_base
= &nut
->time_base
[j
];
706 if (j
== nut
->time_base_count
)
707 nut
->time_base_count
++;
710 nut
->max_distance
= MAX_DISTANCE
;
711 build_elision_headers(s
);
713 assert(nut
->frame_code
['N'].flags
== FLAG_INVALID
);
715 avio_write(bc
, ID_STRING
, strlen(ID_STRING
));
718 if ((ret
= write_headers(s
, bc
)) < 0)
728 static int get_needed_flags(NUTContext
*nut
, StreamContext
*nus
, FrameCode
*fc
,
733 if (pkt
->flags
& AV_PKT_FLAG_KEY
)
735 if (pkt
->stream_index
!= fc
->stream_id
)
736 flags
|= FLAG_STREAM_ID
;
737 if (pkt
->size
/ fc
->size_mul
)
738 flags
|= FLAG_SIZE_MSB
;
739 if (pkt
->pts
- nus
->last_pts
!= fc
->pts_delta
)
740 flags
|= FLAG_CODED_PTS
;
741 if (pkt
->size
> 2 * nut
->max_distance
)
742 flags
|= FLAG_CHECKSUM
;
743 if (FFABS(pkt
->pts
- nus
->last_pts
) > nus
->max_pts_distance
)
744 flags
|= FLAG_CHECKSUM
;
745 if (pkt
->size
< nut
->header_len
[fc
->header_idx
] ||
746 (pkt
->size
> 4096 && fc
->header_idx
) ||
747 memcmp(pkt
->data
, nut
->header
[fc
->header_idx
],
748 nut
->header_len
[fc
->header_idx
]))
749 flags
|= FLAG_HEADER_IDX
;
751 return flags
| (fc
->flags
& FLAG_CODED
);
754 static int find_best_header_idx(NUTContext
*nut
, AVPacket
*pkt
)
760 if (pkt
->size
> 4096)
763 for (i
= 1; i
< nut
->header_count
; i
++)
764 if (pkt
->size
>= nut
->header_len
[i
]
765 && nut
->header_len
[i
] > best_len
766 && !memcmp(pkt
->data
, nut
->header
[i
], nut
->header_len
[i
])) {
768 best_len
= nut
->header_len
[i
];
773 static int nut_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
775 NUTContext
*nut
= s
->priv_data
;
776 StreamContext
*nus
= &nut
->stream
[pkt
->stream_index
];
777 AVIOContext
*bc
= s
->pb
, *dyn_bc
;
780 int best_length
, frame_code
, flags
, needed_flags
, i
, header_idx
,
782 int key_frame
= !!(pkt
->flags
& AV_PKT_FLAG_KEY
);
787 av_log(s
, AV_LOG_ERROR
,
788 "Negative pts not supported stream %d, pts %"PRId64
"\n",
789 pkt
->stream_index
, pkt
->pts
);
790 return AVERROR_INVALIDDATA
;
793 if (1LL << (20 + 3 * nut
->header_count
) <= avio_tell(bc
))
794 write_headers(s
, bc
);
796 if (key_frame
&& !(nus
->last_flags
& FLAG_KEY
))
799 if (pkt
->size
+ 30 /*FIXME check*/ + avio_tell(bc
) >=
800 nut
->last_syncpoint_pos
+ nut
->max_distance
)
803 //FIXME: Ensure store_sp is 1 in the first place.
806 (!(nut
->flags
& NUT_PIPE
) || nut
->last_syncpoint_pos
== INT_MIN
)) {
807 Syncpoint
*sp
, dummy
= { .pos
= INT64_MAX
};
809 ff_nut_reset_ts(nut
, *nus
->time_base
, pkt
->dts
);
810 for (i
= 0; i
< s
->nb_streams
; i
++) {
811 AVStream
*st
= s
->streams
[i
];
812 int64_t dts_tb
= av_rescale_rnd(pkt
->dts
,
813 nus
->time_base
->num
* (int64_t)nut
->stream
[i
].time_base
->den
,
814 nus
->time_base
->den
* (int64_t)nut
->stream
[i
].time_base
->num
,
816 int index
= av_index_search_timestamp(st
, dts_tb
,
817 AVSEEK_FLAG_BACKWARD
);
819 dummy
.pos
= FFMIN(dummy
.pos
, st
->index_entries
[index
].pos
);
821 if (dummy
.pos
== INT64_MAX
)
823 sp
= av_tree_find(nut
->syncpoints
, &dummy
, (void *)ff_nut_sp_pos_cmp
,
826 nut
->last_syncpoint_pos
= avio_tell(bc
);
827 ret
= avio_open_dyn_buf(&dyn_bc
);
830 put_tt(nut
, nus
->time_base
, dyn_bc
, pkt
->dts
);
831 ff_put_v(dyn_bc
, sp ?
(nut
->last_syncpoint_pos
- sp
->pos
) >> 4 : 0);
833 if (nut
->flags
& NUT_BROADCAST
) {
834 put_tt(nut
, nus
->time_base
, dyn_bc
,
835 av_rescale_q(av_gettime(), AV_TIME_BASE_Q
, *nus
->time_base
));
837 put_packet(nut
, bc
, dyn_bc
, 1, SYNCPOINT_STARTCODE
);
839 if ((ret
= ff_nut_add_sp(nut
, nut
->last_syncpoint_pos
, 0 /*unused*/, pkt
->dts
)) < 0)
842 assert(nus
->last_pts
!= AV_NOPTS_VALUE
);
844 coded_pts
= pkt
->pts
& ((1 << nus
->msb_pts_shift
) - 1);
845 if (ff_lsb2full(nus
, coded_pts
) != pkt
->pts
)
846 coded_pts
= pkt
->pts
+ (1 << nus
->msb_pts_shift
);
848 best_header_idx
= find_best_header_idx(nut
, pkt
);
850 best_length
= INT_MAX
;
852 for (i
= 0; i
< 256; i
++) {
854 FrameCode
*fc
= &nut
->frame_code
[i
];
855 int flags
= fc
->flags
;
857 if (flags
& FLAG_INVALID
)
859 needed_flags
= get_needed_flags(nut
, nus
, fc
, pkt
);
861 if (flags
& FLAG_CODED
) {
863 flags
= needed_flags
;
866 if ((flags
& needed_flags
) != needed_flags
)
869 if ((flags
^ needed_flags
) & FLAG_KEY
)
872 if (flags
& FLAG_STREAM_ID
)
873 length
+= ff_get_v_length(pkt
->stream_index
);
875 if (pkt
->size
% fc
->size_mul
!= fc
->size_lsb
)
877 if (flags
& FLAG_SIZE_MSB
)
878 length
+= ff_get_v_length(pkt
->size
/ fc
->size_mul
);
880 if (flags
& FLAG_CHECKSUM
)
883 if (flags
& FLAG_CODED_PTS
)
884 length
+= ff_get_v_length(coded_pts
);
886 if ((flags
& FLAG_CODED
)
887 && nut
->header_len
[best_header_idx
] >
888 nut
->header_len
[fc
->header_idx
] + 1) {
889 flags
|= FLAG_HEADER_IDX
;
892 if (flags
& FLAG_HEADER_IDX
) {
893 length
+= 1 - nut
->header_len
[best_header_idx
];
895 length
-= nut
->header_len
[fc
->header_idx
];
899 length
+= !(flags
& FLAG_CODED_PTS
);
900 length
+= !(flags
& FLAG_CHECKSUM
);
902 if (length
< best_length
) {
903 best_length
= length
;
911 fc
= &nut
->frame_code
[frame_code
];
913 needed_flags
= get_needed_flags(nut
, nus
, fc
, pkt
);
914 header_idx
= fc
->header_idx
;
916 ffio_init_checksum(bc
, ff_crc04C11DB7_update
, 0);
917 avio_w8(bc
, frame_code
);
918 if (flags
& FLAG_CODED
) {
919 ff_put_v(bc
, (flags
^ needed_flags
) & ~(FLAG_CODED
));
920 flags
= needed_flags
;
922 if (flags
& FLAG_STREAM_ID
)
923 ff_put_v(bc
, pkt
->stream_index
);
924 if (flags
& FLAG_CODED_PTS
)
925 ff_put_v(bc
, coded_pts
);
926 if (flags
& FLAG_SIZE_MSB
)
927 ff_put_v(bc
, pkt
->size
/ fc
->size_mul
);
928 if (flags
& FLAG_HEADER_IDX
)
929 ff_put_v(bc
, header_idx
= best_header_idx
);
931 if (flags
& FLAG_CHECKSUM
)
932 avio_wl32(bc
, ffio_get_checksum(bc
));
934 ffio_get_checksum(bc
);
936 avio_write(bc
, pkt
->data
+ nut
->header_len
[header_idx
],
937 pkt
->size
- nut
->header_len
[header_idx
]);
938 nus
->last_flags
= flags
;
939 nus
->last_pts
= pkt
->pts
;
941 //FIXME just store one per syncpoint
942 if (flags
& FLAG_KEY
&& !(nut
->flags
& NUT_PIPE
))
944 s
->streams
[pkt
->stream_index
],
945 nut
->last_syncpoint_pos
,
954 static int nut_write_trailer(AVFormatContext
*s
)
956 NUTContext
*nut
= s
->priv_data
;
957 AVIOContext
*bc
= s
->pb
;
959 while (nut
->header_count
< 3)
960 write_headers(s
, bc
);
963 av_freep(&nut
->stream
);
964 av_freep(&nut
->chapter
);
965 av_freep(&nut
->time_base
);
970 #define OFFSET(x) offsetof(NUTContext, x)
971 #define E AV_OPT_FLAG_ENCODING_PARAM
972 static const AVOption options
[] = {
973 { "syncpoints", "NUT syncpoint behaviour", OFFSET(flags
), AV_OPT_TYPE_FLAGS
, {.i64
= 0}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
974 { "default", "", 0, AV_OPT_TYPE_CONST
, {.i64
= 0}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
975 { "none", "Disable syncpoints, low overhead and unseekable", 0, AV_OPT_TYPE_CONST
, {.i64
= NUT_PIPE
}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
976 { "timestamped", "Extend syncpoints with a wallclock timestamp", 0, AV_OPT_TYPE_CONST
, {.i64
= NUT_BROADCAST
}, INT_MIN
, INT_MAX
, E
, "syncpoints" },
980 static const AVClass
class = {
981 .class_name
= "nutenc",
982 .item_name
= av_default_item_name
,
984 .version
= LIBAVUTIL_VERSION_INT
,
987 AVOutputFormat ff_nut_muxer
= {
989 .long_name
= NULL_IF_CONFIG_SMALL("NUT"),
990 .mime_type
= "video/x-nut",
992 .priv_data_size
= sizeof(NUTContext
),
993 .audio_codec
= CONFIG_LIBVORBIS ? AV_CODEC_ID_VORBIS
:
994 CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3
: AV_CODEC_ID_MP2
,
995 .video_codec
= AV_CODEC_ID_MPEG4
,
996 .write_header
= nut_write_header
,
997 .write_packet
= nut_write_packet
,
998 .write_trailer
= nut_write_trailer
,
999 .flags
= AVFMT_GLOBALHEADER
| AVFMT_VARIABLE_FPS
,
1000 .codec_tag
= ff_nut_codec_tags
,
1001 .priv_class
= &class,