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.
This commit is contained in:
Karl Blomster 2008-08-14 16:10:31 +00:00
parent 620cf44c46
commit d1c62c1324
2 changed files with 18 additions and 9 deletions

View File

@ -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<int16_t>::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<int16_t>(&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<int16_t>(&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);

View File

@ -59,7 +59,6 @@ extern "C" {
#include "lavc_file.h"
#include "include/aegisub/audio_provider.h"
#include "lavc_file.h"
#include <vector>
///////////////////////
@ -75,7 +74,7 @@ private:
int audStream;
int16_t *buffer;
std::vector<int16_t> overshoot_buffer;
int16_t *overshoot_buffer;
int leftover_samples;