segment: Properly create new AVStreams for the chained muxer
authorMartin Storsjö <martin@martin.st>
Sat, 25 Feb 2012 23:39:32 +0000 (01:39 +0200)
committerMartin Storsjö <martin@martin.st>
Thu, 4 Oct 2012 10:52:09 +0000 (13:52 +0300)
Before, the chained muxer reused the AVStreams array from
the outer muxer, which made it impossible to use the proper
public functions (such as av_write_frame) when calling the
chained muxer.

Signed-off-by: Martin Storsjö <martin@martin.st>
libavformat/segment.c

index e6dafe3..ccd8a91 100644 (file)
@@ -147,8 +147,15 @@ static int seg_write_header(AVFormatContext *s)
     oc->interrupt_callback = s->interrupt_callback;
     seg->avf = oc;
 
-    oc->streams = s->streams;
-    oc->nb_streams = s->nb_streams;
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st;
+        if (!(st = avformat_new_stream(oc, NULL))) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        avcodec_copy_context(st->codec, s->streams[i]->codec);
+        st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+    }
 
     if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
                               s->filename, seg->number++) < 0) {
@@ -172,8 +179,6 @@ static int seg_write_header(AVFormatContext *s)
 
 fail:
     if (ret) {
-        oc->streams = NULL;
-        oc->nb_streams = 0;
         if (seg->list)
             avio_close(seg->pb);
         avformat_free_context(oc);
@@ -185,7 +190,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
-    AVStream *st = oc->streams[pkt->stream_index];
+    AVStream *st = s->streams[pkt->stream_index];
     int64_t end_pts = seg->recording_time * seg->number;
     int ret;
 
@@ -217,12 +222,10 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
         }
     }
 
-    ret = oc->oformat->write_packet(oc, pkt);
+    ret = ff_write_chained(oc, pkt->stream_index, pkt, s);
 
 fail:
     if (ret < 0) {
-        oc->streams = NULL;
-        oc->nb_streams = 0;
         if (seg->list)
             avio_close(seg->pb);
         avformat_free_context(oc);
@@ -238,8 +241,6 @@ static int seg_write_trailer(struct AVFormatContext *s)
     int ret = segment_end(oc);
     if (seg->list)
         avio_close(seg->pb);
-    oc->streams = NULL;
-    oc->nb_streams = 0;
     avformat_free_context(oc);
     return ret;
 }