]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/ttaenc.c
avformat/hlsenc: fix write wrong init file URI string problem
[ffmpeg] / libavformat / ttaenc.c
index fdce1e3dc1c0fb65f436dd8a76509ef8925df26c..add15873d048fffc647d9fd88581550a1b239974 100644 (file)
 
 typedef struct TTAMuxContext {
     AVIOContext *seek_table;
-    AVIOContext *data;
+    AVPacketList *queue, *queue_end;
     uint32_t nb_samples;
     int frame_size;
     int last_frame;
 } TTAMuxContext;
 
-static int tta_write_header(AVFormatContext *s)
+static int tta_init(AVFormatContext *s)
 {
     TTAMuxContext *tta = s->priv_data;
-    AVCodecParameters *par = s->streams[0]->codecpar;
-    int ret;
+    AVCodecParameters *par;
 
     if (s->nb_streams != 1) {
         av_log(s, AV_LOG_ERROR, "Only one stream is supported\n");
         return AVERROR(EINVAL);
     }
+    par = s->streams[0]->codecpar;
+
     if (par->codec_id != AV_CODEC_ID_TTA) {
         av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
         return AVERROR(EINVAL);
@@ -54,12 +55,25 @@ static int tta_write_header(AVFormatContext *s)
         return AVERROR_INVALIDDATA;
     }
 
+    /* Prevent overflow */
+    if (par->sample_rate > 0x7FFFFFu) {
+        av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
+        return AVERROR(EINVAL);
+    }
+    tta->frame_size = par->sample_rate * 256 / 245;
+    avpriv_set_pts_info(s->streams[0], 64, 1, par->sample_rate);
+
+    return 0;
+}
+
+static int tta_write_header(AVFormatContext *s)
+{
+    TTAMuxContext *tta = s->priv_data;
+    AVCodecParameters *par = s->streams[0]->codecpar;
+    int ret;
+
     if ((ret = avio_open_dyn_buf(&tta->seek_table)) < 0)
         return ret;
-    if ((ret = avio_open_dyn_buf(&tta->data)) < 0) {
-        ffio_free_dyn_buf(&tta->seek_table);
-        return ret;
-    }
 
     /* Ignore most extradata information if present. It can be innacurate
        if for example remuxing from Matroska */
@@ -70,13 +84,6 @@ static int tta_write_header(AVFormatContext *s)
     avio_wl16(s->pb, par->channels);
     avio_wl16(s->pb, par->bits_per_raw_sample);
     avio_wl32(s->pb, par->sample_rate);
-    /* Prevent overflow */
-    if (par->sample_rate > 0x7FFFFFu) {
-        av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
-        return AVERROR(EINVAL);
-    }
-    tta->frame_size = par->sample_rate * 256 / 245;
-    avpriv_set_pts_info(s->streams[0], 64, 1, par->sample_rate);
 
     return 0;
 }
@@ -84,8 +91,23 @@ static int tta_write_header(AVFormatContext *s)
 static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     TTAMuxContext *tta = s->priv_data;
+    AVPacketList *pktl = av_mallocz(sizeof(*pktl));
+    int ret;
+
+    if (!pktl)
+        return AVERROR(ENOMEM);
+
+    ret = av_packet_ref(&pktl->pkt, pkt);
+    if (ret < 0) {
+        av_free(pktl);
+        return ret;
+    }
+    if (tta->queue_end)
+        tta->queue_end->next = pktl;
+    else
+        tta->queue = pktl;
+    tta->queue_end = pktl;
 
-    avio_write(tta->data, pkt->data, pkt->size);
     avio_wl32(tta->seek_table, pkt->size);
     tta->nb_samples += pkt->duration;
 
@@ -106,6 +128,21 @@ static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
     return 0;
 }
 
+static void tta_queue_flush(AVFormatContext *s)
+{
+    TTAMuxContext *tta = s->priv_data;
+    AVPacketList *pktl;
+
+    while (pktl = tta->queue) {
+        AVPacket *pkt = &pktl->pkt;
+        avio_write(s->pb, pkt->data, pkt->size);
+        av_packet_unref(pkt);
+        tta->queue = pktl->next;
+        av_free(pktl);
+    }
+    tta->queue_end = NULL;
+}
+
 static int tta_write_trailer(AVFormatContext *s)
 {
     TTAMuxContext *tta = s->priv_data;
@@ -125,9 +162,7 @@ static int tta_write_trailer(AVFormatContext *s)
     av_free(ptr);
 
     /* Write audio data */
-    size = avio_close_dyn_buf(tta->data, &ptr);
-    avio_write(s->pb, ptr, size);
-    av_free(ptr);
+    tta_queue_flush(s);
 
     ff_ape_write_tag(s);
     avio_flush(s->pb);
@@ -143,6 +178,7 @@ AVOutputFormat ff_tta_muxer = {
     .priv_data_size    = sizeof(TTAMuxContext),
     .audio_codec       = AV_CODEC_ID_TTA,
     .video_codec       = AV_CODEC_ID_NONE,
+    .init              = tta_init,
     .write_header      = tta_write_header,
     .write_packet      = tta_write_packet,
     .write_trailer     = tta_write_trailer,