[FFmpeg-devel] [PATCH] avformat/fivdec: cached keyframes before video or audio stream was created

XinZheng Zhang zhangxzheng at gmail.com
Mon Jul 25 12:34:58 EEST 2016


On Mon, Jul 25, 2016 at 4:41 PM, Michael Niedermayer
<michael at 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 at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>


More information about the ffmpeg-devel mailing list