Browse code

avformat: add av_format_inject_global_side_data(), and disable it by default

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@gmx.at>

Michael Niedermayer authored on 2014/04/14 02:20:17
Showing 5 changed files
... ...
@@ -15,6 +15,9 @@ libavutil:     2012-10-22
15 15
 
16 16
 API changes, most recent first:
17 17
 
18
+2014-04-XX - xxxxxxx - lavf xx.xx.1xx - avformat.h
19
+  Add av_format_inject_global_side_data()
20
+
18 21
 2014-04-12 - xxxxxxx - lavu 52.76.100 - log.h
19 22
   Add av_log_get_flags()
20 23
 
... ...
@@ -2752,6 +2752,8 @@ static int read_thread(void *arg)
2752 2752
     if (genpts)
2753 2753
         ic->flags |= AVFMT_FLAG_GENPTS;
2754 2754
 
2755
+    av_format_inject_global_side_data(ic);
2756
+
2755 2757
     opts = setup_find_stream_info_opts(ic, codec_opts);
2756 2758
     orig_nb_streams = ic->nb_streams;
2757 2759
 
... ...
@@ -862,6 +862,8 @@ typedef struct AVStream {
862 862
      * - muxing: May be set by the caller before avformat_write_header().
863 863
      *
864 864
      * Freed by libavformat in avformat_free_context().
865
+     *
866
+     * @see av_format_inject_global_side_data()
865 867
      */
866 868
     AVPacketSideData *side_data;
867 869
     /**
... ...
@@ -1043,7 +1045,7 @@ typedef struct AVStream {
1043 1043
     /**
1044 1044
      * Internal data to inject global side data
1045 1045
      */
1046
-    int global_side_data_injected;
1046
+    int inject_global_side_data;
1047 1047
 
1048 1048
 } AVStream;
1049 1049
 
... ...
@@ -1613,6 +1615,12 @@ av_format_control_message av_format_get_control_message_cb(const AVFormatContext
1613 1613
 void      av_format_set_control_message_cb(AVFormatContext *s, av_format_control_message callback);
1614 1614
 
1615 1615
 /**
1616
+ * This function will cause global side data to be injected in the next packet
1617
+ * of each stream as well as after any subsequent seek.
1618
+ */
1619
+void av_format_inject_global_side_data(AVFormatContext *s);
1620
+
1621
+/**
1616 1622
  * Returns the method used to set ctx->duration.
1617 1623
  *
1618 1624
  * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE.
... ...
@@ -52,6 +52,8 @@ struct AVFormatInternal {
52 52
      * Muxing only.
53 53
      */
54 54
     int nb_interleaved_streams;
55
+
56
+    int inject_global_side_data;
55 57
 };
56 58
 
57 59
 #ifdef __GNUC__
... ...
@@ -110,6 +110,16 @@ MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding)
110 110
 MAKE_ACCESSORS(AVFormatContext, format, void *, opaque)
111 111
 MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb)
112 112
 
113
+void av_format_inject_global_side_data(AVFormatContext *s)
114
+{
115
+    int i;
116
+    s->internal->inject_global_side_data = 1;
117
+    for (i = 0; i < s->nb_streams; i++) {
118
+        AVStream *st = s->streams[i];
119
+        st->inject_global_side_data = 1;
120
+    }
121
+}
122
+
113 123
 static AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
114 124
 {
115 125
     if (st->codec->codec)
... ...
@@ -1527,7 +1537,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
1527 1527
             st->skip_samples = 0;
1528 1528
         }
1529 1529
 
1530
-        if (!st->global_side_data_injected) {
1530
+        if (st->inject_global_side_data) {
1531 1531
             for (i = 0; i < st->nb_side_data; i++) {
1532 1532
                 AVPacketSideData *src_sd = &st->side_data[i];
1533 1533
                 uint8_t *dst_data;
... ...
@@ -1543,7 +1553,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
1543 1543
 
1544 1544
                 memcpy(dst_data, src_sd->data, src_sd->size);
1545 1545
             }
1546
-            st->global_side_data_injected = 1;
1546
+            st->inject_global_side_data = 0;
1547 1547
         }
1548 1548
 
1549 1549
         if (!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
... ...
@@ -1717,7 +1727,8 @@ void ff_read_frame_flush(AVFormatContext *s)
1717 1717
         for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
1718 1718
             st->pts_buffer[j] = AV_NOPTS_VALUE;
1719 1719
 
1720
-        st->global_side_data_injected = 0;
1720
+        if (s->internal->inject_global_side_data)
1721
+            st->inject_global_side_data = 1;
1721 1722
     }
1722 1723
 }
1723 1724
 
... ...
@@ -3690,6 +3701,8 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
3690 3690
     st->info->fps_first_dts = AV_NOPTS_VALUE;
3691 3691
     st->info->fps_last_dts  = AV_NOPTS_VALUE;
3692 3692
 
3693
+    st->inject_global_side_data = s->internal->inject_global_side_data;
3694
+
3693 3695
     s->streams[s->nb_streams++] = st;
3694 3696
     return st;
3695 3697
 }