[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