Index: libavformat/flvdec.c =================================================================== --- libavformat/flvdec.c (revision 7375) +++ libavformat/flvdec.c (working copy) @@ -364,14 +364,88 @@ return 0; } +static int64_t find_framestart(ByteIOContext *bc, AVStream *st, int64_t pos, int is_last){ + unsigned int cur, ncur, psize, size; + int type, flags; + int64_t pts; + + url_fseek(bc, pos, SEEK_SET); + +retry: + + if(pos != 11){ + psize = get_be24(bc); + while(!url_feof(bc)){ + cur = url_ftell(bc); + psize = ((psize&0xffffff)<<8) | get_byte(bc); + if(psize > cur) + continue; + url_fseek(bc, -(int64_t)psize+11-4-15+5, SEEK_CUR); + size = get_be24(bc); + url_fseek(bc, cur + 1, SEEK_SET); + if(psize-11 == size) + break; + } + }else + url_fskip(bc, 4); + + ncur = url_ftell(bc); + + while(!url_feof(bc)){ + type = get_byte(bc); + size = get_be24(bc); + if (type != FLV_TAG_TYPE_AUDIO && type != FLV_TAG_TYPE_VIDEO){ + url_fseek(bc, size + 7, SEEK_CUR); + psize = get_be32(bc); + if(psize-11 != size){ + url_fseek(bc, ncur, SEEK_SET); + goto retry; + } + continue; + } + pts = get_be24(bc); + if (url_feof(bc)) + return AV_NOPTS_VALUE; + if(!is_last) + return pts; + url_fskip(bc, 4); + flags = get_byte(bc); + if ((flags & FLV_VIDEO_FRAMETYPE_MASK) != FLV_FRAME_KEY){ + url_fseek(bc, size - 1, SEEK_CUR); + psize = get_be32(bc); + if(psize-11 != size){ + url_fseek(bc, ncur, SEEK_SET); + goto retry; + } + continue; + } + av_add_index_entry(st, url_ftell(bc)-16, pts, size, 0, AVINDEX_KEYFRAME); + return pts; + } + + return AV_NOPTS_VALUE; +} + +static int64_t flv_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit){ + unsigned int size; + int64_t pts; + + size = url_fsize(&s->pb); + pts = find_framestart(&s->pb, s->streams[stream_index], *pos_arg, 0); + if(pts == AV_NOPTS_VALUE) + return AV_NOPTS_VALUE; + *pos_arg = url_ftell(&s->pb) - 11; + return pts; +} + static int flv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - AVStream *st = s->streams[stream_index]; - int index = av_index_search_timestamp(st, timestamp, flags); - if (index < 0) + int64_t pts; + if(av_seek_frame_binary(s, stream_index, timestamp, flags) < 0) return -1; - url_fseek(&s->pb, st->index_entries[index].pos, SEEK_SET); - + pts = find_framestart(&s->pb, s->streams[stream_index], url_ftell(&s->pb), 1); + if(pts != AV_NOPTS_VALUE) + url_fseek(&s->pb, -16, SEEK_CUR); return 0; } @@ -384,6 +458,7 @@ flv_read_packet, flv_read_close, flv_read_seek, + flv_read_timestamp, .extensions = "flv", .value = CODEC_ID_FLV1, };