[FFmpeg-devel] [PATCH] avformat: add av_format_inject_global_side_data(), and disable it by default

wm4 nfxjfg at googlemail.com
Sun Apr 13 19:42:49 CEST 2014


On Sun, 13 Apr 2014 19:35:21 +0200
Michael Niedermayer <michaelni at gmx.at> wrote:

> After this commit applications needs to call av_format_inject_global_side_data()
> or handle AVStream side data by some other means if they want it not to be lost.
> 
> This fixes a API incompatibility with libav.
> libav API does not allow the data to be passed through AVPackets
> 
> Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> ---

Sounds somewhat ok.

>  doc/APIchanges         |    3 +++
>  ffplay.c               |    2 ++
>  libavformat/avformat.h |   10 +++++++++-
>  libavformat/internal.h |    2 ++
>  libavformat/utils.c    |   17 ++++++++++++++---
>  5 files changed, 30 insertions(+), 4 deletions(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index a53647f..4cf922b 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -15,6 +15,9 @@ libavutil:     2012-10-22
>  
>  API changes, most recent first:
>  
> +2014-04-XX - xxxxxxx - lavf xx.xx.1xx - avformat.h
> +  Add av_format_inject_global_side_data()
> +
>  2014-04-12 - xxxxxxx - lavu 52.76.100 - log.h
>    Add av_log_get_flags()
>  
> diff --git a/ffplay.c b/ffplay.c
> index c86f94f..86b9126 100644
> --- a/ffplay.c
> +++ b/ffplay.c
> @@ -2752,6 +2752,8 @@ static int read_thread(void *arg)
>      if (genpts)
>          ic->flags |= AVFMT_FLAG_GENPTS;
>  
> +    av_format_inject_global_side_data(ic);
> +
>      opts = setup_find_stream_info_opts(ic, codec_opts);
>      orig_nb_streams = ic->nb_streams;
>  
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index ebebb3f..a1185ca 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -862,6 +862,8 @@ typedef struct AVStream {
>       * - muxing: May be set by the caller before avformat_write_header().
>       *
>       * Freed by libavformat in avformat_free_context().
> +     *
> +     * @see av_format_inject_global_side_data()
>       */
>      AVPacketSideData *side_data;
>      /**
> @@ -1043,7 +1045,7 @@ typedef struct AVStream {
>      /**
>       * Internal data to inject global side data
>       */
> -    int global_side_data_injected;
> +    int inject_global_side_data;
>  
>  } AVStream;
>  
> @@ -1613,6 +1615,12 @@ av_format_control_message av_format_get_control_message_cb(const AVFormatContext
>  void      av_format_set_control_message_cb(AVFormatContext *s, av_format_control_message callback);
>  
>  /**
> + * This function will cause global side data to be injected in the next packet
> + * of each stream as well as after any subsequent seek.
> + */
> +void av_format_inject_global_side_data(AVFormatContext *s);
> +
> +/**
>   * Returns the method used to set ctx->duration.
>   *
>   * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE.
> diff --git a/libavformat/internal.h b/libavformat/internal.h
> index f19cebf..e9e9293 100644
> --- a/libavformat/internal.h
> +++ b/libavformat/internal.h
> @@ -52,6 +52,8 @@ struct AVFormatInternal {
>       * Muxing only.
>       */
>      int nb_interleaved_streams;
> +
> +    int inject_global_side_data;
>  };
>  
>  #ifdef __GNUC__
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 2014577..8105ecf 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -110,6 +110,16 @@ MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding)
>  MAKE_ACCESSORS(AVFormatContext, format, void *, opaque)
>  MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb)
>  
> +void av_format_inject_global_side_data(AVFormatContext *s)
> +{
> +    int i;
> +    s->internal->inject_global_side_data = 1;
> +    for (i = 0; i < s->nb_streams; i++) {
> +        AVStream *st = s->streams[i];
> +        st->inject_global_side_data = 1;
> +    }
> +}

What about streams that are added later? Or is ff_read_frame_flush
called on new streams?

>  static AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
>  {
>      if (st->codec->codec)
> @@ -1527,7 +1537,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
>              st->skip_samples = 0;
>          }
>  
> -        if (!st->global_side_data_injected) {
> +        if (st->inject_global_side_data) {
>              for (i = 0; i < st->nb_side_data; i++) {
>                  AVPacketSideData *src_sd = &st->side_data[i];
>                  uint8_t *dst_data;
> @@ -1543,7 +1553,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
>  
>                  memcpy(dst_data, src_sd->data, src_sd->size);
>              }
> -            st->global_side_data_injected = 1;
> +            st->inject_global_side_data = 0;
>          }
>  
>          if (!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
> @@ -1717,7 +1727,8 @@ void ff_read_frame_flush(AVFormatContext *s)
>          for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
>              st->pts_buffer[j] = AV_NOPTS_VALUE;
>  
> -        st->global_side_data_injected = 0;
> +        if (s->internal->inject_global_side_data)
> +            st->inject_global_side_data = 1;
>      }
>  }
>  



More information about the ffmpeg-devel mailing list