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

Steven Liu lingjiujianke at gmail.com
Wed Jul 20 18:12:48 EEST 2016


XinZheng Zhang <zhangxzheng at 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 <lingjiujianke at gmail.com>
> wrote:
> >
> >
> > 2016-07-20 21:46 GMT+08:00 XinZheng Zhang <zhangxzheng at 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 <zhangxzheng at gmail.com>
> >> wrote:
> >> > From: Xinzheng Zhang <zhangxzheng at 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


More information about the ffmpeg-devel mailing list