On Mon, Jul 25, 2016 at 4:41 PM, Michael Niedermayer <mich...@niedermayer.cc> wrote: > On Thu, Jul 21, 2016 at 10:36:20AM +0800, Xinzheng Zhang wrote: >> --- >> libavformat/flvdec.c | 51 >> ++++++++++++++++++++++++++++++++++++++++++++------- >> 1 file changed, 44 insertions(+), 7 deletions(-) >> >> diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c >> index 2bf1e05..b4fb4e2 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,11 @@ >> >> #define RESYNC_BUFFER_SIZE (1<<20) >> >> +typedef struct FLVKeyFrame { >> + int64_t pos; >> + int64_t timestamp; >> +} FLVKeyFrame; > > instead of adding a 3rd array the local arrays from parse_keyframes_index() > could be moved into the context. That would reduce the memory needed >
ok > It also may be needed to keep 2 sets that is one per stream > and the arrays should be freed after their use > > Is that mean we need to call av_add_index_entry() for both stream? >> + >> typedef struct FLVContext { >> const AVClass *class; ///< Class for private options. >> int trust_metadata; ///< configure streams according onMetaData >> @@ -61,6 +67,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 +105,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 +117,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 +330,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 +339,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 +397,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 +454,10 @@ static int amf_parse_object(AVFormatContext *s, >> AVStream *astream, > > maybe the filepositions/times -> av_add_index_entry() code can be > split out of parse_keyframes_index() in a seperate patch > > that way parse_keyframes_index() would always do the same and not > depend on a stream while the 2nd part would be called once a > strea and index is available > ok > thanks > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > It is dangerous to be right in matters on which the established authorities > are wrong. -- Voltaire > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel