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

Michael Niedermayer michaelni at gmx.at
Sun Apr 13 19:35:21 CEST 2014


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>
---
 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;
+    }
+}
+
 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;
     }
 }
 
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list