aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/ttaenc.c
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2017-11-20 16:16:11 -0300
committerJames Almer <jamrial@gmail.com>2017-11-24 15:05:35 -0300
commite97667c82f4c3ed813269383f8ea825ffb96204f (patch)
tree83d63431c6baa6c2893bead96bb982f9b04a324a /libavformat/ttaenc.c
parent9648cc6d7fdbb0a260bed1e3e23300569cff9579 (diff)
downloadffmpeg-e97667c82f4c3ed813269383f8ea825ffb96204f.tar.gz
avformat/ttaenc: buffer packets directly
This is a bit more robust in case of OOM. Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavformat/ttaenc.c')
-rw-r--r--libavformat/ttaenc.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/libavformat/ttaenc.c b/libavformat/ttaenc.c
index fdce1e3dc1..b05705b6b6 100644
--- a/libavformat/ttaenc.c
+++ b/libavformat/ttaenc.c
@@ -29,7 +29,7 @@
typedef struct TTAMuxContext {
AVIOContext *seek_table;
- AVIOContext *data;
+ AVPacketList *queue, *queue_end;
uint32_t nb_samples;
int frame_size;
int last_frame;
@@ -56,10 +56,6 @@ static int tta_write_header(AVFormatContext *s)
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 */
@@ -84,8 +80,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 +117,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 +151,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);