XinZheng Zhang <zhangxzh...@gmail.com>于2016年7月20日 周三下午11:05写道:
> What are you meaning for the original mail? > > On Wed, Jul 20, 2016 at 10:24 PM, Steven Liu <lingjiujia...@gmail.com> > wrote: > > > > > > 2016-07-20 21:46 GMT+08:00 XinZheng Zhang <zhangxzh...@gmail.com>: > >> > >> There has an error when seeking in a flv file, which key frames was > >> sorted before video frame. > >> This ensures that all the key frames was cached, and add to > >> corresponding stream when it was created. > >> > >> On Wed, Jul 20, 2016 at 9:30 PM, zhangxinzheng <zhangxzh...@gmail.com> > >> wrote: > >> > From: Xinzheng Zhang <zhangxzh...@gmail.com> > >> > > >> > --- > >> > libavformat/flvdec.c | 52 > >> > +++++++++++++++++++++++++++++++++++++++++++++------- > >> > 1 file changed, 45 insertions(+), 7 deletions(-) > >> > > >> > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > >> > index 2bf1e05..8a73b68 100644 > >> > --- a/libavformat/flvdec.c > >> > +++ b/libavformat/flvdec.c > >> > @@ -30,6 +30,7 @@ > >> > #include "libavutil/opt.h" > >> > #include "libavutil/intfloat.h" > >> > #include "libavutil/mathematics.h" > >> > +#include "libavutil/mem.h" > >> > #include "libavcodec/bytestream.h" > >> > #include "libavcodec/mpeg4audio.h" > >> > #include "avformat.h" > >> > @@ -41,6 +42,12 @@ > >> > > >> > #define RESYNC_BUFFER_SIZE (1<<20) > >> > > >> > + > >> > +typedef struct FLVKeyFrame { > >> > + int64_t pos; > >> > + int64_t timestamp; > >> > +} FLVKeyFrame; > >> > + > >> > typedef struct FLVContext { > >> > const AVClass *class; ///< Class for private options. > >> > int trust_metadata; ///< configure streams according onMetaData > >> > @@ -61,6 +68,10 @@ typedef struct FLVContext { > >> > > >> > int broken_sizes; > >> > int sum_flv_tag_size; > >> > + > >> > + int head_flags; //r8 > >> > + FLVKeyFrame *keyframes; > >> > + int keyframe_count; > >> > } FLVContext; > >> > > >> > static int probe(AVProbeData *p, int live) > >> > @@ -95,6 +106,9 @@ static int live_flv_probe(AVProbeData *p) > >> > static AVStream *create_stream(AVFormatContext *s, int codec_type) > >> > { > >> > AVStream *st = avformat_new_stream(s, NULL); > >> > + FLVContext *flv = s->priv_data; > >> > + int flags = flv->head_flags; > >> > + int i = 0; > >> > if (!st) > >> > return NULL; > >> > st->codecpar->codec_type = codec_type; > >> > @@ -104,6 +118,17 @@ static AVStream *create_stream(AVFormatContext > *s, > >> > int codec_type) > >> > s->ctx_flags &= ~AVFMTCTX_NOHEADER; > >> > > >> > avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ > >> > + if ((!(flags & FLV_HEADER_FLAG_HASVIDEO) && codec_type == > >> > AVMEDIA_TYPE_AUDIO) || > >> > + (codec_type == AVMEDIA_TYPE_VIDEO) > >> > + ) { > >> > + for (; i < flv->keyframe_count; i++) { > >> > + FLVKeyFrame *keyframe = &flv->keyframes[i]; > >> > + av_add_index_entry(st, keyframe->pos, > keyframe->timestamp, > >> > + 0, 0, AVINDEX_KEYFRAME); > >> > + } > >> > + flv->keyframe_count = 0; > >> > + av_freep(&flv->keyframes); > >> > + } > >> > return st; > >> > } > >> > > >> > @@ -306,7 +331,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) > >> > + AVStream *vstream, AVStream > *astream, > >> > int64_t max_pos) > >> > { > >> > FLVContext *flv = s->priv_data; > >> > unsigned int timeslen = 0, fileposlen = 0, i; > >> > @@ -315,8 +340,12 @@ static int parse_keyframes_index(AVFormatContext > >> > *s, AVIOContext *ioc, > >> > int64_t *filepositions = NULL; > >> > int ret = AVERROR(ENOSYS); > >> > int64_t initial_pos = avio_tell(ioc); > >> > + int head_flags = flv->head_flags; > >> > + AVStream *kf_stream = vstream; > >> > + if (!kf_stream && astream && (!(head_flags & > >> > FLV_HEADER_FLAG_HASVIDEO) && (head_flags & FLV_HEADER_FLAG_HASAUDIO))) > >> > + kf_stream = astream; > >> > > >> > - if (vstream->nb_index_entries>0) { > >> > + if (kf_stream && kf_stream->nb_index_entries > 0) { > >> > av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n"); > >> > return 0; > >> > } > >> > @@ -369,8 +398,16 @@ static int parse_keyframes_index(AVFormatContext > >> > *s, AVIOContext *ioc, > >> > > >> > if (timeslen == fileposlen && fileposlen>1 && max_pos <= > >> > filepositions[0]) { > >> > for (i = 0; i < fileposlen; i++) { > >> > - av_add_index_entry(vstream, filepositions[i], times[i] * > >> > 1000, > >> > - 0, 0, AVINDEX_KEYFRAME); > >> > + if (kf_stream) { > >> > + av_add_index_entry(kf_stream, filepositions[i], > >> > times[i] * 1000, > >> > + 0, 0, AVINDEX_KEYFRAME); > >> > + } else { > >> > + FLVKeyFrame frame = {0}; > >> > + frame.pos = filepositions[i]; > >> > + frame.timestamp = times[i] * 1000; > >> > + av_dynarray2_add((void **)&flv->keyframes, > >> > &flv->keyframe_count,sizeof(FLVKeyFrame), (const uint8_t *)&frame); > >> > + } > >> > + > >> > if (i < 2) { > >> > flv->validate_index[i].pos = filepositions[i]; > >> > flv->validate_index[i].dts = times[i] * 1000; > >> > @@ -418,10 +455,10 @@ static int amf_parse_object(AVFormatContext *s, > >> > AVStream *astream, > >> > } > >> > break; > >> > case AMF_DATA_TYPE_OBJECT: > >> > - if ((vstream || astream) && key && > >> > + if (key && > >> > ioc->seekable && > >> > !strcmp(KEYFRAMES_TAG, key) && depth == 1) > >> > - if (parse_keyframes_index(s, ioc, vstream ? vstream : > >> > astream, > >> > + if (parse_keyframes_index(s, ioc, vstream, astream, > >> > max_pos) < 0) > >> > av_log(s, AV_LOG_ERROR, "Keyframe index parsing > >> > failed\n"); > >> > > >> > @@ -633,7 +670,7 @@ static int flv_read_header(AVFormatContext *s) > >> > int offset; > >> > > >> > avio_skip(s->pb, 4); > >> > - avio_r8(s->pb); // flags > >> > + flv->head_flags = avio_r8(s->pb); // flags > >> > > >> > s->ctx_flags |= AVFMTCTX_NOHEADER; > >> > > >> > @@ -653,6 +690,7 @@ static int flv_read_close(AVFormatContext *s) > >> > FLVContext *flv = s->priv_data; > >> > for (i=0; i<FLV_STREAM_TYPE_NB; i++) > >> > av_freep(&flv->new_extradata[i]); > >> > + av_freep(&flv->keyframes); > >> > return 0; > >> > } > >> > > >> > -- > >> > 2.5.4 (Apple Git-61) > >> > > > > > > > Where is the original mail? > I saw you sent a reply mail to this maillist and the patch in a original mail I mean you have sent a reply mail to mail list, the mail have no main mail? Perhaps you should send a new mail for the patch, not a reply mail. And please send mail to mail list Thanks Steven Liu _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel