forked from mia/Aegisub
Fix crash when playing audio before time 0
There were two checks for reads past the end rather than checks for before start and after end. Closes #1556.
This commit is contained in:
parent
4e8e5b597c
commit
59e6a1bef7
2 changed files with 33 additions and 42 deletions
|
@ -78,58 +78,47 @@ void AudioProvider::GetAudioWithVolume(void *buf, int64_t start, int64_t count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
void AudioProvider::ZeroFill(void *buf, int64_t count) const {
|
||||||
if (start+count > num_samples) {
|
if (bytes_per_sample == 1)
|
||||||
int64_t oldcount = count;
|
// 8 bit formats are usually unsigned with bias 127
|
||||||
count = num_samples-start;
|
memset(buf, 127, count * channels);
|
||||||
if (count < 0) count = 0;
|
else
|
||||||
|
// While everything else is signed
|
||||||
|
memset(buf, 0, count * bytes_per_sample * channels);
|
||||||
|
}
|
||||||
|
|
||||||
// Fill beyond with zero
|
void AudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
|
||||||
if (bytes_per_sample == 1) {
|
if (start < 0) {
|
||||||
char *temp = (char *) buf;
|
ZeroFill(buf, std::min(-start, count));
|
||||||
for (int i=count;i<oldcount;i++) {
|
buf = static_cast<char *>(buf) + -start * bytes_per_sample * channels;
|
||||||
temp[i] = 0;
|
count += start;
|
||||||
}
|
start = 0;
|
||||||
}
|
|
||||||
if (bytes_per_sample == 2) {
|
|
||||||
short *temp = (short *) buf;
|
|
||||||
for (int i=count;i<oldcount;i++) {
|
|
||||||
temp[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start + count > num_samples) {
|
if (start + count > num_samples) {
|
||||||
int64_t zero_count = std::min(count, start + count - num_samples);
|
int64_t zero_count = std::min(count, start + count - num_samples);
|
||||||
count -= zero_count;
|
count -= zero_count;
|
||||||
char *zero_buf = static_cast<char *>(buf) + count * bytes_per_sample * channels;
|
ZeroFill(static_cast<char *>(buf) + count * bytes_per_sample * channels, zero_count);
|
||||||
|
|
||||||
if (bytes_per_sample == 1)
|
|
||||||
// 8 bit formats are usually unsigned with bias 127
|
|
||||||
memset(zero_buf, 127, zero_count * channels);
|
|
||||||
else
|
|
||||||
// While everything else is signed
|
|
||||||
memset(zero_buf, 0, zero_count * bytes_per_sample * channels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 0) {
|
if (count <= 0) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FillBuffer(buf, start, count);
|
FillBuffer(buf, start, count);
|
||||||
}
|
}
|
||||||
catch (AudioDecodeError const& e) {
|
catch (AudioDecodeError const& e) {
|
||||||
LOG_E("audio_provider") << e.GetChainedMessage();
|
LOG_E("audio_provider") << e.GetChainedMessage();
|
||||||
memset(buf, 0, count*bytes_per_sample);
|
ZeroFill(buf, count);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
// FIXME: Poor error handling though better than none, to patch issue #800.
|
// FIXME: Poor error handling though better than none, to patch issue #800.
|
||||||
// Just return blank audio if real provider fails.
|
// Just return blank audio if real provider fails.
|
||||||
LOG_E("audio_provider") << "Unknown audio decoding error";
|
LOG_E("audio_provider") << "Unknown audio decoding error";
|
||||||
memset(buf, 0, count*bytes_per_sample);
|
ZeroFill(buf, count);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename, int cache) {
|
AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename, int cache) {
|
||||||
AudioProvider *provider = 0;
|
AudioProvider *provider = 0;
|
||||||
|
|
|
@ -67,6 +67,8 @@ protected:
|
||||||
|
|
||||||
virtual void FillBuffer(void *buf, int64_t start, int64_t count) const = 0;
|
virtual void FillBuffer(void *buf, int64_t start, int64_t count) const = 0;
|
||||||
|
|
||||||
|
void ZeroFill(void *buf, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~AudioProvider() { }
|
virtual ~AudioProvider() { }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue