]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/utils.c
Merge commit '32d05934abc7427bb90380a4c1ab20a15fd7d821'
[ffmpeg] / libavformat / utils.c
index 10508f6ab751ad77df1c10a39f54c1c9d5d70a35..ac82dc63a158fe0632d715926fa65f39d754cbdd 100644 (file)
@@ -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)
@@ -1526,10 +1536,29 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
             }
             st->skip_samples = 0;
         }
-    }
 
-    if (ret >= 0 && !(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
-        av_packet_merge_side_data(pkt);
+        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;
+
+                if (av_packet_get_side_data(pkt, src_sd->type, NULL))
+                    continue;
+
+                dst_data = av_packet_new_side_data(pkt, src_sd->type, src_sd->size);
+                if (!dst_data) {
+                    av_log(s, AV_LOG_WARNING, "Could not inject global side data\n");
+                    continue;
+                }
+
+                memcpy(dst_data, src_sd->data, src_sd->size);
+            }
+            st->inject_global_side_data = 0;
+        }
+
+        if (!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
+            av_packet_merge_side_data(pkt);
+    }
 
     if (s->debug & FF_FDEBUG_TS)
         av_log(s, AV_LOG_DEBUG,
@@ -1697,6 +1726,9 @@ void ff_read_frame_flush(AVFormatContext *s)
 
         for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
             st->pts_buffer[j] = AV_NOPTS_VALUE;
+
+        if (s->internal->inject_global_side_data)
+            st->inject_global_side_data = 1;
     }
 }
 
@@ -2451,7 +2483,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
             st->first_dts == AV_NOPTS_VALUE &&
             st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN)
             av_log(st->codec, AV_LOG_WARNING,
-                   "start time is not set in estimate_timings_from_pts\n");
+                   "start time for stream %d is not set in estimate_timings_from_pts\n", i);
 
         if (st->parser) {
             av_parser_close(st->parser);
@@ -3546,6 +3578,8 @@ void avformat_free_context(AVFormatContext *s)
     av_opt_free(s);
     if (s->iformat && s->iformat->priv_class && s->priv_data)
         av_opt_free(s->priv_data);
+    if (s->oformat && s->oformat->priv_class && s->priv_data)
+        av_opt_free(s->priv_data);
 
     for (i = s->nb_streams - 1; i >= 0; i--) {
         ff_free_stream(s, s->streams[i]);
@@ -3667,6 +3701,8 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
     st->info->fps_first_dts = AV_NOPTS_VALUE;
     st->info->fps_last_dts  = AV_NOPTS_VALUE;
 
+    st->inject_global_side_data = s->internal->inject_global_side_data;
+
     s->streams[s->nb_streams++] = st;
     return st;
 }