diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-02-28 06:38:58 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-02-28 06:38:58 +0400 |
commit | e3822886ebb3ae97bdae9be264d891f1d35c960b (patch) | |
tree | 0debfb9843f9a8b56454a1bbe9b679827e9c2615 /libavformat/flvdec.c | |
parent | f1808e304834304122ebce9325eb997a673a9dc2 (diff) | |
parent | d10319d87f7f408dc69e1540498e87e2860e945d (diff) |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
avcodec_default_reget_buffer(): fix compilation in DEBUG mode
fate: Overhaul WavPack coverage
h264: fix mmxext chroma deblock to use correct TC values.
flvdec: Remove the now redundant check for known broken metadata creator
flvdec: Validate index entries added from metadata while reading
rtsp: Handle requests from server to client
movenc: use timestamps instead of frame_size for samples-per-packet
movenc: use the first cluster duration as the tfhd default duration
movenc: factorize calculation of cluster duration into a separate function
doc/APIchanges: fill in missing dates and hashes.
lavc: reorder AVCodecContext fields.
lavc: reorder AVFrame fields.
Conflicts:
doc/APIchanges
libavcodec/avcodec.h
libavformat/flvdec.c
libavformat/movenc.c
tests/fate/lossless-audio.mak
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/flvdec.c')
-rw-r--r-- | libavformat/flvdec.c | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index bbc71636f1..8ae79501b4 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -35,12 +35,20 @@ #include "avio_internal.h" #include "flv.h" +#define VALIDATE_INDEX_TS_THRESH 2500 + typedef struct { int wrong_dts; ///< wrong dts due to negative cts uint8_t *new_extradata[FLV_STREAM_TYPE_NB]; int new_extradata_size[FLV_STREAM_TYPE_NB]; int last_sample_rate; int last_channels; + struct { + int64_t dts; + int64_t pos; + } validate_index[2]; + int validate_next; + int validate_count; } FLVContext; static int flv_probe(AVProbeData *p) @@ -137,6 +145,7 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) { } static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) { + FLVContext *flv = s->priv_data; unsigned int timeslen = 0, fileposlen = 0, i; char str_val[256]; int64_t *times = NULL; @@ -192,18 +201,15 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream } if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { - int64_t av_unused dts, size0, size1; - avio_seek(ioc, filepositions[1]-4, SEEK_SET); - size0 = avio_rb32(ioc); - avio_r8(ioc); - size1 = avio_rb24(ioc); - dts = avio_rb24(ioc); - dts |= avio_r8(ioc) << 24; - if (size0 > filepositions[1] || FFABS(dts - times[1]*1000)>5000/*arbitraray threshold to detect invalid index*/) - goto invalid; - for(i = 0; i < timeslen; i++) + for (i = 0; i < fileposlen; i++) { av_add_index_entry(vstream, filepositions[i], times[i]*1000, 0, 0, AVINDEX_KEYFRAME); + if (i < 2) { + flv->validate_index[i].pos = filepositions[i]; + flv->validate_index[i].dts = times[i] * 1000; + flv->validate_count = i + 1; + } + } } else { invalid: av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n"); @@ -444,6 +450,22 @@ static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream, return 0; } +static void clear_index_entries(AVFormatContext *s, int64_t pos) +{ + int i, j, out; + av_log(s, AV_LOG_WARNING, "Found invalid index entries, clearing the index.\n"); + for (i = 0; i < s->nb_streams; i++) { + AVStream *st = s->streams[i]; + /* Remove all index entries that point to >= pos */ + out = 0; + for (j = 0; j < st->nb_index_entries; j++) { + if (st->index_entries[j].pos < pos) + st->index_entries[out++] = st->index_entries[j]; + } + st->nb_index_entries = out; + } +} + static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) { FLVContext *flv = s->priv_data; @@ -467,6 +489,22 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) avio_skip(s->pb, 3); /* stream id, always 0 */ flags = 0; + if (flv->validate_next < flv->validate_count) { + int64_t validate_pos = flv->validate_index[flv->validate_next].pos; + if (pos == validate_pos) { + if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <= + VALIDATE_INDEX_TS_THRESH) { + flv->validate_next++; + } else { + clear_index_entries(s, validate_pos); + flv->validate_count = 0; + } + } else if (pos > validate_pos) { + clear_index_entries(s, validate_pos); + flv->validate_count = 0; + } + } + if(size == 0) continue; @@ -654,6 +692,8 @@ leave: static int flv_read_seek(AVFormatContext *s, int stream_index, int64_t ts, int flags) { + FLVContext *flv = s->priv_data; + flv->validate_count = 0; return avio_seek_time(s->pb, stream_index, ts, flags); } |