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

--HG--
extra : rebase_source : d8de2c85de5a78c2d1a17201a9d0c418ce3312e4
This commit is contained in:
Jean-Yves Avenard 2016-04-13 17:30:23 +10:00
Родитель 6517105f96
Коммит d679b38075
1 изменённых файлов: 31 добавлений и 11 удалений

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

@ -53,10 +53,7 @@ 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));
mAudioQueueListener = aAudioQueue.PushEvent().Connect(
mProcessingThread, this, &DecodedAudioDataSink::OnAudioPushed);
mProcessedQueueListener = mProcessedQueue.PopEvent().Connect(
@ -320,13 +317,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