1 /*
2 * "NUT" Container Format demuxer
3 * Copyright (c) 2004-2006 Michael Niedermayer
4 * Copyright (c) 2003 Alex Beregszaszi
5 *
6 * This file is part of FFmpeg.
7 *
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.
12 *
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.
17 *
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
21 */
22
34
35 #define NUT_MAX_STREAMS 256 /* arbitrary sanity check value */
36
38 int64_t *pos_arg, int64_t pos_limit);
39
41 {
43
44 if (len && maxlen)
46 while (len > maxlen) {
48 len--;
49 }
50
51 if (maxlen)
52 string[
FFMIN(len, maxlen - 1)] = 0;
53
54 if (maxlen == len)
55 return -1;
56 else
57 return 0;
58 }
59
61 {
63
64 if (v & 1)
65 return -(v >> 1);
66 else
67 return (v >> 1);
68 }
69
71 {
73
74 if (len == 2)
76 else if (len == 4)
78 else {
80 return -1;
81 }
82 }
83
84 #ifdef TRACE
85 static inline uint64_t get_v_trace(
AVIOContext *bc,
const char *file,
87 {
89
91 v, v, file, func, line);
93 }
94
95 static inline int64_t get_s_trace(
AVIOContext *bc,
const char *file,
97 {
99
101 v, v, file, func, line);
103 }
104
105 static inline uint64_t get_4cc_trace(
AVIOContext *bc,
char *file,
107 {
109
111 v, v, file, func, line);
113 }
114 #define ffio_read_varlen(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
115 #define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
116 #define get_fourcc(bc) get_4cc_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
117 #endif
118
120 int calculate_checksum, uint64_t startcode)
121 {
123 // start = avio_tell(bc) - 8;
124
127
130 if (size > 4096)
133 return -1;
134
136
138 }
139
141 {
143
144 if (pos >= 0)
145 /* Note, this may fail if the stream is not seekable, but that should
146 * not matter, as in this case we simply start where we currently are */
149 state = (state << 8) |
avio_r8(bc);
150 if ((state >> 56) != 'N')
151 continue;
152 switch (state) {
159 }
160 }
161
162 return 0;
163 }
164
165 /**
166 * Find the given startcode.
167 * @param code the startcode
168 * @param pos the start position of the search, or -1 if the current position
169 * @return the position of the startcode or -1 if not found
170 */
172 {
173 for (;;) {
175 if (startcode == code)
177 else if (startcode == 0)
178 return -1;
179 pos = -1;
180 }
181 }
182
184 {
185 int i;
186 uint64_t code = 0;
187
189 code = (code << 8) | p->
buf[i];
192 }
193 return 0;
194 }
195
196 #define GET_V(dst, check) \
197 do { \
198 tmp = ffio_read_varlen(bc); \
199 if (!(check)) { \
200 av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \
201 return AVERROR_INVALIDDATA; \
202 } \
203 dst = tmp; \
204 } while (0)
205
207 {
209 if (pos < 0) {
212 } else {
213 while (pos--)
215 return 0;
216 }
217 }
218
220 {
224 unsigned int stream_count;
226 int tmp_stream, tmp_mul, tmp_pts, tmp_size, tmp_res, tmp_head_idx;
227
230
232 if (tmp < 2 && tmp > 4) {
234 tmp);
236 }
240
242
247 }
248
253
260 }
261 }
262 tmp_pts = 0;
263 tmp_mul = 1;
264 tmp_stream = 0;
265 tmp_head_idx = 0;
266 for (i = 0; i < 256;) {
269
270 if (tmp_fields > 0)
272 if (tmp_fields > 1)
274 if (tmp_fields > 2)
276 if (tmp_fields > 3)
278 else
279 tmp_size = 0;
280 if (tmp_fields > 4)
282 else
283 tmp_res = 0;
284 if (tmp_fields > 5)
286 else
287 count = tmp_mul - tmp_size;
288 if (tmp_fields > 6)
290 if (tmp_fields > 7)
292
293 while (tmp_fields-- > 8)
295
296 if (count == 0 || i + count > 256) {
299 }
300 if (tmp_stream >= stream_count) {
303 }
304
305 for (j = 0; j <
count; j++, i++) {
306 if (i == 'N') {
308 j--;
309 continue;
310 }
318 }
319 }
321
323 int rem = 1024;
330 if (rem < 0) {
333 }
335 if (!hdr)
339 }
341 }
342
346 }
347
351 for (i = 0; i < stream_count; i++)
353
354 return 0;
355 }
356
358 {
362 int class, stream_id;
365
368
370 stc = &nut->
stream[stream_id];
372 if (!st)
374
375 class = ffio_read_varlen(bc);
378 switch (class) {
379 case 0:
384 0
385 },
386 tmp);
387 break;
388 case 1:
393 0
394 },
395 tmp);
396 break;
397 case 2:
400 break;
401 case 3:
404 break;
405 default:
408 }
411 "Unknown codec tag '0x%04x' for stream number %d\n",
412 (unsigned int) tmp, stream_id);
413
417 GET_V(stc->
decode_delay, tmp < 1000);
// sanity limit, raise this if Moore's law is true
420
425 }
426
436 }
442 }
445 "stream header %d checksum mismatch\n", stream_id);
447 }
451 return 0;
452 }
453
455 int stream_id)
456 {
457 int flag = 0, i;
458
462 if (!flag)
465 if (stream_id == i || stream_id == -1)
467 }
468
470 {
473 uint64_t tmp, chapter_start, chapter_len;
474 unsigned int stream_id_plus1,
count;
475 int chapter_id, i;
477 char name[256], str_value[1024], type_str[256];
482
485
486 GET_V(stream_id_plus1, tmp <= s->nb_streams);
487 chapter_id =
get_s(bc);
491
492 if (chapter_id && !stream_id_plus1) {
497 start, start + chapter_len, NULL);
499 } else if (stream_id_plus1) {
500 st = s->
streams[stream_id_plus1 - 1];
502 } else
504
505 for (i = 0; i <
count; i++) {
506 get_str(bc, name,
sizeof(name));
508 if (value == -1) {
509 type = "UTF-8";
510 get_str(bc, str_value,
sizeof(str_value));
511 } else if (value == -2) {
512 get_str(bc, type_str,
sizeof(type_str));
513 type = type_str;
514 get_str(bc, str_value,
sizeof(str_value));
515 } else if (value == -3) {
516 type = "s";
518 } else if (value == -4) {
519 type = "t";
521 } else if (value < -4) {
522 type = "r";
524 } else {
525 type = "v";
526 }
527
530 continue;
531 }
532
533 if (!strcmp(type, "UTF-8")) {
534 if (chapter_id == 0 && !strcmp(name, "Disposition")) {
536 continue;
537 }
538
539 if (stream_id_plus1 && !strcmp(name, "r_frame_rate")) {
543 continue;
544 }
545
549 }
550 }
551
555 }
556 return 0;
557 }
558
560 {
564 uint64_t tmp;
566
568
571
574 if (*back_ptr < 0)
576
579
583 }
584
587
590
591 return 0;
592 }
593
594 //FIXME calculate exactly, this is just a good approximation.
596 {
599
601
602 if(duration > 0)
605 }
606
608 {
612 int i, j, syncpoint_count;
614 int64_t *syncpoints;
615 uint64_t max_pts;
616 int8_t *has_keyframe;
618
619 if(filesize <= 0)
620 return -1;
621
626
630 }
631
634
640
641 GET_V(syncpoint_count, tmp < INT_MAX / 8 && tmp > 0);
642 syncpoints = av_malloc_array(syncpoint_count, sizeof(int64_t));
643 has_keyframe = av_malloc_array(syncpoint_count + 1, sizeof(int8_t));
644 if (!syncpoints || !has_keyframe) {
646 goto fail;
647 }
648 for (i = 0; i < syncpoint_count; i++) {
650 if (syncpoints[i] <= 0)
651 goto fail;
652 if (i)
653 syncpoints[i] += syncpoints[i - 1];
654 }
655
658 for (j = 0; j < syncpoint_count;) {
662 x >>= 1;
663 if (type) {
664 int flag = x & 1;
665 x >>= 1;
666 if (n + x >= syncpoint_count + 1) {
667 av_log(s,
AV_LOG_ERROR,
"index overflow A %d + %"PRIu64
" >= %d\n", n, x, syncpoint_count + 1);
668 goto fail;
669 }
670 while (x--)
671 has_keyframe[n++] = flag;
672 has_keyframe[n++] = !flag;
673 } else {
674 while (x != 1) {
675 if (n >= syncpoint_count + 1) {
677 goto fail;
678 }
679 has_keyframe[n++] = x & 1;
680 x >>= 1;
681 }
682 }
683 if (has_keyframe[0]) {
685 goto fail;
686 }
688 for (; j < n && j < syncpoint_count; j++) {
689 if (has_keyframe[j]) {
691 if (!A) {
694 // eor_pts[j][i] = last_pts + A + B
695 } else
696 B = 0;
700 }
701 }
702 }
703 }
704
707 goto fail;
708 }
709 ret = 0;
710
711 fail:
715 }
716
718 {
721 int64_t pos;
722 int initialized_stream_count;
723
725
726 /* main header */
727 pos = 0;
728 do {
730 if (pos < 0 + 1) {
733 }
735
736 /* stream headers */
737 pos = 0;
738 for (initialized_stream_count = 0; initialized_stream_count < s->
nb_streams;) {
740 if (pos < 0 + 1) {
743 }
745 initialized_stream_count++;
746 }
747
748 /* info headers */
749 pos = 0;
750 for (;;) {
753
754 if (startcode == 0) {
759 break;
761 continue;
762 }
763
765 }
766
768
773 }
775
777
778 return 0;
779 }
780
782 {
784 int skip_start = 0;
785 int skip_end = 0;
786 int channels = 0;
787 int64_t channel_layout = 0;
791 int i;
792
793 for (i=0; i<
count; i++) {
798 get_str(bc, name,
sizeof(name));
800
801 if (value == -1) {
802 get_str(bc, str_value,
sizeof(str_value));
804 } else if (value == -2) {
806 int64_t v64, value_len;
807
808 get_str(bc, type_str,
sizeof(type_str));
812 if (!strcmp(name, "Palette")) {
814 } else if (!strcmp(name, "Extradata")) {
816 } else if (sscanf(name, "CodecSpecificSide%"SCNd64"", &v64) == 1) {
818 if(!dst)
821 dst += 8;
822 } else if (!strcmp(name, "ChannelLayout") && value_len == 8) {
824 continue;
825 } else {
828 continue;
829 }
830 if(!dst)
833 } else if (value == -3) {
835 } else if (value == -4) {
837 } else if (value < -4) {
839 } else {
840 if (!strcmp(name, "SkipStart")) {
842 } else if (!strcmp(name, "SkipEnd")) {
844 } else if (!strcmp(name, "Channels")) {
846 } else if (!strcmp(name, "SampleRate")) {
848 } else if (!strcmp(name, "Width")) {
850 } else if (!strcmp(name, "Height")) {
852 } else {
854 }
855 }
856 }
857
858 if (channels || channel_layout || sample_rate || width || height) {
860 if (!dst)
862 bytestream_put_le32(&dst,
867 );
868 if (channels)
869 bytestream_put_le32(&dst, channels);
870 if (channel_layout)
871 bytestream_put_le64(&dst, channel_layout);
872 if (sample_rate)
873 bytestream_put_le32(&dst, sample_rate);
874 if (width || height){
875 bytestream_put_le32(&dst, width);
876 bytestream_put_le32(&dst, height);
877 }
878 }
879
880 if (skip_start || skip_end) {
882 if (!dst)
886 }
887
888 return 0;
889 }
890
892 uint8_t *header_idx,
int frame_code)
893 {
897 int size,
flags, size_mul, pts_delta, i, reserved_count;
898 uint64_t tmp;
899
902 "Last frame must have been damaged %"PRId64" > %"PRId64" + %d\n",
905 }
906
914
920 GET_V(*stream_id, tmp < s->nb_streams);
921 }
922 stc = &nut->
stream[*stream_id];
925 // FIXME check last_pts validity?
928 } else
930 } else
940 for (i = 0; i < reserved_count; i++)
942
946 }
947 if (size > 4096)
948 *header_idx = 0;
950
957 }
958
961
963 }
964
966 {
969 int size, stream_id, discard;
970 int64_t pts, last_IP_pts;
974
976 if (size < 0)
978
979 stc = &nut->
stream[stream_id];
980
983
988 last_IP_pts > pts) ||
992 return 1;
993 }
994
1000 int sm_size;
1006 size -= sm_size;
1007 pkt->
size -= sm_size;
1008 }
1009
1011 if (ret != size) {
1012 if (ret < 0)
1014 }
1016
1021
1022 return 0;
1023 }
1024
1026 {
1029 int i, frame_code = 0,
ret, skip;
1030 int64_t ts, back_ptr;
1031
1032 for (;;) {
1036
1037 if (tmp) {
1038 pos -= 8;
1039 } else {
1043 if (frame_code == 'N') {
1044 tmp = frame_code;
1045 for (i = 1; i < 8; i++)
1046 tmp = (tmp << 8) +
avio_r8(bc);
1047 }
1048 }
1049 switch (tmp) {
1055 break;
1059 break;
1064 case 0:
1067 return 0;
1068 else if (
ret == 1)
// OK but discard packet
1069 break;
1070 default:
1074 if (tmp == 0)
1078 }
1079 }
1080 }
1081
1083 int64_t *pos_arg, int64_t pos_limit)
1084 {
1087 int64_t pos, pts, back_ptr;
1089 stream_index, *pos_arg, pos_limit);
1090
1091 pos = *pos_arg;
1092 do {
1094 if (pos < 1) {
1097 }
1099 *pos_arg = pos - 1;
1101
1103 if (stream_index == -2)
1104 return back_ptr;
1106 return pts;
1107 }
1108
1110 int64_t pts,
int flags)
1111 {
1116 Syncpoint *
sp, *next_node[2] = { &nopts_sp, &nopts_sp };
1117 int64_t pos, pos2, ts;
1118 int i;
1119
1122 if (index < 0)
1124 if (index < 0)
1125 return -1;
1126
1129 } else {
1131 (void **) next_node);
1133 next_node[0]->pos, next_node[1]->pos, next_node[0]->ts,
1134 next_node[1]->ts);
1136 next_node[1]->
pos, next_node[1]->
pos,
1137 next_node[0]->
ts, next_node[1]->
ts,
1139
1141 dummy.
pos = pos + 16;
1142 next_node[1] = &nopts_sp;
1144 (void **) next_node);
1146 next_node[1]->
pos, next_node[1]->
pos,
1149 if (pos2 >= 0)
1150 pos = pos2;
1151 // FIXME dir but I think it does not matter
1152 }
1155 NULL);
1156
1159 }
1164 if (pos2 > pos || pos2 + 15 < pos)
1168
1169 return 0;
1170 }
1171
1173 {
1175 int i;
1176
1182
1183 return 0;
1184 }
1185
1196 .extensions = "nut",
1198 };