1 /*
2 * AVI demuxer
3 * Copyright (c) 2001 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
34
36 int64_t
frame_offset;
/* current frame (video) or byte (audio) counter
37 (used to compute the pts) */
40
43 int sample_size;
/* size of one sample (or packet) (in the rate/scale sense) in bytes */
44
45 int64_t
cum_len;
/* temporary storage (used during seek) */
46
47 int prefix;
///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
51 int dshow_block_align;
///< block align variable used to emulate bugs in the MS dshow demuxer
52
56
59
75 #define MAX_ODML_DEPTH 1000
78
79
82 { NULL },
83 };
84
91 };
92
93
95 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
96 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
97 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19},
98 { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' },
99 { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
100 { 0 }
101 };
102
104 { "strn", "title" },
105 { 0 },
106 };
107
110
111 #define print_tag(str, tag, size) \
112 av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \
113 str, tag & 0xff, \
114 (tag >> 8) & 0xff, \
115 (tag >> 16) & 0xff, \
116 (tag >> 24) & 0xff, \
117 size)
118
124 }else
125 return 1;
126 }
127
129 {
131 char header[8];
132 int i;
133
134 /* check RIFF header */
139
142 break;
145
146 if(header[7] == 0x19)
147 av_log(s,
AV_LOG_INFO,
"This file has been generated by a totally broken muxer.\n");
148
149 return 0;
150 }
151
156 int index_sub_type =
avio_r8(pb);
161 int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
164 int i;
165 int64_t last_pos= -1;
166 int64_t filesize= avi->
fsize;
167
168 av_dlog(s,
"longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64
"\n",
169 longs_pre_entry,index_type, entries_in_use, chunk_id, base);
170
171 if(stream_id >= s->
nb_streams || stream_id < 0)
175
176 if(index_sub_type)
178
180
181 if(index_type && longs_pre_entry != 2)
183 if(index_type>1)
185
186 if(filesize > 0 && base >= filesize){
188 if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
189 base &= 0xFFFFFFFF;
190 else
192 }
193
194 for(i=0; i<entries_in_use; i++){
195 if(index_type){
198 int key= len >= 0;
199 len &= 0x7FFFFFFF;
200
201 #ifdef DEBUG_SEEK
203 #endif
206
207 if(last_pos == pos || pos == base - 8)
211
213 last_pos= pos;
214 }else{
220
223
225
229 }
230
231 if(
avio_seek(pb, offset+8, SEEK_SET) < 0)
232 return -1;
237
240 return -1;
241 }
242
243 }
244 }
246 return 0;
247 }
248
250 int i;
251 int64_t j;
252
258 int64_t pos,
size, ts;
259
261 continue;
262
263 while(max < 1024) max+=max;
264
268
269 for(j=0; j<
size; j+=max){
271 }
272 }
273 }
274
276 {
278 char key[5] = {0}, *
value;
279
280 size += (size & 1);
281
282 if (size == UINT_MAX)
289
291
294 }
295
296 static const char months[12][4] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
297 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
298
300 {
301 char month[4], time[9],
buffer[64];
302 int i, day, year;
303 /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
304 if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
305 month, &day, time, &year) == 4) {
306 for (i=0; i<12; i++)
308 snprintf(buffer,
sizeof(buffer),
"%.4d-%.2d-%.2d %s",
309 year, i+1, day, time);
311 }
312 } else if (date[4] == '/' && date[7] == '/') {
313 date[4] = date[7] = '-';
315 }
316 }
317
319 {
323 switch (tag) {
324 case MKTAG(
'n',
'c',
't',
'g'): {
/* Nikon Tags */
329 const char *
name = NULL;
332 FFMIN(size,
sizeof(buffer)-1));
333 switch (tag) {
334 case 0x03: name = "maker"; break;
335 case 0x04: name = "model"; break;
336 case 0x13: name = "creation_time";
337 if (buffer[4] == ':' && buffer[7] == ':')
338 buffer[4] = buffer[7] = '-';
339 break;
340 }
341 if (name)
344 }
345 break;
346 }
347 default:
349 break;
350 }
351 }
352 }
353
355 {
358 unsigned int tag, tag1, handler;
361 int i;
364 int avih_width=0, avih_height=0;
365 int amv_file_format=0;
366 uint64_t list_end = 0;
369
371
373 if (ret < 0)
375
377
381
382 /* first list tag */
383 stream_index = -1;
384 codec_type = -1;
385 frame_period = 0;
386 for(;;) {
388 goto fail;
391
393
394 switch(tag) {
395 case MKTAG(
'L',
'I',
'S',
'T'):
397 /* Ignored, except at start of video packets. */
399
401
402 if (tag1 ==
MKTAG(
'm',
'o',
'v',
'i')) {
407 goto end_of_header;
408 }
409 else if (tag1 ==
MKTAG(
'I',
'N',
'F',
'O'))
411 else if (tag1 ==
MKTAG(
'n',
'c',
'd',
't'))
413
414 break;
415 case MKTAG(
'I',
'D',
'I',
'T'): {
416 unsigned char date[64] = {0};
417 size += (size & 1);
421 break;
422 }
423 case MKTAG(
'd',
'm',
'l',
'h'):
426 break;
427 case MKTAG(
'a',
'm',
'v',
'h'):
428 amv_file_format=1;
429 case MKTAG(
'a',
'v',
'i',
'h'):
430 /* AVI header */
431 /* using frame_period is bad idea */
433 avio_rl32(pb);
/* max. bytes per second */
436
442
444 break;
445 case MKTAG(
's',
't',
'r',
'h'):
446 /* stream header */
447
450
451 if(tag1 ==
MKTAG(
'p',
'a',
'd',
's')){
453 break;
454 }else{
455 stream_index++;
457 if (!st)
458 goto fail;
459
460 st->
id = stream_index;
462 if (!ast)
463 goto fail;
465 }
466 if(amv_file_format)
467 tag1 = stream_index ?
MKTAG(
'a',
'u',
'd',
's') :
MKTAG(
'v',
'i',
'd',
's');
468
470
471 if(tag1 ==
MKTAG(
'i',
'a',
'v',
's') || tag1 ==
MKTAG(
'i',
'v',
'a',
's')){
472 int64_t dv_dur;
473
474 /*
475 * After some consideration -- I don't think we
476 * have to support anything but DV in type1 AVIs.
477 */
479 goto fail;
480
481 if (handler !=
MKTAG(
'd',
'v',
's',
'd') &&
482 handler !=
MKTAG(
'd',
'v',
'h',
'd') &&
483 handler !=
MKTAG(
'd',
'v',
's',
'l'))
484 goto fail;
485
494 if (CONFIG_DV_DEMUXER) {
497 goto fail;
498 }
504
506 if (ast->
scale > 0 && ast->
rate > 0 && dv_dur > 0) {
509 }
510 /*
511 * else, leave duration alone; timing estimation in utils.c
512 * will make a guess based on bitrate.
513 */
514
517 break;
518 }
519
522
530 av_log(s,
AV_LOG_WARNING,
"scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->
scale, ast->
rate);
531 if(frame_period){
533 ast->
scale = frame_period;
534 }else{
537 }
538 }
540
543
550 }
553 av_dlog(s,
"%"PRIu32
" %"PRIu32
" %d\n",
555
556 switch(tag1) {
557 case MKTAG(
'v',
'i',
'd',
's'):
559
561 break;
562 case MKTAG(
'a',
'u',
'd',
's'):
564 break;
565 case MKTAG(
't',
'x',
't',
's'):
567 break;
568 case MKTAG(
'd',
'a',
't',
's'):
570 break;
571 default:
573 }
579 }
580 }
583 break;
584 case MKTAG(
's',
't',
'r',
'f'):
585 /* stream header */
586 if (!size)
587 break;
590 } else {
592 unsigned esize;
593 if (cur_pos < list_end)
594 size =
FFMIN(size, list_end - cur_pos);
596 switch(codec_type) {
598 if(amv_file_format){
604 break;
605 }
607
608 if (tag1 ==
MKTAG(
'D',
'X',
'S',
'B') || tag1 ==
MKTAG(
'D',
'X',
'S',
'A')) {
612 break;
613 }
614
615 if(size > 10*4 && size<(1<<30) && size < avi->fsize){
622 }
624 }
625
628
629 /* Extract palette from extradata if bpp <= 8. */
630 /* This code assumes that extradata contains only palette. */
631 /* This is true for all paletted codecs implemented in FFmpeg. */
635
638 for (i = 0; i < pal_size/4; i++)
639 ast->
pal[i] = 0xFFU<<24 |
AV_RL32(pal_src+4*i);
641 }
642
644
649
655 }
657
658 // avio_skip(pb, size - 5 * 4);
659 break;
662 if (ret < 0)
668 }
669 if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
671 /* Force parsing as several audio frames can be in
672 * one packet and timestamps refer to packet start. */
674 /* ADTS header is in extradata, AAC without header must be
675 * stored as exact frames. Parser not needed and it will
676 * fail. */
679 /* AVI files with Xan DPCM audio (wrongly) declare PCM
680 * audio in the header but have Axan as stream_code_tag. */
685 }
686 if (amv_file_format){
689 }
693 }
699 }
700 break;
705 break;
706 default:
711 break;
712 }
713 }
714 break;
715 case MKTAG(
's',
't',
'r',
'd'):
720 } else {
722 if (cur_pos < list_end)
723 size =
FFMIN(size, list_end - cur_pos);
725
726 if(size<(1<<30)){
732 }
734 }
735
738 }
739 break;
740 case MKTAG(
'i',
'n',
'd',
'x'):
744 goto fail;
746 break;
747 case MKTAG(
'v',
'p',
'r',
'p'):
748 if(stream_index < (
unsigned)s->
nb_streams && size > 9*4){
750
757
763
764 if(active_aspect.
num && active_aspect.
den && active.
num && active.
den){
766 av_dlog(s,
"vprp %d/%d %d/%d\n",
767 active_aspect.
num, active_aspect.
den,
769 }
770 size -= 9*4;
771 }
773 break;
774 case MKTAG(
's',
't',
'r',
'n'):
777 if (ret < 0)
779 break;
780 }
781 default:
782 if(size > 1000000){
784 "I will ignore it and try to continue anyway.\n");
786 goto fail;
789 goto end_of_header;
790 }
791 /* skip tag */
792 size += (size & 1);
794 break;
795 }
796 }
797 end_of_header:
798 /* check stream number */
800 fail:
802 }
803
808
810 if (dict_entry && !strcmp(dict_entry->
value,
"PotEncoder"))
816 }
817
821 break;
822 }
823 // DV-in-AVI cannot be non-interleaved, if set this must be
824 // a mis-detection.
830 }
831
835 }
836
839
840 return 0;
841 }
842
852 0, NULL, NULL, NULL, NULL);
855
857 goto error;
858
861 if (*desc)
863
866
869 goto error;
870
872 goto error;
873
881 }
883 memset(pkt, 0, sizeof(*pkt));
884 return 1;
885 error:
887 }
888 return 0;
889 }
890
893 {
895 int64_t ts, next_ts, ts_min = INT64_MAX;
897 int i;
898
901
907 if (ts <= next_ts && ts < ts_min) {
908 ts_min = ts;
909 sub_st = st;
910 }
911 }
912 }
913
914 if (sub_st) {
920 }
921 return sub_st;
922 }
923
925 if( d[0] >= '0' && d[0] <= '9'
926 && d[1] >= '0' && d[1] <= '9'){
927 return (d[0] - '0') * 10 + (d[1] - '0');
928 }else{
929 return 100; //invalid stream ID
930 }
931 }
932
933 /**
934 *
935 * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
936 */
938 {
942 unsigned int d[8];
945
946 start_sync:
947 memset(d, -1, sizeof(d));
949 int j;
950
951 for(j=0; j<7; j++)
952 d[j]= d[j+1];
954
955 size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
956
958 av_dlog(s,
"%X %X %X %X %X %X %X %X %"PRId64
" %u %d\n",
959 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
960 if(i*(avi->
io_fsize>0) + (uint64_t)size > avi->
fsize || d[0] > 127)
961 continue;
962
963 //parse ix##
964 if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
965 //parse JUNK
966 ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
967 ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
969 goto start_sync;
970 }
971
972 //parse stray LIST
973 if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
975 goto start_sync;
976 }
977
979
981 continue;
982
983 //detect ##ix chunk and skip
984 if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
986 goto start_sync;
987 }
988
989 //parse ##dc/##wb
990 if(n < s->nb_streams){
995
996 if (!ast) {
998 continue;
999 }
1000
1004 //workaround for broken small-file-bug402.avi
1005 if( d[2] == 'w' && d[3] == 'b'
1006 && n==0
1009 && ast->
prefix ==
'd'*256+
'c'
1011 ){
1012 n=1;
1013 st = st1;
1014 ast = ast1;
1016 }
1017 }
1018
1019
1021 /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
1023 if (!exit_early) {
1026 goto start_sync;
1027 }
1028 }
1029
1030 if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
1032 int last = (k +
avio_r8(pb) - 1) & 0xFF;
1033
1035
1036 for (; k <= last; k++)
1037 ast->
pal[k] = 0xFFU<<24 |
avio_rb32(pb)>>8;
// b + (g << 8) + (r << 16);
1039 goto start_sync;
1040 }
else if( ((ast->
prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
1041 d[2]*256+d[3] == ast->
prefix /*||
1042 (d[2] == 'd' && d[3] == 'c') ||
1043 (d[2] == 'w' && d[3] == 'b')*/) {
1044
1045 if (exit_early)
1046 return 0;
1047 if(d[2]*256+d[3] == ast->
prefix)
1049 else{
1050 ast->
prefix= d[2]*256+d[3];
1052 }
1053
1057
1062 }
1063 }
1064 return 0;
1065 }
1066 }
1067 }
1068
1072 }
1073
1075 {
1078 int err;
1079 #if FF_API_DESTRUCT_PACKET
1080 void* dstr;
1081 #endif
1082
1083 if (CONFIG_DV_DEMUXER && avi->
dv_demux) {
1085 if (size >= 0)
1087 }
1088
1090 int best_stream_index = 0;
1093 int64_t best_ts= INT64_MAX;
1094 int i;
1095
1100 int64_t last_ts;
1101
1103 continue;
1104
1107 continue;
1108
1110
1111 av_dlog(s,
"%"PRId64
" %d/%d %"PRId64
"\n", ts,
1112 st->time_base.num, st->time_base.den, ast->frame_offset);
1113 if(ts < best_ts){
1114 best_ts= ts;
1115 best_st= st;
1116 best_stream_index= i;
1117 }
1118 }
1119 if(!best_st)
1121
1122 best_ast = best_st->priv_data;
1123 best_ts = best_ast->frame_offset;
1124 if(best_ast->remaining)
1126 else{
1128 if(i>=0)
1129 best_ast->frame_offset= best_st->index_entries[i].timestamp;
1130 }
1131
1132 if(i>=0){
1133 int64_t pos= best_st->index_entries[i].pos;
1134 pos += best_ast->packet_size - best_ast->remaining;
1137
1138 av_assert0(best_ast->remaining <= best_ast->packet_size);
1139
1141 if(!best_ast->remaining)
1142 best_ast->packet_size=
1143 best_ast->remaining= best_st->index_entries[i].size;
1144 }
1145 else
1147 }
1148
1150 if(avi->stream_index >= 0){
1151 AVStream *st=
s->streams[ avi->stream_index ];
1154
1156 return 0;
1157
1158 if(ast->
sample_size <= 1)
// minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
1159 size= INT_MAX;
1161 // arbitrary multiplier to avoid tiny packets for raw PCM data
1163 else
1165
1170 if(err<0)
1171 return err;
1172 size = err;
1173
1177 if(!pal){
1179 }else{
1182 }
1183 }
1184
1185 if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1187 #if FF_API_DESTRUCT_PACKET
1188 dstr =
pkt->destruct;
1189 #endif
1192 #if FF_API_DESTRUCT_PACKET
1193 pkt->destruct = dstr;
1194 #endif
1197 if (size < 0)
1202 avi->stream_index = -1;
1205 } else {
1206 /* XXX: How to handle B-frames in AVI? */
1208 // pkt->dts += ast->start;
1211 av_dlog(
s,
"dts:%"PRId64
" offset:%"PRId64
" %d/%d smpl_siz:%d base:%d st:%d size:%d\n",
1215
1220
1223
1226 int key=1;
1227 int i;
1229 for(i=0; i<
FFMIN(size,256); i++){
1231 if(state == 0x1B6){
1233 break;
1234 }
1235 }else
1236 break;
1237 state= (state<<8) +
pkt->
data[i];
1238 }
1239 if(!key)
1241 }
1244 }
1245 } else {
1247 }
1249 }
1252 avi->stream_index= -1;
1254 }
1255
1259 }
1261
1262 if(!avi->non_interleaved && st->
nb_index_entries>1 && avi->index_loaded>1){
1264
1266 avi->non_interleaved= 1;
1268 }else if(avi->dts_max < dts)
1269 avi->dts_max = dts;
1270 }
1271
1272 return 0;
1273 }
1274
1276 return err;
1278 }
1279
1280 /* XXX: We make the implicit supposition that the positions are sorted
1281 for each stream. */
1283 {
1286 int nb_index_entries, i;
1290 unsigned last_pos= -1;
1291 unsigned last_idx= -1;
1292 int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
1293 int anykey = 0;
1294
1295 nb_index_entries = size / 16;
1296 if (nb_index_entries <= 0)
1298
1303 }
1306
1308 first_packet_pos = 0;
1310 }
1311
1312 /* Read the entries and sort them in each stream component. */
1313 for(i = 0; i < nb_index_entries; i++) {
1315 return -1;
1316
1321 av_dlog(s,
"%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
1322 i, tag, flags, pos, len);
1323
1324 index = ((tag & 0xff) - '0') * 10;
1325 index += ((tag >> 8) & 0xff) - '0';
1327 continue;
1330
1331 if(first_packet && first_packet_pos && len) {
1332 data_offset = first_packet_pos - pos;
1333 first_packet = 0;
1334 }
1335 pos += data_offset;
1336
1338
1339 // even if we have only a single stream, we should
1340 // switch to non-interleaved to get correct timestamps
1341 if(last_pos == pos)
1343 if(last_idx != pos && len) {
1345 last_idx= pos;
1346 }
1348 last_pos= pos;
1350 }
1351 if (!anykey) {
1352 for (index = 0; index < s->
nb_streams; index++) {
1356 }
1357 }
1358 return 0;
1359 }
1360
1362 int i;
1363 int64_t last_start=0;
1364 int64_t first_end= INT64_MAX;
1366 int *idx;
1367 int64_t min_pos, pos;
1368
1373
1374 if(n <= 0)
1375 continue;
1376
1377 if(n >= 2){
1382 last_start= INT64_MAX;
1383 }
1384
1389 }
1391 if (last_start > first_end)
1392 return 1;
1394 for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) {
1395 int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2;
1396 min_pos = INT64_MAX;
1397
1403 idx[i]++;
1404 if (idx[i] < n) {
1407 }
1408 if (idx[i])
1410 }
1413 return 1;
1414 }
1415 }
1417 return 0;
1418 }
1419
1421 {
1426 int64_t next;
1428
1430 goto the_end; // maybe truncated file
1432 for(;;) {
1436 break;
1437 next =
avio_tell(pb) + size + (size & 1);
1438
1439 av_dlog(s,
"tag=%c%c%c%c size=0x%x\n",
1440 tag & 0xff,
1441 (tag >> 8) & 0xff,
1442 (tag >> 16) & 0xff,
1443 (tag >> 24) & 0xff,
1444 size);
1445
1446 if (tag ==
MKTAG(
'i',
'd',
'x',
'1') &&
1449 ret = 0;
1450 }
else if(tag ==
MKTAG(
'L',
'I',
'S',
'T')) {
1452
1453 if (tag1 ==
MKTAG(
'I',
'N',
'F',
'O'))
1455 }else if(!ret)
1456 break;
1457
1459 break; // something is wrong here
1460 }
1461 the_end:
1464 }
1465
1467 {
1474 }
1475
1477 {
1481 int64_t pos, pos_min;
1483
1485 /* we only load the index on demand */
1488 }
1490
1491 st = s->
streams[stream_index];
1494 if (index<0) {
1496 av_log(s,
AV_LOG_DEBUG,
"Failed to find timestamp %"PRId64
" in index %"PRId64
" .. %"PRId64
"\n",
1501 }
1502
1503 /* find the position */
1506
1507 av_dlog(s,
"XX %"PRId64
" %d %"PRId64
"\n",
1509
1510 if (CONFIG_DV_DEMUXER && avi->
dv_demux) {
1511 /* One and only one real stream for DV in AVI, and it has video */
1512 /* offsets. Calling with other stream indexes should have failed */
1513 /* the av_index_search_timestamp call above. */
1515
1517 return -1;
1518
1519 /* Feed the DV video stream version of the timestamp to the */
1520 /* DV demux so it can synthesize correct timestamps. */
1522
1524 return 0;
1525 }
1526
1527 pos_min= pos;
1531
1534
1537 continue;
1538 }
1539
1541 continue;
1542
1543 // av_assert1(st2->codec->block_align);
1546 st2,
1549 if(index<0)
1550 index=0;
1553 }
1557
1559 continue;
1560
1562 st2,
1565 if(index<0)
1566 index=0;
1568 index--;
1570 }
1571
1572 /* do the seek */
1575 return -1;
1576 }
1579 return 0;
1580 }
1581
1583 {
1584 int i;
1586
1590 if (ast) {
1594 }
1597 }
1598 }
1599
1601
1602 return 0;
1603 }
1604
1606 {
1607 int i;
1608
1609 /* check file header */
1614
1615 return 0;
1616 }
1617
1627 .priv_class = &demuxer_class,
1628 };