mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-14 02:33:51 +02:00
Added better workaround for planar audio format from ffmpeg
This commit is contained in:
parent
2ef3e5e2f1
commit
e39461165a
@ -445,19 +445,11 @@ std::pair<std::unique_ptr<ui8 []>, si64> CAudioInstance::extractAudio(const Vide
|
||||
std::vector<ui8> samples;
|
||||
|
||||
auto formatProperties = getAudioFormatProperties(codecpar->format);
|
||||
#if(LIBAVUTIL_VERSION_MAJOR < 58)
|
||||
int numChannels = codecpar->channels;
|
||||
|
||||
// Workaround for lack of resampler
|
||||
// Currently, ffmpeg on conan systems is built without sws resampler
|
||||
// Because of that, and because wav format does not supports 'planar' formats from ffmpeg
|
||||
// we need to load only one channel and play this sound as mono-channel audio
|
||||
// correct approach would be to either use resampler or to do this conversion manually
|
||||
// alternative approaches:
|
||||
// - use SDL resampler, however planar formats are not suppported by it either
|
||||
// - generate two audio streams and play them separately
|
||||
// Good news is that it looks like none of H3 video files use this format (only in not supported HD Edition)
|
||||
if (formatProperties.isPlanar)
|
||||
numChannels = 1;
|
||||
#else
|
||||
int numChannels = codecpar->ch_layout.nb_channels;
|
||||
#endif
|
||||
|
||||
samples.reserve(44100 * 5); // arbitrary 5-second buffer
|
||||
|
||||
@ -469,8 +461,24 @@ std::pair<std::unique_ptr<ui8 []>, si64> CAudioInstance::extractAudio(const Vide
|
||||
if (!frame)
|
||||
break;
|
||||
|
||||
int bytesToRead = frame->nb_samples * numChannels * formatProperties.sampleSizeBytes;
|
||||
samples.insert(samples.end(), frame->data[0], frame->data[0] + bytesToRead);
|
||||
int samplesToRead = frame->nb_samples * numChannels;
|
||||
int bytesToRead = samplesToRead * formatProperties.sampleSizeBytes;
|
||||
|
||||
if (formatProperties.isPlanar && numChannels > 1)
|
||||
{
|
||||
// Workaround for lack of resampler
|
||||
// Currently, ffmpeg on conan systems is built without sws resampler
|
||||
// Because of that, and because wav format does not supports 'planar' formats from ffmpeg
|
||||
// we need to de-planarize it and convert to "normal" (non-planar / interleaved) steram
|
||||
samples.reserve(samples.size() + bytesToRead);
|
||||
for (int sm = 0; sm < frame->nb_samples; ++sm)
|
||||
for (int ch = 0; ch < numChannels; ++ch)
|
||||
samples.insert(samples.end(), frame->data[ch] + sm * formatProperties.sampleSizeBytes, frame->data[ch] + (sm+1) * formatProperties.sampleSizeBytes );
|
||||
}
|
||||
else
|
||||
{
|
||||
samples.insert(samples.end(), frame->data[0], frame->data[0] + bytesToRead);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct WAV_HEADER {
|
||||
|
Loading…
Reference in New Issue
Block a user