Bug 1264199: P2. Ensure the AudioStream only ever receive the same content format. r=kinetik

The audio is automatically converted to always match the format of the first processed sample.
This is a temporary approach, as it would be preferred to use a final sampling rate not causing too much quality loss.

MozReview-Commit-ID: Lo3827aon43
This commit is contained in:
Jean-Yves Avenard 2016-04-13 17:30:23 +10:00
Родитель b130178b94
Коммит 024b052f14
1 изменённых файлов: 30 добавлений и 11 удалений

Просмотреть файл

@ -52,10 +52,6 @@ DecodedAudioDataSink::DecodedAudioDataSink(AbstractThread* aThread,
mOutputRate = resampling ? resamplingRate : mInfo.mRate;
mOutputChannels = mInfo.mChannels > 2 && gfxPrefs::AudioSinkForceStereo()
? 2 : mInfo.mChannels;
mConverter =
MakeUnique<AudioConverter>(
AudioConfig(mInfo.mChannels, mInfo.mRate),
AudioConfig(mOutputChannels, mOutputRate));
}
DecodedAudioDataSink::~DecodedAudioDataSink()
@ -317,13 +313,36 @@ DecodedAudioDataSink::NotifyAudioNeeded()
continue;
}
// Ignore invalid samples.
if (data->mRate != mConverter->InputConfig().Rate() ||
data->mChannels != mConverter->InputConfig().Channels()) {
NS_WARNING(nsPrintfCString(
"mismatched sample format, data=%p rate=%u channels=%u frames=%u",
data->mAudioData.get(), data->mRate, data->mChannels, data->mFrames).get());
continue;
if (!mConverter ||
(data->mRate != mConverter->InputConfig().Rate() ||
data->mChannels != mConverter->InputConfig().Channels())) {
SINK_LOG_V("Audio format changed from %u@%uHz to %u@%uHz",
mConverter? mConverter->InputConfig().Channels() : 0,
mConverter ? mConverter->InputConfig().Rate() : 0,
data->mChannels, data->mRate);
// mFramesParsed indicates the current playtime in frames at the current
// input sampling rate. Recalculate it per the new sampling rate.
if (mFramesParsed) {
// We minimize overflow.
uint32_t oldRate = mConverter->InputConfig().Rate();
uint32_t newRate = data->mRate;
int64_t major = mFramesParsed / oldRate;
int64_t remainder = mFramesParsed % oldRate;
CheckedInt64 result =
CheckedInt64(remainder) * newRate / oldRate + major * oldRate;
if (!result.isValid()) {
NS_WARNING("Int overflow in DecodedAudioDataSink");
mErrored = true;
return;
}
mFramesParsed = result.value();
}
mConverter =
MakeUnique<AudioConverter>(
AudioConfig(data->mChannels, data->mRate),
AudioConfig(mOutputChannels, mOutputRate));
}
// See if there's a gap in the audio. If there is, push silence into the