00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <strings.h>
00023 #include "libavutil/intreadwrite.h"
00024 #include "libavutil/bswap.h"
00025 #include "libavutil/opt.h"
00026 #include "libavutil/dict.h"
00027 #include "avformat.h"
00028 #include "avi.h"
00029 #include "dv.h"
00030 #include "riff.h"
00031
00032 #undef NDEBUG
00033 #include <assert.h>
00034
00035 typedef struct AVIStream {
00036 int64_t frame_offset;
00037
00038 int remaining;
00039 int packet_size;
00040
00041 int scale;
00042 int rate;
00043 int sample_size;
00044
00045 int64_t cum_len;
00046
00047 int prefix;
00048 int prefix_count;
00049 uint32_t pal[256];
00050 int has_pal;
00051 int dshow_block_align;
00052
00053 AVFormatContext *sub_ctx;
00054 AVPacket sub_pkt;
00055 uint8_t *sub_buffer;
00056
00057 int64_t seek_pos;
00058 } AVIStream;
00059
00060 typedef struct {
00061 const AVClass *class;
00062 int64_t riff_end;
00063 int64_t movi_end;
00064 int64_t fsize;
00065 int64_t movi_list;
00066 int64_t last_pkt_pos;
00067 int index_loaded;
00068 int is_odml;
00069 int non_interleaved;
00070 int stream_index;
00071 DVDemuxContext* dv_demux;
00072 int odml_depth;
00073 int use_odml;
00074 #define MAX_ODML_DEPTH 1000
00075 } AVIContext;
00076
00077
00078 static const AVOption options[] = {
00079 { "use_odml", "use odml index", offsetof(AVIContext, use_odml), FF_OPT_TYPE_INT, 1, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
00080 { NULL },
00081 };
00082
00083 static const AVClass demuxer_class = {
00084 "AVI demuxer",
00085 av_default_item_name,
00086 options,
00087 LIBAVUTIL_VERSION_INT,
00088 };
00089
00090
00091 static const char avi_headers[][8] = {
00092 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
00093 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
00094 { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19},
00095 { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' },
00096 { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
00097 { 0 }
00098 };
00099
00100 static int avi_load_index(AVFormatContext *s);
00101 static int guess_ni_flag(AVFormatContext *s);
00102
00103 #define print_tag(str, tag, size) \
00104 av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \
00105 str, tag & 0xff, \
00106 (tag >> 8) & 0xff, \
00107 (tag >> 16) & 0xff, \
00108 (tag >> 24) & 0xff, \
00109 size)
00110
00111 static inline int get_duration(AVIStream *ast, int len){
00112 if(ast->sample_size){
00113 return len;
00114 }else if (ast->dshow_block_align){
00115 return (len + ast->dshow_block_align - 1)/ast->dshow_block_align;
00116 }else
00117 return 1;
00118 }
00119
00120 static int get_riff(AVFormatContext *s, AVIOContext *pb)
00121 {
00122 AVIContext *avi = s->priv_data;
00123 char header[8];
00124 int i;
00125
00126
00127 avio_read(pb, header, 4);
00128 avi->riff_end = avio_rl32(pb);
00129 avi->riff_end += avio_tell(pb);
00130 avio_read(pb, header+4, 4);
00131
00132 for(i=0; avi_headers[i][0]; i++)
00133 if(!memcmp(header, avi_headers[i], 8))
00134 break;
00135 if(!avi_headers[i][0])
00136 return -1;
00137
00138 if(header[7] == 0x19)
00139 av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n");
00140
00141 return 0;
00142 }
00143
00144 static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
00145 AVIContext *avi = s->priv_data;
00146 AVIOContext *pb = s->pb;
00147 int longs_pre_entry= avio_rl16(pb);
00148 int index_sub_type = avio_r8(pb);
00149 int index_type = avio_r8(pb);
00150 int entries_in_use = avio_rl32(pb);
00151 int chunk_id = avio_rl32(pb);
00152 int64_t base = avio_rl64(pb);
00153 int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
00154 AVStream *st;
00155 AVIStream *ast;
00156 int i;
00157 int64_t last_pos= -1;
00158 int64_t filesize= avio_size(s->pb);
00159
00160 av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
00161 longs_pre_entry,index_type, entries_in_use, chunk_id, base);
00162
00163 if(stream_id >= s->nb_streams || stream_id < 0)
00164 return -1;
00165 st= s->streams[stream_id];
00166 ast = st->priv_data;
00167
00168 if(index_sub_type)
00169 return -1;
00170
00171 avio_rl32(pb);
00172
00173 if(index_type && longs_pre_entry != 2)
00174 return -1;
00175 if(index_type>1)
00176 return -1;
00177
00178 if(filesize > 0 && base >= filesize){
00179 av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
00180 if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
00181 base &= 0xFFFFFFFF;
00182 else
00183 return -1;
00184 }
00185
00186 for(i=0; i<entries_in_use; i++){
00187 if(index_type){
00188 int64_t pos= avio_rl32(pb) + base - 8;
00189 int len = avio_rl32(pb);
00190 int key= len >= 0;
00191 len &= 0x7FFFFFFF;
00192
00193 #ifdef DEBUG_SEEK
00194 av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
00195 #endif
00196 if(url_feof(pb))
00197 return -1;
00198
00199 if(last_pos == pos || pos == base - 8)
00200 avi->non_interleaved= 1;
00201 if(last_pos != pos && (len || !ast->sample_size))
00202 av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);
00203
00204 ast->cum_len += get_duration(ast, len);
00205 last_pos= pos;
00206 }else{
00207 int64_t offset, pos;
00208 int duration;
00209 offset = avio_rl64(pb);
00210 avio_rl32(pb);
00211 duration = avio_rl32(pb);
00212
00213 if(url_feof(pb))
00214 return -1;
00215
00216 pos = avio_tell(pb);
00217
00218 if(avi->odml_depth > MAX_ODML_DEPTH){
00219 av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
00220 return -1;
00221 }
00222
00223 if(avio_seek(pb, offset+8, SEEK_SET) < 0)
00224 return -1;
00225 avi->odml_depth++;
00226 read_braindead_odml_indx(s, frame_num);
00227 avi->odml_depth--;
00228 frame_num += duration;
00229
00230 if(avio_seek(pb, pos, SEEK_SET) < 0) {
00231 av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index");
00232 return -1;
00233 }
00234
00235 }
00236 }
00237 avi->index_loaded=1;
00238 return 0;
00239 }
00240
00241 static void clean_index(AVFormatContext *s){
00242 int i;
00243 int64_t j;
00244
00245 for(i=0; i<s->nb_streams; i++){
00246 AVStream *st = s->streams[i];
00247 AVIStream *ast = st->priv_data;
00248 int n= st->nb_index_entries;
00249 int max= ast->sample_size;
00250 int64_t pos, size, ts;
00251
00252 if(n != 1 || ast->sample_size==0)
00253 continue;
00254
00255 while(max < 1024) max+=max;
00256
00257 pos= st->index_entries[0].pos;
00258 size= st->index_entries[0].size;
00259 ts= st->index_entries[0].timestamp;
00260
00261 for(j=0; j<size; j+=max){
00262 av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
00263 }
00264 }
00265 }
00266
00267 static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
00268 {
00269 AVIOContext *pb = s->pb;
00270 char key[5] = {0}, *value;
00271
00272 size += (size & 1);
00273
00274 if (size == UINT_MAX)
00275 return -1;
00276 value = av_malloc(size+1);
00277 if (!value)
00278 return -1;
00279 avio_read(pb, value, size);
00280 value[size]=0;
00281
00282 AV_WL32(key, tag);
00283
00284 return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
00285 AV_DICT_DONT_STRDUP_VAL);
00286 }
00287
00288 static void avi_read_info(AVFormatContext *s, uint64_t end)
00289 {
00290 while (avio_tell(s->pb) < end) {
00291 uint32_t tag = avio_rl32(s->pb);
00292 uint32_t size = avio_rl32(s->pb);
00293 avi_read_tag(s, NULL, tag, size);
00294 }
00295 }
00296
00297 static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00298 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00299
00300 static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
00301 {
00302 char month[4], time[9], buffer[64];
00303 int i, day, year;
00304
00305 if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
00306 month, &day, time, &year) == 4) {
00307 for (i=0; i<12; i++)
00308 if (!strcasecmp(month, months[i])) {
00309 snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
00310 year, i+1, day, time);
00311 av_dict_set(metadata, "creation_time", buffer, 0);
00312 }
00313 } else if (date[4] == '/' && date[7] == '/') {
00314 date[4] = date[7] = '-';
00315 av_dict_set(metadata, "creation_time", date, 0);
00316 }
00317 }
00318
00319 static void avi_read_nikon(AVFormatContext *s, uint64_t end)
00320 {
00321 while (avio_tell(s->pb) < end) {
00322 uint32_t tag = avio_rl32(s->pb);
00323 uint32_t size = avio_rl32(s->pb);
00324 switch (tag) {
00325 case MKTAG('n', 'c', 't', 'g'): {
00326 uint64_t tag_end = avio_tell(s->pb) + size;
00327 while (avio_tell(s->pb) < tag_end) {
00328 uint16_t tag = avio_rl16(s->pb);
00329 uint16_t size = avio_rl16(s->pb);
00330 const char *name = NULL;
00331 char buffer[64] = {0};
00332 size -= avio_read(s->pb, buffer,
00333 FFMIN(size, sizeof(buffer)-1));
00334 switch (tag) {
00335 case 0x03: name = "maker"; break;
00336 case 0x04: name = "model"; break;
00337 case 0x13: name = "creation_time";
00338 if (buffer[4] == ':' && buffer[7] == ':')
00339 buffer[4] = buffer[7] = '-';
00340 break;
00341 }
00342 if (name)
00343 av_dict_set(&s->metadata, name, buffer, 0);
00344 avio_skip(s->pb, size);
00345 }
00346 break;
00347 }
00348 default:
00349 avio_skip(s->pb, size);
00350 break;
00351 }
00352 }
00353 }
00354
00355 static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
00356 {
00357 AVIContext *avi = s->priv_data;
00358 AVIOContext *pb = s->pb;
00359 unsigned int tag, tag1, handler;
00360 int codec_type, stream_index, frame_period;
00361 unsigned int size;
00362 int i;
00363 AVStream *st;
00364 AVIStream *ast = NULL;
00365 int avih_width=0, avih_height=0;
00366 int amv_file_format=0;
00367 uint64_t list_end = 0;
00368 int ret;
00369
00370 avi->stream_index= -1;
00371
00372 if (get_riff(s, pb) < 0)
00373 return -1;
00374
00375 av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
00376
00377 avi->fsize = avio_size(pb);
00378 if(avi->fsize<=0)
00379 avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
00380
00381
00382 stream_index = -1;
00383 codec_type = -1;
00384 frame_period = 0;
00385 for(;;) {
00386 if (url_feof(pb))
00387 goto fail;
00388 tag = avio_rl32(pb);
00389 size = avio_rl32(pb);
00390
00391 print_tag("tag", tag, size);
00392
00393 switch(tag) {
00394 case MKTAG('L', 'I', 'S', 'T'):
00395 list_end = avio_tell(pb) + size;
00396
00397 tag1 = avio_rl32(pb);
00398
00399 print_tag("list", tag1, 0);
00400
00401 if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
00402 avi->movi_list = avio_tell(pb) - 4;
00403 if(size) avi->movi_end = avi->movi_list + size + (size & 1);
00404 else avi->movi_end = avio_size(pb);
00405 av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
00406 goto end_of_header;
00407 }
00408 else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
00409 avi_read_info(s, list_end);
00410 else if (tag1 == MKTAG('n', 'c', 'd', 't'))
00411 avi_read_nikon(s, list_end);
00412
00413 break;
00414 case MKTAG('I', 'D', 'I', 'T'): {
00415 unsigned char date[64] = {0};
00416 size += (size & 1);
00417 size -= avio_read(pb, date, FFMIN(size, sizeof(date)-1));
00418 avio_skip(pb, size);
00419 avi_metadata_creation_time(&s->metadata, date);
00420 break;
00421 }
00422 case MKTAG('d', 'm', 'l', 'h'):
00423 avi->is_odml = 1;
00424 avio_skip(pb, size + (size & 1));
00425 break;
00426 case MKTAG('a', 'm', 'v', 'h'):
00427 amv_file_format=1;
00428 case MKTAG('a', 'v', 'i', 'h'):
00429
00430
00431 frame_period = avio_rl32(pb);
00432 avio_rl32(pb);
00433 avio_rl32(pb);
00434 avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
00435
00436 avio_skip(pb, 2 * 4);
00437 avio_rl32(pb);
00438 avio_rl32(pb);
00439 avih_width=avio_rl32(pb);
00440 avih_height=avio_rl32(pb);
00441
00442 avio_skip(pb, size - 10 * 4);
00443 break;
00444 case MKTAG('s', 't', 'r', 'h'):
00445
00446
00447 tag1 = avio_rl32(pb);
00448 handler = avio_rl32(pb);
00449
00450 if(tag1 == MKTAG('p', 'a', 'd', 's')){
00451 avio_skip(pb, size - 8);
00452 break;
00453 }else{
00454 stream_index++;
00455 st = av_new_stream(s, stream_index);
00456 if (!st)
00457 goto fail;
00458
00459 ast = av_mallocz(sizeof(AVIStream));
00460 if (!ast)
00461 goto fail;
00462 st->priv_data = ast;
00463 }
00464 if(amv_file_format)
00465 tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s');
00466
00467 print_tag("strh", tag1, -1);
00468
00469 if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
00470 int64_t dv_dur;
00471
00472
00473
00474
00475
00476 if (s->nb_streams != 1)
00477 goto fail;
00478
00479 if (handler != MKTAG('d', 'v', 's', 'd') &&
00480 handler != MKTAG('d', 'v', 'h', 'd') &&
00481 handler != MKTAG('d', 'v', 's', 'l'))
00482 goto fail;
00483
00484 ast = s->streams[0]->priv_data;
00485 av_freep(&s->streams[0]->codec->extradata);
00486 av_freep(&s->streams[0]->codec);
00487 av_freep(&s->streams[0]);
00488 s->nb_streams = 0;
00489 if (CONFIG_DV_DEMUXER) {
00490 avi->dv_demux = dv_init_demux(s);
00491 if (!avi->dv_demux)
00492 goto fail;
00493 }
00494 s->streams[0]->priv_data = ast;
00495 avio_skip(pb, 3 * 4);
00496 ast->scale = avio_rl32(pb);
00497 ast->rate = avio_rl32(pb);
00498 avio_skip(pb, 4);
00499
00500 dv_dur = avio_rl32(pb);
00501 if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
00502 dv_dur *= AV_TIME_BASE;
00503 s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
00504 }
00505
00506
00507
00508
00509
00510 stream_index = s->nb_streams - 1;
00511 avio_skip(pb, size - 9*4);
00512 break;
00513 }
00514
00515 assert(stream_index < s->nb_streams);
00516 st->codec->stream_codec_tag= handler;
00517
00518 avio_rl32(pb);
00519 avio_rl16(pb);
00520 avio_rl16(pb);
00521 avio_rl32(pb);
00522 ast->scale = avio_rl32(pb);
00523 ast->rate = avio_rl32(pb);
00524 if(!(ast->scale && ast->rate)){
00525 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);
00526 if(frame_period){
00527 ast->rate = 1000000;
00528 ast->scale = frame_period;
00529 }else{
00530 ast->rate = 25;
00531 ast->scale = 1;
00532 }
00533 }
00534 av_set_pts_info(st, 64, ast->scale, ast->rate);
00535
00536 ast->cum_len=avio_rl32(pb);
00537 st->nb_frames = avio_rl32(pb);
00538
00539 st->start_time = 0;
00540 avio_rl32(pb);
00541 avio_rl32(pb);
00542 ast->sample_size = avio_rl32(pb);
00543 ast->cum_len *= FFMAX(1, ast->sample_size);
00544
00545
00546 switch(tag1) {
00547 case MKTAG('v', 'i', 'd', 's'):
00548 codec_type = AVMEDIA_TYPE_VIDEO;
00549
00550 ast->sample_size = 0;
00551 break;
00552 case MKTAG('a', 'u', 'd', 's'):
00553 codec_type = AVMEDIA_TYPE_AUDIO;
00554 break;
00555 case MKTAG('t', 'x', 't', 's'):
00556 codec_type = AVMEDIA_TYPE_SUBTITLE;
00557 break;
00558 case MKTAG('d', 'a', 't', 's'):
00559 codec_type = AVMEDIA_TYPE_DATA;
00560 break;
00561 default:
00562 av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
00563 }
00564 if(ast->sample_size == 0)
00565 st->duration = st->nb_frames;
00566 ast->frame_offset= ast->cum_len;
00567 avio_skip(pb, size - 12 * 4);
00568 break;
00569 case MKTAG('s', 't', 'r', 'f'):
00570
00571 if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
00572 avio_skip(pb, size);
00573 } else {
00574 uint64_t cur_pos = avio_tell(pb);
00575 if (cur_pos < list_end)
00576 size = FFMIN(size, list_end - cur_pos);
00577 st = s->streams[stream_index];
00578 switch(codec_type) {
00579 case AVMEDIA_TYPE_VIDEO:
00580 if(amv_file_format){
00581 st->codec->width=avih_width;
00582 st->codec->height=avih_height;
00583 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00584 st->codec->codec_id = CODEC_ID_AMV;
00585 avio_skip(pb, size);
00586 break;
00587 }
00588 tag1 = ff_get_bmp_header(pb, st);
00589
00590 if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
00591 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
00592 st->codec->codec_tag = tag1;
00593 st->codec->codec_id = CODEC_ID_XSUB;
00594 break;
00595 }
00596
00597 if(size > 10*4 && size<(1<<30)){
00598 st->codec->extradata_size= size - 10*4;
00599 st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
00600 if (!st->codec->extradata) {
00601 st->codec->extradata_size= 0;
00602 return AVERROR(ENOMEM);
00603 }
00604 avio_read(pb, st->codec->extradata, st->codec->extradata_size);
00605 }
00606
00607 if(st->codec->extradata_size & 1)
00608 avio_r8(pb);
00609
00610
00611
00612
00613 if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
00614 st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
00615 #if HAVE_BIGENDIAN
00616 for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
00617 st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]);
00618 #else
00619 memcpy(st->codec->palctrl->palette, st->codec->extradata,
00620 FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
00621 #endif
00622 st->codec->palctrl->palette_changed = 1;
00623 }
00624
00625 print_tag("video", tag1, 0);
00626
00627 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00628 st->codec->codec_tag = tag1;
00629 st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
00630 st->need_parsing = AVSTREAM_PARSE_HEADERS;
00631
00632 if(tag1 == MKTAG('A', 'V', 'R', 'n') &&
00633 st->codec->extradata_size >= 31 &&
00634 !memcmp(&st->codec->extradata[28], "1:1", 3))
00635 st->codec->codec_id = CODEC_ID_RAWVIDEO;
00636
00637 if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
00638 st->codec->extradata_size+= 9;
00639 st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
00640 if(st->codec->extradata)
00641 memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
00642 }
00643 st->codec->height= FFABS(st->codec->height);
00644
00645
00646 break;
00647 case AVMEDIA_TYPE_AUDIO:
00648 ret = ff_get_wav_header(pb, st->codec, size);
00649 if (ret < 0)
00650 return ret;
00651 ast->dshow_block_align= st->codec->block_align;
00652 if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
00653 av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
00654 ast->sample_size= st->codec->block_align;
00655 }
00656 if (size&1)
00657 avio_skip(pb, 1);
00658
00659
00660 st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
00661
00662
00663
00664 if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size)
00665 st->need_parsing = AVSTREAM_PARSE_NONE;
00666
00667
00668 if (st->codec->stream_codec_tag == AV_RL32("Axan")){
00669 st->codec->codec_id = CODEC_ID_XAN_DPCM;
00670 st->codec->codec_tag = 0;
00671 }
00672 if (amv_file_format){
00673 st->codec->codec_id = CODEC_ID_ADPCM_IMA_AMV;
00674 ast->dshow_block_align = 0;
00675 }
00676 break;
00677 case AVMEDIA_TYPE_SUBTITLE:
00678 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
00679 st->request_probe= 1;
00680 break;
00681 default:
00682 st->codec->codec_type = AVMEDIA_TYPE_DATA;
00683 st->codec->codec_id= CODEC_ID_NONE;
00684 st->codec->codec_tag= 0;
00685 avio_skip(pb, size);
00686 break;
00687 }
00688 }
00689 break;
00690 case MKTAG('i', 'n', 'd', 'x'):
00691 i= avio_tell(pb);
00692 if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml){
00693 read_braindead_odml_indx(s, 0);
00694 }
00695 avio_seek(pb, i+size, SEEK_SET);
00696 break;
00697 case MKTAG('v', 'p', 'r', 'p'):
00698 if(stream_index < (unsigned)s->nb_streams && size > 9*4){
00699 AVRational active, active_aspect;
00700
00701 st = s->streams[stream_index];
00702 avio_rl32(pb);
00703 avio_rl32(pb);
00704 avio_rl32(pb);
00705 avio_rl32(pb);
00706 avio_rl32(pb);
00707
00708 active_aspect.den= avio_rl16(pb);
00709 active_aspect.num= avio_rl16(pb);
00710 active.num = avio_rl32(pb);
00711 active.den = avio_rl32(pb);
00712 avio_rl32(pb);
00713
00714 if(active_aspect.num && active_aspect.den && active.num && active.den){
00715 st->sample_aspect_ratio= av_div_q(active_aspect, active);
00716
00717 }
00718 size -= 9*4;
00719 }
00720 avio_skip(pb, size);
00721 break;
00722 case MKTAG('s', 't', 'r', 'n'):
00723 if(s->nb_streams){
00724 avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
00725 break;
00726 }
00727 default:
00728 if(size > 1000000){
00729 av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
00730 "I will ignore it and try to continue anyway.\n");
00731 avi->movi_list = avio_tell(pb) - 4;
00732 avi->movi_end = avio_size(pb);
00733 goto end_of_header;
00734 }
00735
00736 size += (size & 1);
00737 avio_skip(pb, size);
00738 break;
00739 }
00740 }
00741 end_of_header:
00742
00743 if (stream_index != s->nb_streams - 1) {
00744 fail:
00745 return -1;
00746 }
00747
00748 if(!avi->index_loaded && pb->seekable)
00749 avi_load_index(s);
00750 avi->index_loaded = 1;
00751 avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
00752 for(i=0; i<s->nb_streams; i++){
00753 AVStream *st = s->streams[i];
00754 if(st->nb_index_entries)
00755 break;
00756 }
00757
00758
00759 if(avi->dv_demux)
00760 avi->non_interleaved=0;
00761 if(i==s->nb_streams && avi->non_interleaved) {
00762 av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
00763 avi->non_interleaved=0;
00764 }
00765
00766 if(avi->non_interleaved) {
00767 av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
00768 clean_index(s);
00769 }
00770
00771 ff_metadata_conv_ctx(s, NULL, ff_avi_metadata_conv);
00772
00773 return 0;
00774 }
00775
00776 static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
00777 if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
00778 uint8_t desc[256];
00779 int score = AVPROBE_SCORE_MAX / 2, ret;
00780 AVIStream *ast = st->priv_data;
00781 AVInputFormat *sub_demuxer;
00782 AVRational time_base;
00783 AVIOContext *pb = avio_alloc_context( pkt->data + 7,
00784 pkt->size - 7,
00785 0, NULL, NULL, NULL, NULL);
00786 AVProbeData pd;
00787 unsigned int desc_len = avio_rl32(pb);
00788
00789 if (desc_len > pb->buf_end - pb->buf_ptr)
00790 goto error;
00791
00792 ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
00793 avio_skip(pb, desc_len - ret);
00794 if (*desc)
00795 av_dict_set(&st->metadata, "title", desc, 0);
00796
00797 avio_rl16(pb);
00798 avio_rl32(pb);
00799
00800 pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
00801 if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
00802 goto error;
00803
00804 if (!(ast->sub_ctx = avformat_alloc_context()))
00805 goto error;
00806
00807 ast->sub_ctx->pb = pb;
00808 if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
00809 av_read_packet(ast->sub_ctx, &ast->sub_pkt);
00810 *st->codec = *ast->sub_ctx->streams[0]->codec;
00811 ast->sub_ctx->streams[0]->codec->extradata = NULL;
00812 time_base = ast->sub_ctx->streams[0]->time_base;
00813 av_set_pts_info(st, 64, time_base.num, time_base.den);
00814 }
00815 ast->sub_buffer = pkt->data;
00816 memset(pkt, 0, sizeof(*pkt));
00817 return 1;
00818 error:
00819 av_freep(&pb);
00820 }
00821 return 0;
00822 }
00823
00824 static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
00825 AVPacket *pkt)
00826 {
00827 AVIStream *ast, *next_ast = next_st->priv_data;
00828 int64_t ts, next_ts, ts_min = INT64_MAX;
00829 AVStream *st, *sub_st = NULL;
00830 int i;
00831
00832 next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
00833 AV_TIME_BASE_Q);
00834
00835 for (i=0; i<s->nb_streams; i++) {
00836 st = s->streams[i];
00837 ast = st->priv_data;
00838 if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
00839 ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q);
00840 if (ts <= next_ts && ts < ts_min) {
00841 ts_min = ts;
00842 sub_st = st;
00843 }
00844 }
00845 }
00846
00847 if (sub_st) {
00848 ast = sub_st->priv_data;
00849 *pkt = ast->sub_pkt;
00850 pkt->stream_index = sub_st->index;
00851 if (av_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
00852 ast->sub_pkt.data = NULL;
00853 }
00854 return sub_st;
00855 }
00856
00857 static int get_stream_idx(int *d){
00858 if( d[0] >= '0' && d[0] <= '9'
00859 && d[1] >= '0' && d[1] <= '9'){
00860 return (d[0] - '0') * 10 + (d[1] - '0');
00861 }else{
00862 return 100;
00863 }
00864 }
00865
00866 static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
00867 {
00868 AVIContext *avi = s->priv_data;
00869 AVIOContext *pb = s->pb;
00870 int n, d[8];
00871 unsigned int size;
00872 int64_t i, sync;
00873 void* dstr;
00874
00875 if (CONFIG_DV_DEMUXER && avi->dv_demux) {
00876 int size = dv_get_packet(avi->dv_demux, pkt);
00877 if (size >= 0)
00878 return size;
00879 }
00880
00881 if(avi->non_interleaved){
00882 int best_stream_index = 0;
00883 AVStream *best_st= NULL;
00884 AVIStream *best_ast;
00885 int64_t best_ts= INT64_MAX;
00886 int i;
00887
00888 for(i=0; i<s->nb_streams; i++){
00889 AVStream *st = s->streams[i];
00890 AVIStream *ast = st->priv_data;
00891 int64_t ts= ast->frame_offset;
00892 int64_t last_ts;
00893
00894 if(!st->nb_index_entries)
00895 continue;
00896
00897 last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
00898 if(!ast->remaining && ts > last_ts)
00899 continue;
00900
00901 ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE});
00902
00903
00904 if(ts < best_ts){
00905 best_ts= ts;
00906 best_st= st;
00907 best_stream_index= i;
00908 }
00909 }
00910 if(!best_st)
00911 return -1;
00912
00913 best_ast = best_st->priv_data;
00914 best_ts = av_rescale_q(best_ts, (AVRational){FFMAX(1, best_ast->sample_size), AV_TIME_BASE}, best_st->time_base);
00915 if(best_ast->remaining)
00916 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
00917 else{
00918 i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
00919 if(i>=0)
00920 best_ast->frame_offset= best_st->index_entries[i].timestamp;
00921 }
00922
00923
00924 if(i>=0){
00925 int64_t pos= best_st->index_entries[i].pos;
00926 pos += best_ast->packet_size - best_ast->remaining;
00927 avio_seek(s->pb, pos + 8, SEEK_SET);
00928
00929
00930 assert(best_ast->remaining <= best_ast->packet_size);
00931
00932 avi->stream_index= best_stream_index;
00933 if(!best_ast->remaining)
00934 best_ast->packet_size=
00935 best_ast->remaining= best_st->index_entries[i].size;
00936 }
00937 }
00938
00939 resync:
00940 if(avi->stream_index >= 0){
00941 AVStream *st= s->streams[ avi->stream_index ];
00942 AVIStream *ast= st->priv_data;
00943 int size, err;
00944
00945 if(get_subtitle_pkt(s, st, pkt))
00946 return 0;
00947
00948 if(ast->sample_size <= 1)
00949 size= INT_MAX;
00950 else if(ast->sample_size < 32)
00951
00952 size= 1024*ast->sample_size;
00953 else
00954 size= ast->sample_size;
00955
00956 if(size > ast->remaining)
00957 size= ast->remaining;
00958 avi->last_pkt_pos= avio_tell(pb);
00959 err= av_get_packet(pb, pkt, size);
00960 if(err<0)
00961 return err;
00962
00963 if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){
00964 void *ptr= av_realloc(pkt->data, pkt->size + 4*256 + FF_INPUT_BUFFER_PADDING_SIZE);
00965 if(ptr){
00966 ast->has_pal=0;
00967 pkt->size += 4*256;
00968 pkt->data= ptr;
00969 memcpy(pkt->data + pkt->size - 4*256, ast->pal, 4*256);
00970 }else
00971 av_log(s, AV_LOG_ERROR, "Failed to append palette\n");
00972 }
00973
00974 if (CONFIG_DV_DEMUXER && avi->dv_demux) {
00975 dstr = pkt->destruct;
00976 size = dv_produce_packet(avi->dv_demux, pkt,
00977 pkt->data, pkt->size, pkt->pos);
00978 pkt->destruct = dstr;
00979 pkt->flags |= AV_PKT_FLAG_KEY;
00980 if (size < 0)
00981 av_free_packet(pkt);
00982 } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
00983 && !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
00984 ast->frame_offset++;
00985 avi->stream_index = -1;
00986 ast->remaining = 0;
00987 goto resync;
00988 } else {
00989
00990 pkt->dts = ast->frame_offset;
00991
00992 if(ast->sample_size)
00993 pkt->dts /= ast->sample_size;
00994
00995 pkt->stream_index = avi->stream_index;
00996
00997 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00998 AVIndexEntry *e;
00999 int index;
01000 assert(st->index_entries);
01001
01002 index= av_index_search_timestamp(st, ast->frame_offset, 0);
01003 e= &st->index_entries[index];
01004
01005 if(index >= 0 && e->timestamp == ast->frame_offset){
01006 if (index == st->nb_index_entries-1){
01007 int key=1;
01008 int i;
01009 uint32_t state=-1;
01010 for(i=0; i<FFMIN(size,256); i++){
01011 if(st->codec->codec_id == CODEC_ID_MPEG4){
01012 if(state == 0x1B6){
01013 key= !(pkt->data[i]&0xC0);
01014 break;
01015 }
01016 }else
01017 break;
01018 state= (state<<8) + pkt->data[i];
01019 }
01020 if(!key)
01021 e->flags &= ~AVINDEX_KEYFRAME;
01022 }
01023 if (e->flags & AVINDEX_KEYFRAME)
01024 pkt->flags |= AV_PKT_FLAG_KEY;
01025 }
01026 } else {
01027 pkt->flags |= AV_PKT_FLAG_KEY;
01028 }
01029 ast->frame_offset += get_duration(ast, pkt->size);
01030 }
01031 ast->remaining -= size;
01032 if(!ast->remaining){
01033 avi->stream_index= -1;
01034 ast->packet_size= 0;
01035 }
01036
01037 if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
01038 av_free_packet(pkt);
01039 goto resync;
01040 }
01041 ast->seek_pos= 0;
01042
01043 return size;
01044 }
01045
01046 memset(d, -1, sizeof(int)*8);
01047 for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
01048 int j;
01049
01050 for(j=0; j<7; j++)
01051 d[j]= d[j+1];
01052 d[7]= avio_r8(pb);
01053
01054 size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
01055
01056 n= get_stream_idx(d+2);
01057
01058 if(i + (uint64_t)size > avi->fsize || d[0]<0)
01059 continue;
01060
01061
01062 if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
01063
01064 ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
01065 ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
01066 avio_skip(pb, size);
01067
01068 goto resync;
01069 }
01070
01071
01072 if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
01073 avio_skip(pb, 4);
01074 goto resync;
01075 }
01076
01077 n= get_stream_idx(d);
01078
01079 if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
01080 continue;
01081
01082
01083 if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
01084 avio_skip(pb, size);
01085 goto resync;
01086 }
01087
01088
01089 if(n < s->nb_streams){
01090 AVStream *st;
01091 AVIStream *ast;
01092 st = s->streams[n];
01093 ast = st->priv_data;
01094
01095 if(s->nb_streams>=2){
01096 AVStream *st1 = s->streams[1];
01097 AVIStream *ast1= st1->priv_data;
01098
01099 if( d[2] == 'w' && d[3] == 'b'
01100 && n==0
01101 && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
01102 && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
01103 && ast->prefix == 'd'*256+'c'
01104 && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
01105 ){
01106 n=1;
01107 st = st1;
01108 ast = ast1;
01109 av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
01110 }
01111 }
01112
01113
01114 if( (st->discard >= AVDISCARD_DEFAULT && size==0)
01115
01116 || st->discard >= AVDISCARD_ALL){
01117 ast->frame_offset += get_duration(ast, size);
01118 avio_skip(pb, size);
01119 goto resync;
01120 }
01121
01122 if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
01123 int k = avio_r8(pb);
01124 int last = (k + avio_r8(pb) - 1) & 0xFF;
01125
01126 avio_rl16(pb);
01127
01128 for (; k <= last; k++)
01129 ast->pal[k] = avio_rb32(pb)>>8;
01130 ast->has_pal= 1;
01131 goto resync;
01132 } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
01133 d[2]*256+d[3] == ast->prefix
01134
01135 ) {
01136
01137
01138 if(d[2]*256+d[3] == ast->prefix)
01139 ast->prefix_count++;
01140 else{
01141 ast->prefix= d[2]*256+d[3];
01142 ast->prefix_count= 0;
01143 }
01144
01145 avi->stream_index= n;
01146 ast->packet_size= size + 8;
01147 ast->remaining= size;
01148
01149 if(size || !ast->sample_size){
01150 uint64_t pos= avio_tell(pb) - 8;
01151 if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
01152 av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
01153 }
01154 }
01155 goto resync;
01156 }
01157 }
01158 }
01159
01160 return AVERROR_EOF;
01161 }
01162
01163
01164
01165 static int avi_read_idx1(AVFormatContext *s, int size)
01166 {
01167 AVIContext *avi = s->priv_data;
01168 AVIOContext *pb = s->pb;
01169 int nb_index_entries, i;
01170 AVStream *st;
01171 AVIStream *ast;
01172 unsigned int index, tag, flags, pos, len;
01173 unsigned last_pos= -1;
01174
01175 nb_index_entries = size / 16;
01176 if (nb_index_entries <= 0)
01177 return -1;
01178
01179
01180 for(i = 0; i < nb_index_entries; i++) {
01181 tag = avio_rl32(pb);
01182 flags = avio_rl32(pb);
01183 pos = avio_rl32(pb);
01184 len = avio_rl32(pb);
01185 av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
01186 i, tag, flags, pos, len);
01187 if(i==0 && pos > avi->movi_list)
01188 avi->movi_list= 0;
01189 pos += avi->movi_list;
01190
01191 index = ((tag & 0xff) - '0') * 10;
01192 index += ((tag >> 8) & 0xff) - '0';
01193 if (index >= s->nb_streams)
01194 continue;
01195 st = s->streams[index];
01196 ast = st->priv_data;
01197
01198 #if defined(DEBUG_SEEK)
01199 av_log(s, AV_LOG_DEBUG, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
01200 #endif
01201 if(url_feof(pb))
01202 return -1;
01203
01204 if(last_pos == pos)
01205 avi->non_interleaved= 1;
01206 else if(len || !ast->sample_size)
01207 av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
01208 ast->cum_len += get_duration(ast, len);
01209 last_pos= pos;
01210 }
01211 return 0;
01212 }
01213
01214 static int guess_ni_flag(AVFormatContext *s){
01215 int i;
01216 int64_t last_start=0;
01217 int64_t first_end= INT64_MAX;
01218 int64_t oldpos= avio_tell(s->pb);
01219
01220 for(i=0; i<s->nb_streams; i++){
01221 AVStream *st = s->streams[i];
01222 int n= st->nb_index_entries;
01223 unsigned int size;
01224
01225 if(n <= 0)
01226 continue;
01227
01228 if(n >= 2){
01229 int64_t pos= st->index_entries[0].pos;
01230 avio_seek(s->pb, pos + 4, SEEK_SET);
01231 size= avio_rl32(s->pb);
01232 if(pos + size > st->index_entries[1].pos)
01233 last_start= INT64_MAX;
01234 }
01235
01236 if(st->index_entries[0].pos > last_start)
01237 last_start= st->index_entries[0].pos;
01238 if(st->index_entries[n-1].pos < first_end)
01239 first_end= st->index_entries[n-1].pos;
01240 }
01241 avio_seek(s->pb, oldpos, SEEK_SET);
01242 return last_start > first_end;
01243 }
01244
01245 static int avi_load_index(AVFormatContext *s)
01246 {
01247 AVIContext *avi = s->priv_data;
01248 AVIOContext *pb = s->pb;
01249 uint32_t tag, size;
01250 int64_t pos= avio_tell(pb);
01251 int ret = -1;
01252
01253 if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
01254 goto the_end;
01255 av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
01256 for(;;) {
01257 if (url_feof(pb))
01258 break;
01259 tag = avio_rl32(pb);
01260 size = avio_rl32(pb);
01261 av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
01262 tag & 0xff,
01263 (tag >> 8) & 0xff,
01264 (tag >> 16) & 0xff,
01265 (tag >> 24) & 0xff,
01266 size);
01267 switch(tag) {
01268 case MKTAG('i', 'd', 'x', '1'):
01269 if (avi_read_idx1(s, size) < 0)
01270 goto skip;
01271 ret = 0;
01272 goto the_end;
01273 break;
01274 default:
01275 skip:
01276 size += (size & 1);
01277 if (avio_skip(pb, size) < 0)
01278 goto the_end;
01279 break;
01280 }
01281 }
01282 the_end:
01283 avio_seek(pb, pos, SEEK_SET);
01284 return ret;
01285 }
01286
01287 static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
01288 {
01289 AVIStream *ast2 = st2->priv_data;
01290 int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
01291 av_free_packet(&ast2->sub_pkt);
01292 if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
01293 avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
01294 av_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
01295 }
01296
01297 static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
01298 {
01299 AVIContext *avi = s->priv_data;
01300 AVStream *st;
01301 int i, index;
01302 int64_t pos, pos_min;
01303 AVIStream *ast;
01304
01305 if (!avi->index_loaded) {
01306
01307 avi_load_index(s);
01308 avi->index_loaded = 1;
01309 }
01310 assert(stream_index>= 0);
01311
01312 st = s->streams[stream_index];
01313 ast= st->priv_data;
01314 index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
01315 if(index<0)
01316 return -1;
01317
01318
01319 pos = st->index_entries[index].pos;
01320 timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
01321
01322
01323
01324 if (CONFIG_DV_DEMUXER && avi->dv_demux) {
01325
01326
01327
01328 assert(stream_index == 0);
01329
01330 if(avio_seek(s->pb, pos, SEEK_SET) < 0)
01331 return -1;
01332
01333
01334
01335 dv_offset_reset(avi->dv_demux, timestamp);
01336
01337 avi->stream_index= -1;
01338 return 0;
01339 }
01340
01341 pos_min= pos;
01342 for(i = 0; i < s->nb_streams; i++) {
01343 AVStream *st2 = s->streams[i];
01344 AVIStream *ast2 = st2->priv_data;
01345
01346 ast2->packet_size=
01347 ast2->remaining= 0;
01348
01349 if (ast2->sub_ctx) {
01350 seek_subtitle(st, st2, timestamp);
01351 continue;
01352 }
01353
01354 if (st2->nb_index_entries <= 0)
01355 continue;
01356
01357
01358 assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
01359 index = av_index_search_timestamp(
01360 st2,
01361 av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
01362 flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
01363 if(index<0)
01364 index=0;
01365 ast2->seek_pos= st2->index_entries[index].pos;
01366 pos_min= FFMIN(pos_min,ast2->seek_pos);
01367 }
01368 for(i = 0; i < s->nb_streams; i++) {
01369 AVStream *st2 = s->streams[i];
01370 AVIStream *ast2 = st2->priv_data;
01371
01372 if (ast2->sub_ctx || st2->nb_index_entries <= 0)
01373 continue;
01374
01375 index = av_index_search_timestamp(
01376 st2,
01377 av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
01378 flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
01379 if(index<0)
01380 index=0;
01381 while(index>0 && st2->index_entries[index-1].pos >= pos_min)
01382 index--;
01383 ast2->frame_offset = st2->index_entries[index].timestamp;
01384 }
01385
01386
01387 if (avio_seek(s->pb, pos_min, SEEK_SET) < 0)
01388 return -1;
01389 avi->stream_index= -1;
01390 return 0;
01391 }
01392
01393 static int avi_read_close(AVFormatContext *s)
01394 {
01395 int i;
01396 AVIContext *avi = s->priv_data;
01397
01398 for(i=0;i<s->nb_streams;i++) {
01399 AVStream *st = s->streams[i];
01400 AVIStream *ast = st->priv_data;
01401 av_free(st->codec->palctrl);
01402 if (ast) {
01403 if (ast->sub_ctx) {
01404 av_freep(&ast->sub_ctx->pb);
01405 av_close_input_file(ast->sub_ctx);
01406 }
01407 av_free(ast->sub_buffer);
01408 av_free_packet(&ast->sub_pkt);
01409 }
01410 }
01411
01412 av_free(avi->dv_demux);
01413
01414 return 0;
01415 }
01416
01417 static int avi_probe(AVProbeData *p)
01418 {
01419 int i;
01420
01421
01422 for(i=0; avi_headers[i][0]; i++)
01423 if(!memcmp(p->buf , avi_headers[i] , 4) &&
01424 !memcmp(p->buf+8, avi_headers[i]+4, 4))
01425 return AVPROBE_SCORE_MAX;
01426
01427 return 0;
01428 }
01429
01430 AVInputFormat ff_avi_demuxer = {
01431 "avi",
01432 NULL_IF_CONFIG_SMALL("AVI format"),
01433 sizeof(AVIContext),
01434 avi_probe,
01435 avi_read_header,
01436 avi_read_packet,
01437 avi_read_close,
01438 avi_read_seek,
01439 .priv_class = &demuxer_class,
01440 };