2 * "NUT" Container Format demuxer
3 * Copyright (c) 2004-2006 Michael Niedermayer
4 * Copyright (c) 2003 Alex Beregszaszi
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libavutil/avstring.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/bswap.h"
26 #include "libavutil/dict.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/mathematics.h"
29 #include "libavutil/tree.h"
30 #include "libavcodec/bytestream.h"
31 #include "avio_internal.h"
36 #define NUT_MAX_STREAMS 256 /* arbitrary sanity check value */
38 static int64_t nut_read_timestamp(AVFormatContext
*s
, int stream_index
,
39 int64_t *pos_arg
, int64_t pos_limit
);
41 static int get_str(AVIOContext
*bc
, char *string
, unsigned int maxlen
)
43 unsigned int len
= ffio_read_varlen(bc
);
46 avio_read(bc
, string
, FFMIN(len
, maxlen
));
47 while (len
> maxlen
) {
53 string
[FFMIN(len
, maxlen
- 1)] = 0;
61 static int64_t get_s(AVIOContext
*bc
)
63 int64_t v
= ffio_read_varlen(bc
) + 1;
71 static uint64_t get_fourcc(AVIOContext
*bc
)
73 unsigned int len
= ffio_read_varlen(bc
);
80 av_log(NULL
, AV_LOG_ERROR
, "Unsupported fourcc length %d\n", len
);
86 static inline uint64_t get_v_trace(AVIOContext
*bc
, const char *file
,
87 const char *func
, int line
)
89 uint64_t v
= ffio_read_varlen(bc
);
91 av_log(NULL
, AV_LOG_DEBUG
, "get_v %5"PRId64
" / %"PRIX64
" in %s %s:%d\n",
92 v
, v
, file
, func
, line
);
96 static inline int64_t get_s_trace(AVIOContext
*bc
, const char *file
,
97 const char *func
, int line
)
99 int64_t v
= get_s(bc
);
101 av_log(NULL
, AV_LOG_DEBUG
, "get_s %5"PRId64
" / %"PRIX64
" in %s %s:%d\n",
102 v
, v
, file
, func
, line
);
106 static inline uint64_t get_4cc_trace(AVIOContext
*bc
, char *file
,
107 char *func
, int line
)
109 uint64_t v
= get_fourcc(bc
);
111 av_log(NULL
, AV_LOG_DEBUG
, "get_fourcc %5"PRId64
" / %"PRIX64
" in %s %s:%d\n",
112 v
, v
, file
, func
, line
);
115 #define ffio_read_varlen(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
116 #define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
117 #define get_fourcc(bc) get_4cc_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
120 static int get_packetheader(NUTContext
*nut
, AVIOContext
*bc
,
121 int calculate_checksum
, uint64_t startcode
)
124 // start = avio_tell(bc) - 8;
126 startcode
= av_be2ne64(startcode
);
127 startcode
= ff_crc04C11DB7_update(0, (uint8_t*) &startcode
, 8);
129 ffio_init_checksum(bc
, ff_crc04C11DB7_update
, startcode
);
130 size
= ffio_read_varlen(bc
);
133 if (ffio_get_checksum(bc
) && size
> 4096)
136 ffio_init_checksum(bc
, calculate_checksum
? ff_crc04C11DB7_update
: NULL
, 0);
141 static uint64_t find_any_startcode(AVIOContext
*bc
, int64_t pos
)
146 /* Note, this may fail if the stream is not seekable, but that should
147 * not matter, as in this case we simply start where we currently are */
148 avio_seek(bc
, pos
, SEEK_SET
);
149 while (!avio_feof(bc
)) {
150 state
= (state
<< 8) | avio_r8(bc
);
151 if ((state
>> 56) != 'N')
155 case STREAM_STARTCODE
:
156 case SYNCPOINT_STARTCODE
:
158 case INDEX_STARTCODE
:
167 * Find the given startcode.
168 * @param code the startcode
169 * @param pos the start position of the search, or -1 if the current position
170 * @return the position of the startcode or -1 if not found
172 static int64_t find_startcode(AVIOContext
*bc
, uint64_t code
, int64_t pos
)
175 uint64_t startcode
= find_any_startcode(bc
, pos
);
176 if (startcode
== code
)
177 return avio_tell(bc
) - 8;
178 else if (startcode
== 0)
184 static int nut_probe(AVProbeData
*p
)
188 for (i
= 0; i
< p
->buf_size
-8; i
++) {
189 if (AV_RB32(p
->buf
+i
) != MAIN_STARTCODE
>>32)
191 if (AV_RB32(p
->buf
+i
+4) == (MAIN_STARTCODE
& 0xFFFFFFFF))
192 return AVPROBE_SCORE_MAX
;
197 #define GET_V(dst, check) \
199 tmp = ffio_read_varlen(bc); \
201 av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \
202 return AVERROR_INVALIDDATA; \
207 static int skip_reserved(AVIOContext
*bc
, int64_t pos
)
209 pos
-= avio_tell(bc
);
211 avio_seek(bc
, pos
, SEEK_CUR
);
212 return AVERROR_INVALIDDATA
;
220 static int decode_main_header(NUTContext
*nut
)
222 AVFormatContext
*s
= nut
->avf
;
223 AVIOContext
*bc
= s
->pb
;
225 unsigned int stream_count
;
227 int tmp_stream
, tmp_mul
, tmp_pts
, tmp_size
, tmp_res
, tmp_head_idx
;
229 end
= get_packetheader(nut
, bc
, 1, MAIN_STARTCODE
);
230 end
+= avio_tell(bc
);
232 nut
->version
= ffio_read_varlen(bc
);
233 if (nut
->version
< NUT_MIN_VERSION
&&
234 nut
->version
> NUT_MAX_VERSION
) {
235 av_log(s
, AV_LOG_ERROR
, "Version %d not supported.\n",
237 return AVERROR(ENOSYS
);
239 if (nut
->version
> 3)
240 nut
->minor_version
= ffio_read_varlen(bc
);
242 GET_V(stream_count
, tmp
> 0 && tmp
<= NUT_MAX_STREAMS
);
244 nut
->max_distance
= ffio_read_varlen(bc
);
245 if (nut
->max_distance
> 65536) {
246 av_log(s
, AV_LOG_DEBUG
, "max_distance %d\n", nut
->max_distance
);
247 nut
->max_distance
= 65536;
250 GET_V(nut
->time_base_count
, tmp
> 0 && tmp
< INT_MAX
/ sizeof(AVRational
));
251 nut
->time_base
= av_malloc(nut
->time_base_count
* sizeof(AVRational
));
253 return AVERROR(ENOMEM
);
255 for (i
= 0; i
< nut
->time_base_count
; i
++) {
256 GET_V(nut
->time_base
[i
].num
, tmp
> 0 && tmp
< (1ULL << 31));
257 GET_V(nut
->time_base
[i
].den
, tmp
> 0 && tmp
< (1ULL << 31));
258 if (av_gcd(nut
->time_base
[i
].num
, nut
->time_base
[i
].den
) != 1) {
259 av_log(s
, AV_LOG_ERROR
, "time base invalid\n");
260 return AVERROR_INVALIDDATA
;
267 for (i
= 0; i
< 256;) {
268 int tmp_flags
= ffio_read_varlen(bc
);
269 int tmp_fields
= ffio_read_varlen(bc
);
274 tmp_mul
= ffio_read_varlen(bc
);
276 tmp_stream
= ffio_read_varlen(bc
);
278 tmp_size
= ffio_read_varlen(bc
);
282 tmp_res
= ffio_read_varlen(bc
);
286 count
= ffio_read_varlen(bc
);
288 count
= tmp_mul
- tmp_size
;
292 tmp_head_idx
= ffio_read_varlen(bc
);
294 while (tmp_fields
-- > 8)
295 ffio_read_varlen(bc
);
297 if (count
== 0 || i
+ count
> 256) {
298 av_log(s
, AV_LOG_ERROR
, "illegal count %d at %d\n", count
, i
);
299 return AVERROR_INVALIDDATA
;
301 if (tmp_stream
>= stream_count
) {
302 av_log(s
, AV_LOG_ERROR
, "illegal stream number\n");
303 return AVERROR_INVALIDDATA
;
306 for (j
= 0; j
< count
; j
++, i
++) {
308 nut
->frame_code
[i
].flags
= FLAG_INVALID
;
312 nut
->frame_code
[i
].flags
= tmp_flags
;
313 nut
->frame_code
[i
].pts_delta
= tmp_pts
;
314 nut
->frame_code
[i
].stream_id
= tmp_stream
;
315 nut
->frame_code
[i
].size_mul
= tmp_mul
;
316 nut
->frame_code
[i
].size_lsb
= tmp_size
+ j
;
317 nut
->frame_code
[i
].reserved_count
= tmp_res
;
318 nut
->frame_code
[i
].header_idx
= tmp_head_idx
;
321 av_assert0(nut
->frame_code
['N'].flags
== FLAG_INVALID
);
323 if (end
> avio_tell(bc
) + 4) {
325 GET_V(nut
->header_count
, tmp
< 128U);
327 for (i
= 1; i
< nut
->header_count
; i
++) {
329 GET_V(nut
->header_len
[i
], tmp
> 0 && tmp
< 256);
330 rem
-= nut
->header_len
[i
];
332 av_log(s
, AV_LOG_ERROR
, "invalid elision header\n");
333 return AVERROR_INVALIDDATA
;
335 hdr
= av_malloc(nut
->header_len
[i
]);
337 return AVERROR(ENOMEM
);
338 avio_read(bc
, hdr
, nut
->header_len
[i
]);
339 nut
->header
[i
] = hdr
;
341 av_assert0(nut
->header_len
[0] == 0);
344 // flags had been effectively introduced in version 4
345 if (nut
->version
> 3 && end
> avio_tell(bc
) + 4) {
346 nut
->flags
= ffio_read_varlen(bc
);
349 if (skip_reserved(bc
, end
) || ffio_get_checksum(bc
)) {
350 av_log(s
, AV_LOG_ERROR
, "main header checksum mismatch\n");
351 return AVERROR_INVALIDDATA
;
354 nut
->stream
= av_calloc(stream_count
, sizeof(StreamContext
));
356 return AVERROR(ENOMEM
);
357 for (i
= 0; i
< stream_count
; i
++)
358 avformat_new_stream(s
, NULL
);
363 static int decode_stream_header(NUTContext
*nut
)
365 AVFormatContext
*s
= nut
->avf
;
366 AVIOContext
*bc
= s
->pb
;
368 int class, stream_id
;
372 end
= get_packetheader(nut
, bc
, 1, STREAM_STARTCODE
);
373 end
+= avio_tell(bc
);
375 GET_V(stream_id
, tmp
< s
->nb_streams
&& !nut
->stream
[tmp
].time_base
);
376 stc
= &nut
->stream
[stream_id
];
377 st
= s
->streams
[stream_id
];
379 return AVERROR(ENOMEM
);
381 class = ffio_read_varlen(bc
);
382 tmp
= get_fourcc(bc
);
383 st
->codec
->codec_tag
= tmp
;
386 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
387 st
->codec
->codec_id
= av_codec_get_id((const AVCodecTag
* const []) {
390 ff_codec_movvideo_tags
,
396 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
397 st
->codec
->codec_id
= av_codec_get_id((const AVCodecTag
* const []) {
400 ff_nut_audio_extra_tags
,
406 st
->codec
->codec_type
= AVMEDIA_TYPE_SUBTITLE
;
407 st
->codec
->codec_id
= ff_codec_get_id(ff_nut_subtitle_tags
, tmp
);
410 st
->codec
->codec_type
= AVMEDIA_TYPE_DATA
;
411 st
->codec
->codec_id
= ff_codec_get_id(ff_nut_data_tags
, tmp
);
414 av_log(s
, AV_LOG_ERROR
, "unknown stream class (%d)\n", class);
415 return AVERROR(ENOSYS
);
417 if (class < 3 && st
->codec
->codec_id
== AV_CODEC_ID_NONE
)
418 av_log(s
, AV_LOG_ERROR
,
419 "Unknown codec tag '0x%04x' for stream number %d\n",
420 (unsigned int) tmp
, stream_id
);
422 GET_V(stc
->time_base_id
, tmp
< nut
->time_base_count
);
423 GET_V(stc
->msb_pts_shift
, tmp
< 16);
424 stc
->max_pts_distance
= ffio_read_varlen(bc
);
425 GET_V(stc
->decode_delay
, tmp
< 1000); // sanity limit, raise this if Moore's law is true
426 st
->codec
->has_b_frames
= stc
->decode_delay
;
427 ffio_read_varlen(bc
); // stream flags
429 GET_V(st
->codec
->extradata_size
, tmp
< (1 << 30));
430 if (st
->codec
->extradata_size
) {
431 if (ff_get_extradata(st
->codec
, bc
, st
->codec
->extradata_size
) < 0)
432 return AVERROR(ENOMEM
);
435 if (st
->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
436 GET_V(st
->codec
->width
, tmp
> 0);
437 GET_V(st
->codec
->height
, tmp
> 0);
438 st
->sample_aspect_ratio
.num
= ffio_read_varlen(bc
);
439 st
->sample_aspect_ratio
.den
= ffio_read_varlen(bc
);
440 if ((!st
->sample_aspect_ratio
.num
) != (!st
->sample_aspect_ratio
.den
)) {
441 av_log(s
, AV_LOG_ERROR
, "invalid aspect ratio %d/%d\n",
442 st
->sample_aspect_ratio
.num
, st
->sample_aspect_ratio
.den
);
443 return AVERROR_INVALIDDATA
;
445 ffio_read_varlen(bc
); /* csp type */
446 } else if (st
->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
447 GET_V(st
->codec
->sample_rate
, tmp
> 0);
448 ffio_read_varlen(bc
); // samplerate_den
449 GET_V(st
->codec
->channels
, tmp
> 0);
451 if (skip_reserved(bc
, end
) || ffio_get_checksum(bc
)) {
452 av_log(s
, AV_LOG_ERROR
,
453 "stream header %d checksum mismatch\n", stream_id
);
454 return AVERROR_INVALIDDATA
;
456 stc
->time_base
= &nut
->time_base
[stc
->time_base_id
];
457 avpriv_set_pts_info(s
->streams
[stream_id
], 63, stc
->time_base
->num
,
458 stc
->time_base
->den
);
462 static void set_disposition_bits(AVFormatContext
*avf
, char *value
,
467 for (i
= 0; ff_nut_dispositions
[i
].flag
; ++i
)
468 if (!strcmp(ff_nut_dispositions
[i
].str
, value
))
469 flag
= ff_nut_dispositions
[i
].flag
;
471 av_log(avf
, AV_LOG_INFO
, "unknown disposition type '%s'\n", value
);
472 for (i
= 0; i
< avf
->nb_streams
; ++i
)
473 if (stream_id
== i
|| stream_id
== -1)
474 avf
->streams
[i
]->disposition
|= flag
;
477 static int decode_info_header(NUTContext
*nut
)
479 AVFormatContext
*s
= nut
->avf
;
480 AVIOContext
*bc
= s
->pb
;
481 uint64_t tmp
, chapter_start
, chapter_len
;
482 unsigned int stream_id_plus1
, count
;
485 char name
[256], str_value
[1024], type_str
[256];
487 int *event_flags
= NULL
;
488 AVChapter
*chapter
= NULL
;
490 AVDictionary
**metadata
= NULL
;
491 int metadata_flag
= 0;
493 end
= get_packetheader(nut
, bc
, 1, INFO_STARTCODE
);
494 end
+= avio_tell(bc
);
496 GET_V(stream_id_plus1
, tmp
<= s
->nb_streams
);
497 chapter_id
= get_s(bc
);
498 chapter_start
= ffio_read_varlen(bc
);
499 chapter_len
= ffio_read_varlen(bc
);
500 count
= ffio_read_varlen(bc
);
502 if (chapter_id
&& !stream_id_plus1
) {
503 int64_t start
= chapter_start
/ nut
->time_base_count
;
504 chapter
= avpriv_new_chapter(s
, chapter_id
,
505 nut
->time_base
[chapter_start
%
506 nut
->time_base_count
],
507 start
, start
+ chapter_len
, NULL
);
508 metadata
= &chapter
->metadata
;
509 } else if (stream_id_plus1
) {
510 st
= s
->streams
[stream_id_plus1
- 1];
511 metadata
= &st
->metadata
;
512 event_flags
= &st
->event_flags
;
513 metadata_flag
= AVSTREAM_EVENT_FLAG_METADATA_UPDATED
;
515 metadata
= &s
->metadata
;
516 event_flags
= &s
->event_flags
;
517 metadata_flag
= AVFMT_EVENT_FLAG_METADATA_UPDATED
;
520 for (i
= 0; i
< count
; i
++) {
521 get_str(bc
, name
, sizeof(name
));
525 get_str(bc
, str_value
, sizeof(str_value
));
526 } else if (value
== -2) {
527 get_str(bc
, type_str
, sizeof(type_str
));
529 get_str(bc
, str_value
, sizeof(str_value
));
530 } else if (value
== -3) {
533 } else if (value
== -4) {
535 value
= ffio_read_varlen(bc
);
536 } else if (value
< -4) {
543 if (stream_id_plus1
> s
->nb_streams
) {
544 av_log(s
, AV_LOG_ERROR
, "invalid stream id for info packet\n");
548 if (!strcmp(type
, "UTF-8")) {
549 if (chapter_id
== 0 && !strcmp(name
, "Disposition")) {
550 set_disposition_bits(s
, str_value
, stream_id_plus1
- 1);
554 if (stream_id_plus1
&& !strcmp(name
, "r_frame_rate")) {
555 sscanf(str_value
, "%d/%d", &st
->r_frame_rate
.num
, &st
->r_frame_rate
.den
);
556 if (st
->r_frame_rate
.num
>= 1000LL*st
->r_frame_rate
.den
)
557 st
->r_frame_rate
.num
= st
->r_frame_rate
.den
= 0;
561 if (metadata
&& av_strcasecmp(name
, "Uses") &&
562 av_strcasecmp(name
, "Depends") && av_strcasecmp(name
, "Replaces")) {
564 *event_flags
|= metadata_flag
;
565 av_dict_set(metadata
, name
, str_value
, 0);
570 if (skip_reserved(bc
, end
) || ffio_get_checksum(bc
)) {
571 av_log(s
, AV_LOG_ERROR
, "info header checksum mismatch\n");
572 return AVERROR_INVALIDDATA
;
577 static int decode_syncpoint(NUTContext
*nut
, int64_t *ts
, int64_t *back_ptr
)
579 AVFormatContext
*s
= nut
->avf
;
580 AVIOContext
*bc
= s
->pb
;
585 nut
->last_syncpoint_pos
= avio_tell(bc
) - 8;
587 end
= get_packetheader(nut
, bc
, 1, SYNCPOINT_STARTCODE
);
588 end
+= avio_tell(bc
);
590 tmp
= ffio_read_varlen(bc
);
591 *back_ptr
= nut
->last_syncpoint_pos
- 16 * ffio_read_varlen(bc
);
593 return AVERROR_INVALIDDATA
;
595 ff_nut_reset_ts(nut
, nut
->time_base
[tmp
% nut
->time_base_count
],
596 tmp
/ nut
->time_base_count
);
598 if (nut
->flags
& NUT_BROADCAST
) {
599 tmp
= ffio_read_varlen(bc
);
600 av_log(s
, AV_LOG_VERBOSE
, "Syncpoint wallclock %"PRId64
"\n",
601 av_rescale_q(tmp
/ nut
->time_base_count
,
602 nut
->time_base
[tmp
% nut
->time_base_count
],
606 if (skip_reserved(bc
, end
) || ffio_get_checksum(bc
)) {
607 av_log(s
, AV_LOG_ERROR
, "sync point checksum mismatch\n");
608 return AVERROR_INVALIDDATA
;
611 *ts
= tmp
/ nut
->time_base_count
*
612 av_q2d(nut
->time_base
[tmp
% nut
->time_base_count
]) * AV_TIME_BASE
;
614 if ((ret
= ff_nut_add_sp(nut
, nut
->last_syncpoint_pos
, *back_ptr
, *ts
)) < 0)
620 //FIXME calculate exactly, this is just a good approximation.
621 static int64_t find_duration(NUTContext
*nut
, int64_t filesize
)
623 AVFormatContext
*s
= nut
->avf
;
624 int64_t duration
= 0;
626 ff_find_last_ts(s
, -1, &duration
, NULL
, nut_read_timestamp
);
629 s
->duration_estimation_method
= AVFMT_DURATION_FROM_PTS
;
633 static int find_and_decode_index(NUTContext
*nut
)
635 AVFormatContext
*s
= nut
->avf
;
636 AVIOContext
*bc
= s
->pb
;
638 int i
, j
, syncpoint_count
;
639 int64_t filesize
= avio_size(bc
);
642 int8_t *has_keyframe
;
643 int ret
= AVERROR_INVALIDDATA
;
648 avio_seek(bc
, filesize
- 12, SEEK_SET
);
649 avio_seek(bc
, filesize
- avio_rb64(bc
), SEEK_SET
);
650 if (avio_rb64(bc
) != INDEX_STARTCODE
) {
651 av_log(s
, AV_LOG_ERROR
, "no index at the end\n");
654 s
->duration
= find_duration(nut
, filesize
);
658 end
= get_packetheader(nut
, bc
, 1, INDEX_STARTCODE
);
659 end
+= avio_tell(bc
);
661 max_pts
= ffio_read_varlen(bc
);
662 s
->duration
= av_rescale_q(max_pts
/ nut
->time_base_count
,
663 nut
->time_base
[max_pts
% nut
->time_base_count
],
665 s
->duration_estimation_method
= AVFMT_DURATION_FROM_PTS
;
667 GET_V(syncpoint_count
, tmp
< INT_MAX
/ 8 && tmp
> 0);
668 syncpoints
= av_malloc_array(syncpoint_count
, sizeof(int64_t));
669 has_keyframe
= av_malloc_array(syncpoint_count
+ 1, sizeof(int8_t));
670 if (!syncpoints
|| !has_keyframe
) {
671 ret
= AVERROR(ENOMEM
);
674 for (i
= 0; i
< syncpoint_count
; i
++) {
675 syncpoints
[i
] = ffio_read_varlen(bc
);
676 if (syncpoints
[i
] <= 0)
679 syncpoints
[i
] += syncpoints
[i
- 1];
682 for (i
= 0; i
< s
->nb_streams
; i
++) {
683 int64_t last_pts
= -1;
684 for (j
= 0; j
< syncpoint_count
;) {
685 uint64_t x
= ffio_read_varlen(bc
);
692 if (n
+ x
>= syncpoint_count
+ 1) {
693 av_log(s
, AV_LOG_ERROR
, "index overflow A %d + %"PRIu64
" >= %d\n", n
, x
, syncpoint_count
+ 1);
697 has_keyframe
[n
++] = flag
;
698 has_keyframe
[n
++] = !flag
;
701 if (n
>= syncpoint_count
+ 1) {
702 av_log(s
, AV_LOG_ERROR
, "index overflow B\n");
705 has_keyframe
[n
++] = x
& 1;
709 if (has_keyframe
[0]) {
710 av_log(s
, AV_LOG_ERROR
, "keyframe before first syncpoint in index\n");
713 av_assert0(n
<= syncpoint_count
+ 1);
714 for (; j
< n
&& j
< syncpoint_count
; j
++) {
715 if (has_keyframe
[j
]) {
716 uint64_t B
, A
= ffio_read_varlen(bc
);
718 A
= ffio_read_varlen(bc
);
719 B
= ffio_read_varlen(bc
);
720 // eor_pts[j][i] = last_pts + A + B
723 av_add_index_entry(s
->streams
[i
], 16 * syncpoints
[j
- 1],
724 last_pts
+ A
, 0, 0, AVINDEX_KEYFRAME
);
731 if (skip_reserved(bc
, end
) || ffio_get_checksum(bc
)) {
732 av_log(s
, AV_LOG_ERROR
, "index checksum mismatch\n");
739 av_free(has_keyframe
);
743 static int nut_read_header(AVFormatContext
*s
)
745 NUTContext
*nut
= s
->priv_data
;
746 AVIOContext
*bc
= s
->pb
;
748 int initialized_stream_count
;
755 pos
= find_startcode(bc
, MAIN_STARTCODE
, pos
) + 1;
757 av_log(s
, AV_LOG_ERROR
, "No main startcode found.\n");
758 return AVERROR_INVALIDDATA
;
760 } while (decode_main_header(nut
) < 0);
764 for (initialized_stream_count
= 0; initialized_stream_count
< s
->nb_streams
;) {
765 pos
= find_startcode(bc
, STREAM_STARTCODE
, pos
) + 1;
767 av_log(s
, AV_LOG_ERROR
, "Not all stream headers found.\n");
768 return AVERROR_INVALIDDATA
;
770 if (decode_stream_header(nut
) >= 0)
771 initialized_stream_count
++;
777 uint64_t startcode
= find_any_startcode(bc
, pos
);
780 if (startcode
== 0) {
781 av_log(s
, AV_LOG_ERROR
, "EOF before video frames\n");
782 return AVERROR_INVALIDDATA
;
783 } else if (startcode
== SYNCPOINT_STARTCODE
) {
784 nut
->next_startcode
= startcode
;
786 } else if (startcode
!= INFO_STARTCODE
) {
790 decode_info_header(nut
);
793 s
->data_offset
= pos
- 8;
796 int64_t orig_pos
= avio_tell(bc
);
797 find_and_decode_index(nut
);
798 avio_seek(bc
, orig_pos
, SEEK_SET
);
800 av_assert0(nut
->next_startcode
== SYNCPOINT_STARTCODE
);
802 ff_metadata_conv_ctx(s
, NULL
, ff_nut_metadata_conv
);
807 static int read_sm_data(AVFormatContext
*s
, AVIOContext
*bc
, AVPacket
*pkt
, int is_meta
, int64_t maxpos
)
809 int count
= ffio_read_varlen(bc
);
813 int64_t channel_layout
= 0;
819 for (i
=0; i
<count
; i
++) {
820 uint8_t name
[256], str_value
[256], type_str
[256];
822 if (avio_tell(bc
) >= maxpos
)
823 return AVERROR_INVALIDDATA
;
824 get_str(bc
, name
, sizeof(name
));
828 get_str(bc
, str_value
, sizeof(str_value
));
829 av_log(s
, AV_LOG_WARNING
, "Unknown string %s / %s\n", name
, str_value
);
830 } else if (value
== -2) {
832 int64_t v64
, value_len
;
834 get_str(bc
, type_str
, sizeof(type_str
));
835 value_len
= ffio_read_varlen(bc
);
836 if (avio_tell(bc
) + value_len
>= maxpos
)
837 return AVERROR_INVALIDDATA
;
838 if (!strcmp(name
, "Palette")) {
839 dst
= av_packet_new_side_data(pkt
, AV_PKT_DATA_PALETTE
, value_len
);
840 } else if (!strcmp(name
, "Extradata")) {
841 dst
= av_packet_new_side_data(pkt
, AV_PKT_DATA_NEW_EXTRADATA
, value_len
);
842 } else if (sscanf(name
, "CodecSpecificSide%"SCNd64
"", &v64
) == 1) {
843 dst
= av_packet_new_side_data(pkt
, AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL
, value_len
+ 8);
845 return AVERROR(ENOMEM
);
848 } else if (!strcmp(name
, "ChannelLayout") && value_len
== 8) {
849 channel_layout
= avio_rl64(bc
);
852 av_log(s
, AV_LOG_WARNING
, "Unknown data %s / %s\n", name
, type_str
);
853 avio_skip(bc
, value_len
);
857 return AVERROR(ENOMEM
);
858 avio_read(bc
, dst
, value_len
);
859 } else if (value
== -3) {
861 } else if (value
== -4) {
862 value
= ffio_read_varlen(bc
);
863 } else if (value
< -4) {
866 if (!strcmp(name
, "SkipStart")) {
868 } else if (!strcmp(name
, "SkipEnd")) {
870 } else if (!strcmp(name
, "Channels")) {
872 } else if (!strcmp(name
, "SampleRate")) {
874 } else if (!strcmp(name
, "Width")) {
876 } else if (!strcmp(name
, "Height")) {
879 av_log(s
, AV_LOG_WARNING
, "Unknown integer %s\n", name
);
884 if (channels
|| channel_layout
|| sample_rate
|| width
|| height
) {
885 uint8_t *dst
= av_packet_new_side_data(pkt
, AV_PKT_DATA_PARAM_CHANGE
, 28);
887 return AVERROR(ENOMEM
);
888 bytestream_put_le32(&dst
,
889 AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT
*(!!channels
) +
890 AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT
*(!!channel_layout
) +
891 AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE
*(!!sample_rate
) +
892 AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS
*(!!(width
|height
))
895 bytestream_put_le32(&dst
, channels
);
897 bytestream_put_le64(&dst
, channel_layout
);
899 bytestream_put_le32(&dst
, sample_rate
);
900 if (width
|| height
){
901 bytestream_put_le32(&dst
, width
);
902 bytestream_put_le32(&dst
, height
);
906 if (skip_start
|| skip_end
) {
907 uint8_t *dst
= av_packet_new_side_data(pkt
, AV_PKT_DATA_SKIP_SAMPLES
, 10);
909 return AVERROR(ENOMEM
);
910 AV_WL32(dst
, skip_start
);
911 AV_WL32(dst
+4, skip_end
);
917 static int decode_frame_header(NUTContext
*nut
, int64_t *pts
, int *stream_id
,
918 uint8_t *header_idx
, int frame_code
)
920 AVFormatContext
*s
= nut
->avf
;
921 AVIOContext
*bc
= s
->pb
;
923 int size
, flags
, size_mul
, pts_delta
, i
, reserved_count
;
926 if (!(nut
->flags
& NUT_PIPE
) &&
927 avio_tell(bc
) > nut
->last_syncpoint_pos
+ nut
->max_distance
) {
928 av_log(s
, AV_LOG_ERROR
,
929 "Last frame must have been damaged %"PRId64
" > %"PRId64
" + %d\n",
930 avio_tell(bc
), nut
->last_syncpoint_pos
, nut
->max_distance
);
931 return AVERROR_INVALIDDATA
;
934 flags
= nut
->frame_code
[frame_code
].flags
;
935 size_mul
= nut
->frame_code
[frame_code
].size_mul
;
936 size
= nut
->frame_code
[frame_code
].size_lsb
;
937 *stream_id
= nut
->frame_code
[frame_code
].stream_id
;
938 pts_delta
= nut
->frame_code
[frame_code
].pts_delta
;
939 reserved_count
= nut
->frame_code
[frame_code
].reserved_count
;
940 *header_idx
= nut
->frame_code
[frame_code
].header_idx
;
942 if (flags
& FLAG_INVALID
)
943 return AVERROR_INVALIDDATA
;
944 if (flags
& FLAG_CODED
)
945 flags
^= ffio_read_varlen(bc
);
946 if (flags
& FLAG_STREAM_ID
) {
947 GET_V(*stream_id
, tmp
< s
->nb_streams
);
949 stc
= &nut
->stream
[*stream_id
];
950 if (flags
& FLAG_CODED_PTS
) {
951 int coded_pts
= ffio_read_varlen(bc
);
952 // FIXME check last_pts validity?
953 if (coded_pts
< (1 << stc
->msb_pts_shift
)) {
954 *pts
= ff_lsb2full(stc
, coded_pts
);
956 *pts
= coded_pts
- (1LL << stc
->msb_pts_shift
);
958 *pts
= stc
->last_pts
+ pts_delta
;
959 if (flags
& FLAG_SIZE_MSB
)
960 size
+= size_mul
* ffio_read_varlen(bc
);
961 if (flags
& FLAG_MATCH_TIME
)
963 if (flags
& FLAG_HEADER_IDX
)
964 *header_idx
= ffio_read_varlen(bc
);
965 if (flags
& FLAG_RESERVED
)
966 reserved_count
= ffio_read_varlen(bc
);
967 for (i
= 0; i
< reserved_count
; i
++)
968 ffio_read_varlen(bc
);
970 if (*header_idx
>= (unsigned)nut
->header_count
) {
971 av_log(s
, AV_LOG_ERROR
, "header_idx invalid\n");
972 return AVERROR_INVALIDDATA
;
976 size
-= nut
->header_len
[*header_idx
];
978 if (flags
& FLAG_CHECKSUM
) {
979 avio_rb32(bc
); // FIXME check this
980 } else if (!(nut
->flags
& NUT_PIPE
) &&
981 size
> 2 * nut
->max_distance
||
982 FFABS(stc
->last_pts
- *pts
) > stc
->max_pts_distance
) {
983 av_log(s
, AV_LOG_ERROR
, "frame size > 2max_distance and no checksum\n");
984 return AVERROR_INVALIDDATA
;
987 stc
->last_pts
= *pts
;
988 stc
->last_flags
= flags
;
993 static int decode_frame(NUTContext
*nut
, AVPacket
*pkt
, int frame_code
)
995 AVFormatContext
*s
= nut
->avf
;
996 AVIOContext
*bc
= s
->pb
;
997 int size
, stream_id
, discard
;
998 int64_t pts
, last_IP_pts
;
1003 size
= decode_frame_header(nut
, &pts
, &stream_id
, &header_idx
, frame_code
);
1007 stc
= &nut
->stream
[stream_id
];
1009 if (stc
->last_flags
& FLAG_KEY
)
1010 stc
->skip_until_key_frame
= 0;
1012 discard
= s
->streams
[stream_id
]->discard
;
1013 last_IP_pts
= s
->streams
[stream_id
]->last_IP_pts
;
1014 if ((discard
>= AVDISCARD_NONKEY
&& !(stc
->last_flags
& FLAG_KEY
)) ||
1015 (discard
>= AVDISCARD_BIDIR
&& last_IP_pts
!= AV_NOPTS_VALUE
&&
1016 last_IP_pts
> pts
) ||
1017 discard
>= AVDISCARD_ALL
||
1018 stc
->skip_until_key_frame
) {
1019 avio_skip(bc
, size
);
1023 if (av_new_packet(pkt
, size
+ nut
->header_len
[header_idx
]) < 0)
1024 return AVERROR(ENOMEM
);
1025 memcpy(pkt
->data
, nut
->header
[header_idx
], nut
->header_len
[header_idx
]);
1026 pkt
->pos
= avio_tell(bc
); // FIXME
1027 if (stc
->last_flags
& FLAG_SM_DATA
) {
1029 if (read_sm_data(s
, bc
, pkt
, 0, pkt
->pos
+ size
) < 0)
1030 return AVERROR_INVALIDDATA
;
1031 if (read_sm_data(s
, bc
, pkt
, 1, pkt
->pos
+ size
) < 0)
1032 return AVERROR_INVALIDDATA
;
1033 sm_size
= avio_tell(bc
) - pkt
->pos
;
1035 pkt
->size
-= sm_size
;
1038 ret
= avio_read(bc
, pkt
->data
+ nut
->header_len
[header_idx
], size
);
1043 av_shrink_packet(pkt
, nut
->header_len
[header_idx
] + ret
);
1045 pkt
->stream_index
= stream_id
;
1046 if (stc
->last_flags
& FLAG_KEY
)
1047 pkt
->flags
|= AV_PKT_FLAG_KEY
;
1053 static int nut_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
1055 NUTContext
*nut
= s
->priv_data
;
1056 AVIOContext
*bc
= s
->pb
;
1057 int i
, frame_code
= 0, ret
, skip
;
1058 int64_t ts
, back_ptr
;
1061 int64_t pos
= avio_tell(bc
);
1062 uint64_t tmp
= nut
->next_startcode
;
1063 nut
->next_startcode
= 0;
1068 frame_code
= avio_r8(bc
);
1071 if (frame_code
== 'N') {
1073 for (i
= 1; i
< 8; i
++)
1074 tmp
= (tmp
<< 8) + avio_r8(bc
);
1078 case MAIN_STARTCODE
:
1079 case STREAM_STARTCODE
:
1080 case INDEX_STARTCODE
:
1081 skip
= get_packetheader(nut
, bc
, 0, tmp
);
1082 avio_skip(bc
, skip
);
1084 case INFO_STARTCODE
:
1085 if (decode_info_header(nut
) < 0)
1088 case SYNCPOINT_STARTCODE
:
1089 if (decode_syncpoint(nut
, &ts
, &back_ptr
) < 0)
1091 frame_code
= avio_r8(bc
);
1093 ret
= decode_frame(nut
, pkt
, frame_code
);
1096 else if (ret
== 1) // OK but discard packet
1100 av_log(s
, AV_LOG_DEBUG
, "syncing from %"PRId64
"\n", pos
);
1101 tmp
= find_any_startcode(bc
, nut
->last_syncpoint_pos
+ 1);
1103 return AVERROR_INVALIDDATA
;
1104 av_log(s
, AV_LOG_DEBUG
, "sync\n");
1105 nut
->next_startcode
= tmp
;
1110 static int64_t nut_read_timestamp(AVFormatContext
*s
, int stream_index
,
1111 int64_t *pos_arg
, int64_t pos_limit
)
1113 NUTContext
*nut
= s
->priv_data
;
1114 AVIOContext
*bc
= s
->pb
;
1115 int64_t pos
, pts
, back_ptr
;
1116 av_log(s
, AV_LOG_DEBUG
, "read_timestamp(X,%d,%"PRId64
",%"PRId64
")\n",
1117 stream_index
, *pos_arg
, pos_limit
);
1121 pos
= find_startcode(bc
, SYNCPOINT_STARTCODE
, pos
) + 1;
1123 av_log(s
, AV_LOG_ERROR
, "read_timestamp failed.\n");
1124 return AV_NOPTS_VALUE
;
1126 } while (decode_syncpoint(nut
, &pts
, &back_ptr
) < 0);
1128 av_assert0(nut
->last_syncpoint_pos
== *pos_arg
);
1130 av_log(s
, AV_LOG_DEBUG
, "return %"PRId64
" %"PRId64
"\n", pts
, back_ptr
);
1131 if (stream_index
== -2)
1133 av_assert0(stream_index
== -1);
1137 static int read_seek(AVFormatContext
*s
, int stream_index
,
1138 int64_t pts
, int flags
)
1140 NUTContext
*nut
= s
->priv_data
;
1141 AVStream
*st
= s
->streams
[stream_index
];
1142 Syncpoint dummy
= { .ts
= pts
* av_q2d(st
->time_base
) * AV_TIME_BASE
};
1143 Syncpoint nopts_sp
= { .ts
= AV_NOPTS_VALUE
, .back_ptr
= AV_NOPTS_VALUE
};
1144 Syncpoint
*sp
, *next_node
[2] = { &nopts_sp
, &nopts_sp
};
1145 int64_t pos
, pos2
, ts
;
1148 if (nut
->flags
& NUT_PIPE
) {
1149 return AVERROR(ENOSYS
);
1152 if (st
->index_entries
) {
1153 int index
= av_index_search_timestamp(st
, pts
, flags
);
1155 index
= av_index_search_timestamp(st
, pts
, flags
^ AVSEEK_FLAG_BACKWARD
);
1159 pos2
= st
->index_entries
[index
].pos
;
1160 ts
= st
->index_entries
[index
].timestamp
;
1162 av_tree_find(nut
->syncpoints
, &dummy
, (void *) ff_nut_sp_pts_cmp
,
1163 (void **) next_node
);
1164 av_log(s
, AV_LOG_DEBUG
, "%"PRIu64
"-%"PRIu64
" %"PRId64
"-%"PRId64
"\n",
1165 next_node
[0]->pos
, next_node
[1]->pos
, next_node
[0]->ts
,
1167 pos
= ff_gen_search(s
, -1, dummy
.ts
, next_node
[0]->pos
,
1168 next_node
[1]->pos
, next_node
[1]->pos
,
1169 next_node
[0]->ts
, next_node
[1]->ts
,
1170 AVSEEK_FLAG_BACKWARD
, &ts
, nut_read_timestamp
);
1172 if (!(flags
& AVSEEK_FLAG_BACKWARD
)) {
1173 dummy
.pos
= pos
+ 16;
1174 next_node
[1] = &nopts_sp
;
1175 av_tree_find(nut
->syncpoints
, &dummy
, (void *) ff_nut_sp_pos_cmp
,
1176 (void **) next_node
);
1177 pos2
= ff_gen_search(s
, -2, dummy
.pos
, next_node
[0]->pos
,
1178 next_node
[1]->pos
, next_node
[1]->pos
,
1179 next_node
[0]->back_ptr
, next_node
[1]->back_ptr
,
1180 flags
, &ts
, nut_read_timestamp
);
1183 // FIXME dir but I think it does not matter
1186 sp
= av_tree_find(nut
->syncpoints
, &dummy
, (void *) ff_nut_sp_pos_cmp
,
1190 pos2
= sp
->back_ptr
- 15;
1192 av_log(NULL
, AV_LOG_DEBUG
, "SEEKTO: %"PRId64
"\n", pos2
);
1193 pos
= find_startcode(s
->pb
, SYNCPOINT_STARTCODE
, pos2
);
1194 avio_seek(s
->pb
, pos
, SEEK_SET
);
1195 av_log(NULL
, AV_LOG_DEBUG
, "SP: %"PRId64
"\n", pos
);
1196 if (pos2
> pos
|| pos2
+ 15 < pos
)
1197 av_log(NULL
, AV_LOG_ERROR
, "no syncpoint at backptr pos\n");
1198 for (i
= 0; i
< s
->nb_streams
; i
++)
1199 nut
->stream
[i
].skip_until_key_frame
= 1;
1204 static int nut_read_close(AVFormatContext
*s
)
1206 NUTContext
*nut
= s
->priv_data
;
1209 av_freep(&nut
->time_base
);
1210 av_freep(&nut
->stream
);
1211 ff_nut_free_sp(nut
);
1212 for (i
= 1; i
< nut
->header_count
; i
++)
1213 av_freep(&nut
->header
[i
]);
1218 AVInputFormat ff_nut_demuxer
= {
1220 .long_name
= NULL_IF_CONFIG_SMALL("NUT"),
1221 .flags
= AVFMT_SEEK_TO_PTS
,
1222 .priv_data_size
= sizeof(NUTContext
),
1223 .read_probe
= nut_probe
,
1224 .read_header
= nut_read_header
,
1225 .read_packet
= nut_read_packet
,
1226 .read_close
= nut_read_close
,
1227 .read_seek
= read_seek
,
1228 .extensions
= "nut",
1229 .codec_tag
= ff_nut_codec_tags
,