⛏️ index : haiku.git

author PulkoMandy <pulkomandy@pulkomandy.tk> 2023-01-21 17:40:01.0 +01:00:00
committer waddlesplash <waddlesplash@gmail.com> 2023-01-26 0:05:43.0 +00:00:00
commit
49cb8b31ca785b0a03e8d0f036010efcb34498a2 [patch]
tree
30417b1f6277a7e0617ec91aa246b8f47ccf4d06
parent
16abf336741cae0cc1e759152c15903aac8f2288
download
49cb8b31ca785b0a03e8d0f036010efcb34498a2.tar.gz

ffmpeg: fix missing initialization of AVFrame

ffmpeg API reference does not allow to allocate AVFrame on the stack,
and especially not without initializing anything in the frame. Calling
av_frame_unref then attempts to free some non-existing data, and
crashes.

The code for video was already using a correctly allocated frame, which
we can reuse here.

Fixes #17415

Probably fixes #16831

Change-Id: I91054dc41f0a91be9c585ec927e77bfc874a37ea
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6019
Reviewed-by: waddlesplash <waddlesplash@gmail.com>

Diff

 src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp
index 93bde34..7c01441 100644
--- a/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp
+++ b/src/add-ons/media/plugins/ffmpeg/AVCodecEncoder.cpp
@@ -584,35 +584,34 @@
	packet.data = NULL;
	packet.size = 0;

	// We need to wrap our input data into an AVFrame structure.
	AVFrame frame;
	int gotPacket = 0;

	if (buffer) {
		av_frame_unref(&frame);
		av_frame_unref(fFrame);
		fFrame->nb_samples = frameCount;

		frame.nb_samples = frameCount;

		ret = avcodec_fill_audio_frame(&frame, fCodecContext->channels,
		ret = avcodec_fill_audio_frame(fFrame, fCodecContext->channels,
				fCodecContext->sample_fmt, (const uint8_t *) buffer, bufferSize, 1);

		if (ret != 0)
		if (ret != 0) {
			TRACE("  avcodec_encode_audio() failed filling data: %ld\n", ret);
			return B_ERROR;
		}

		/* Set the presentation time of the frame */
		frame.pts = (bigtime_t)(fFramesWritten * 1000000LL
		fFrame->pts = (bigtime_t)(fFramesWritten * 1000000LL
			/ fInputFormat.u.raw_audio.frame_rate);
		fFramesWritten += frame.nb_samples;
		fFramesWritten += fFrame->nb_samples;

		ret = avcodec_encode_audio2(fCodecContext, &packet, &frame, &gotPacket);
		ret = avcodec_encode_audio2(fCodecContext, &packet, fFrame, &gotPacket);
	} else {
		// If called with NULL, ask the encoder to flush any buffers it may
		// have pending.
		ret = avcodec_encode_audio2(fCodecContext, &packet, NULL, &gotPacket);
	}

	if (buffer && frame.extended_data != frame.data)
		av_freep(&frame.extended_data);
	if (buffer && fFrame->extended_data != fFrame->data)
		av_freep(&fFrame->extended_data);

	if (ret != 0) {
		TRACE("  avcodec_encode_audio() failed: %ld\n", ret);