avformat/ttaenc: buffer packets directly

This is a bit more robust in case of OOM.

Signed-off-by: James Almer <jamrial@gmail.com>
pull/272/head
James Almer 7 years ago
parent 9648cc6d7f
commit e97667c82f
  1. 42
      libavformat/ttaenc.c

@ -29,7 +29,7 @@
typedef struct TTAMuxContext { typedef struct TTAMuxContext {
AVIOContext *seek_table; AVIOContext *seek_table;
AVIOContext *data; AVPacketList *queue, *queue_end;
uint32_t nb_samples; uint32_t nb_samples;
int frame_size; int frame_size;
int last_frame; int last_frame;
@ -56,10 +56,6 @@ static int tta_write_header(AVFormatContext *s)
if ((ret = avio_open_dyn_buf(&tta->seek_table)) < 0) if ((ret = avio_open_dyn_buf(&tta->seek_table)) < 0)
return ret; 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 /* Ignore most extradata information if present. It can be innacurate
if for example remuxing from Matroska */ 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) static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
{ {
TTAMuxContext *tta = s->priv_data; 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); avio_wl32(tta->seek_table, pkt->size);
tta->nb_samples += pkt->duration; tta->nb_samples += pkt->duration;
@ -106,6 +117,21 @@ static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
return 0; 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) static int tta_write_trailer(AVFormatContext *s)
{ {
TTAMuxContext *tta = s->priv_data; TTAMuxContext *tta = s->priv_data;
@ -125,9 +151,7 @@ static int tta_write_trailer(AVFormatContext *s)
av_free(ptr); av_free(ptr);
/* Write audio data */ /* Write audio data */
size = avio_close_dyn_buf(tta->data, &ptr); tta_queue_flush(s);
avio_write(s->pb, ptr, size);
av_free(ptr);
ff_ape_write_tag(s); ff_ape_write_tag(s);
avio_flush(s->pb); avio_flush(s->pb);

Loading…
Cancel
Save