diff options
author | James Almer <jamrial@gmail.com> | 2017-11-20 16:16:11 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2017-11-24 15:05:35 -0300 |
commit | e97667c82f4c3ed813269383f8ea825ffb96204f (patch) | |
tree | 83d63431c6baa6c2893bead96bb982f9b04a324a /libavformat | |
parent | 9648cc6d7fdbb0a260bed1e3e23300569cff9579 (diff) | |
download | ffmpeg-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')
-rw-r--r-- | libavformat/ttaenc.c | 42 |
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); |