diff options
author | Niklas Haas <git@haasn.dev> | 2021-12-13 13:26:34 +0100 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2021-12-19 15:58:12 +0100 |
commit | e7fbc86d58baffc2e9aa5967bf93c94c2cfca43a (patch) | |
tree | 128ae8095e076e5f6d2c64615c887184ef6df959 /audio | |
parent | 85a45573698598bb4602ec248fa92f2d03fda162 (diff) | |
download | mpv-e7fbc86d58baffc2e9aa5967bf93c94c2cfca43a.tar.bz2 mpv-e7fbc86d58baffc2e9aa5967bf93c94c2cfca43a.tar.xz |
af_lavcac3enc: fix memory leak on no-op
Simply returning out of this function leaks avpkt, need to always "goto
done".
Rewrite the logic a bit to make it more clear what's going on (IMO).
Fixes #9593
Diffstat (limited to 'audio')
-rw-r--r-- | audio/filter/af_lavcac3enc.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/audio/filter/af_lavcac3enc.c b/audio/filter/af_lavcac3enc.c index 45e0aa64a2..78bfefab5d 100644 --- a/audio/filter/af_lavcac3enc.c +++ b/audio/filter/af_lavcac3enc.c @@ -163,46 +163,47 @@ static void process(struct mp_filter *f) break; if (lavc_ret < 0 && lavc_ret != AVERROR(EAGAIN)) { MP_FATAL(f, "Encode failed (receive).\n"); - goto done; + goto error; } } AVFrame *frame = NULL; struct mp_frame input = mp_pin_out_read(s->in_pin); // The following code assumes no sample data buffering in the encoder. - if (input.type == MP_FRAME_EOF) { + switch (input.type) { + case MP_FRAME_NONE: + goto done; // no data yet + case MP_FRAME_EOF: mp_pin_in_write(f->ppins[1], input); - return; - } else if (input.type == MP_FRAME_AUDIO) { + goto done; + case MP_FRAME_AUDIO: TA_FREEP(&s->in_frame); s->in_frame = input.data; frame = mp_frame_to_av(input, NULL); if (!frame) - goto done; + goto error; if (mp_aframe_get_channels(s->in_frame) < s->opts->min_channel_num) { // Just pass it through. s->in_frame = NULL; mp_pin_in_write(f->ppins[1], input); - return; + goto done; } if (!mp_aframe_config_equals(s->in_frame, s->cur_format)) { if (!reinit(f)) - goto done; + goto error; } - } else if (input.type) { - goto done; - } else { - return; // no data yet + break; + default: goto error; // unexpected packet type } int lavc_ret = avcodec_send_frame(s->lavc_actx, frame); av_frame_free(&frame); if (lavc_ret < 0 && lavc_ret != AVERROR(EAGAIN)) { MP_FATAL(f, "Encode failed (send).\n"); - goto done; + goto error; } } if (!s->in_frame) - goto done; + goto error; out = mp_aframe_create(); mp_aframe_set_format(out, AF_FORMAT_S_AC3); @@ -210,7 +211,7 @@ static void process(struct mp_filter *f) mp_aframe_set_rate(out, 48000); if (mp_aframe_pool_allocate(s->out_pool, out, s->out_samples) < 0) - goto done; + goto error; int sstride = mp_aframe_get_sstride(out); @@ -239,7 +240,7 @@ static void process(struct mp_filter *f) uint8_t **planes = mp_aframe_get_data_rw(out); if (!planes) - goto done; + goto error; char *buf = planes[0]; memcpy(buf, hdr, header_len); memcpy(buf + header_len, pkt.data, pkt.size); @@ -250,8 +251,10 @@ static void process(struct mp_filter *f) mp_pin_in_write(f->ppins[1], MAKE_FRAME(MP_FRAME_AUDIO, out)); out = NULL; - err = 0; done: + err = false; + // fall through +error: av_packet_unref(&pkt); talloc_free(out); if (err) |