avformat/cafenc: Fix memleak when trailer is never written

Do this by using the AVStream's priv_data for the buffer holding
the packet size data.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2021-09-23 04:09:59 +02:00
parent 19a6b51fe6
commit d94b641b4a
1 changed files with 8 additions and 9 deletions

View File

@ -30,7 +30,6 @@
typedef struct { typedef struct {
int64_t data; int64_t data;
uint8_t *pkt_sizes;
int size_buffer_size; int size_buffer_size;
int size_entries_used; int size_entries_used;
int packets; int packets;
@ -209,25 +208,26 @@ static int caf_write_header(AVFormatContext *s)
static int caf_write_packet(AVFormatContext *s, AVPacket *pkt) static int caf_write_packet(AVFormatContext *s, AVPacket *pkt)
{ {
CAFContext *caf = s->priv_data; CAFContext *caf = s->priv_data;
AVStream *const st = s->streams[0];
if (!s->streams[0]->codecpar->block_align) { if (!st->codecpar->block_align) {
void *pkt_sizes; uint8_t *pkt_sizes;
int i, alloc_size = caf->size_entries_used + 5U; int i, alloc_size = caf->size_entries_used + 5U;
if (alloc_size < 0) if (alloc_size < 0)
return AVERROR(ERANGE); return AVERROR(ERANGE);
pkt_sizes = av_fast_realloc(caf->pkt_sizes, pkt_sizes = av_fast_realloc(st->priv_data,
&caf->size_buffer_size, &caf->size_buffer_size,
alloc_size); alloc_size);
if (!pkt_sizes) if (!pkt_sizes)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
caf->pkt_sizes = pkt_sizes; st->priv_data = pkt_sizes;
for (i = 4; i > 0; i--) { for (i = 4; i > 0; i--) {
unsigned top = pkt->size >> i * 7; unsigned top = pkt->size >> i * 7;
if (top) if (top)
caf->pkt_sizes[caf->size_entries_used++] = 128 | top; pkt_sizes[caf->size_entries_used++] = 128 | top;
} }
caf->pkt_sizes[caf->size_entries_used++] = pkt->size & 127; pkt_sizes[caf->size_entries_used++] = pkt->size & 127;
caf->packets++; caf->packets++;
} }
avio_write(s->pb, pkt->data, pkt->size); avio_write(s->pb, pkt->data, pkt->size);
@ -260,10 +260,9 @@ static int caf_write_trailer(AVFormatContext *s)
avio_wb64(pb, caf->packets * packet_size); ///< mNumberValidFrames avio_wb64(pb, caf->packets * packet_size); ///< mNumberValidFrames
avio_wb32(pb, 0); ///< mPrimingFrames avio_wb32(pb, 0); ///< mPrimingFrames
avio_wb32(pb, 0); ///< mRemainderFrames avio_wb32(pb, 0); ///< mRemainderFrames
avio_write(pb, caf->pkt_sizes, caf->size_entries_used); avio_write(pb, st->priv_data, caf->size_entries_used);
} }
} }
av_freep(&caf->pkt_sizes);
return 0; return 0;
} }