Commit 0129ba51 authored by Philippe Gorley's avatar Philippe Gorley

audio: fix memory leak

Fixes ~1MB/s leak by using AVFrame API to alloc AVFrame buffers instead
of using Sample API.

Gitlab: #41

Change-Id: I1ebd6f5b87feea7a21046fe3e2172a4c5584526f
parent 589688c2
......@@ -293,42 +293,26 @@ size_t AudioBuffer::copy(AudioSample* in, size_t sample_num, size_t pos_out /* =
AVFrame*
AudioBuffer::toAVFrame() const
{
const constexpr AVSampleFormat fmt = AV_SAMPLE_FMT_S16;
// NOTE: don't use std::vector, avcodec_fill_audio_frame makes the frame point to our array
// instead of copying it, resulting in a heap use after free once we return
AudioSample** samples;
int err = av_samples_alloc_array_and_samples(reinterpret_cast<uint8_t***>(&samples),
nullptr, channels(), frames(), fmt, 0);
if (err < 0) {
RING_ERR() << "Failed to allocate audio buffer";
return nullptr;
}
interleave(*samples);
AVFrame* frame = av_frame_alloc();
if (!frame) {
RING_ERR() << "Failed to allocate frame";
av_freep(samples);
RING_ERR() << "Failed to allocate audio frame";
return nullptr;
}
frame->format = AV_SAMPLE_FMT_S16;
frame->nb_samples = frames();
frame->format = fmt;
frame->channel_layout = av_get_default_channel_layout(channels());
frame->channels = channels();
frame->sample_rate = getSampleRate();
const auto bufSize = av_samples_get_buffer_size(nullptr,
frame->channels, frame->nb_samples, fmt, 0);
if (avcodec_fill_audio_frame(frame, frame->channels, fmt,
reinterpret_cast<uint8_t*>(*samples), bufSize, 0) < 0) {
RING_ERR() << "Failed to fill audio frame";
if (av_frame_get_buffer(frame, 0) < 0) {
RING_ERR() << "Failed to audio frame";
av_frame_free(&frame);
return nullptr;
}
interleave(reinterpret_cast<AudioSample*>(frame->data[0]));
return frame;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment