From d1c62c132481c7314df77b39a6ef681fee3b7e69 Mon Sep 17 00:00:00 2001 From: Karl Blomster Date: Thu, 14 Aug 2008 16:10:31 +0000 Subject: [PATCH] Fix crash on playing video without audio loaded when using the ffmpeg providers. Patch by Manta with minor modifications by me. Originally committed to SVN as r2303. --- aegisub/audio_provider_lavc.cpp | 24 +++++++++++++++++------- aegisub/audio_provider_lavc.h | 3 +-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/aegisub/audio_provider_lavc.cpp b/aegisub/audio_provider_lavc.cpp index 5b75ebbca..9e352ee7f 100644 --- a/aegisub/audio_provider_lavc.cpp +++ b/aegisub/audio_provider_lavc.cpp @@ -152,6 +152,10 @@ LAVCAudioProvider::LAVCAudioProvider(Aegisub::String _filename) if (!buffer) throw _T("ffmpeg audio provider: Failed to allocate audio decoding buffer, out of memory?"); + overshoot_buffer = (int16_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); + if (!overshoot_buffer) + throw _T("ffmpeg audio provider: Failed to allocate audio decoding buffer, out of memory?"); + leftover_samples = 0; } catch (...) { @@ -170,6 +174,8 @@ void LAVCAudioProvider::Destroy() { if (buffer) free(buffer); + if (overshoot_buffer) + free(overshoot_buffer); if (rsct) audio_resample_close(rsct); if (codecContext) @@ -193,15 +199,18 @@ void LAVCAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) memset(_buf + samples_to_decode, 0, ((count * channels) - samples_to_decode) * bytes_per_sample); /* do we have leftover samples from last time we were called? */ + /* FIXME: this assumes that requests are always linear! attempts at random access give bogus results! */ if (leftover_samples > 0) { + int length = (samples_to_decode > leftover_samples) ? leftover_samples : samples_to_decode; + samples_to_decode -= length; + leftover_samples -= length; + /* put them in the output buffer */ samples_to_decode -= leftover_samples; - for (std::vector::iterator i = overshoot_buffer.begin(); i != overshoot_buffer.end(); i++) { - *(_buf++) = *i; + while (length > 0) { + *(_buf++) = *(overshoot_buffer++); + length--; } - /* none left */ - leftover_samples = 0; - overshoot_buffer.clear(); } AVPacket packet; @@ -244,7 +253,8 @@ void LAVCAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) /* in that case, count them */ leftover_samples = decoded_samples - samples_to_decode; /* and put them aside for later */ - overshoot_buffer = std::vector(&temp_output_buffer[samples_to_decode+1], &temp_output_buffer[decoded_samples+1]); + memcpy(buffer, &temp_output_buffer[samples_to_decode+1], leftover_samples * bytes_per_sample); + overshoot_buffer = buffer; /* output the other samples that didn't overflow */ memcpy(_buf, temp_output_buffer, samples_to_decode * bytes_per_sample); _buf += samples_to_decode; @@ -261,7 +271,7 @@ void LAVCAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) /* count sheep^H^H^H^H^Hsamples */ leftover_samples = decoded_samples - samples_to_decode; /* and put them aside for later (mm, lamb chops) */ - overshoot_buffer = std::vector(&buffer[samples_to_decode+1], &buffer[decoded_samples+1]); + overshoot_buffer = &buffer[samples_to_decode+1]; /* output the other samples that didn't overflow */ memcpy(_buf, buffer, samples_to_decode * bytes_per_sample); diff --git a/aegisub/audio_provider_lavc.h b/aegisub/audio_provider_lavc.h index cfd6fb89e..50a0dea7c 100644 --- a/aegisub/audio_provider_lavc.h +++ b/aegisub/audio_provider_lavc.h @@ -59,7 +59,6 @@ extern "C" { #include "lavc_file.h" #include "include/aegisub/audio_provider.h" #include "lavc_file.h" -#include /////////////////////// @@ -75,7 +74,7 @@ private: int audStream; int16_t *buffer; - std::vector overshoot_buffer; + int16_t *overshoot_buffer; int leftover_samples;