зеркало из https://github.com/mozilla/gecko-dev.git
Bug 670055 - Seek video to exact audio sample. r=kinetik
This commit is contained in:
Родитель
371b57bace
Коммит
68f912bb40
|
@ -310,6 +310,10 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
|
|||
|
||||
if (HasAudio()) {
|
||||
// Decode audio forward to the seek target.
|
||||
PRInt64 targetSample = 0;
|
||||
if (!UsecsToSamples(aTarget, mInfo.mAudioRate, targetSample)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
PRBool eof = PR_FALSE;
|
||||
while (HasAudio() && !eof) {
|
||||
while (!eof && mAudioQueue.GetSize() == 0) {
|
||||
|
@ -322,14 +326,53 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
|
|||
}
|
||||
}
|
||||
}
|
||||
nsAutoPtr<SoundData> audio(mAudioQueue.PeekFront());
|
||||
if (audio && audio->mTime + audio->mDuration <= aTarget) {
|
||||
mAudioQueue.PopFront();
|
||||
const SoundData* audio = mAudioQueue.PeekFront();
|
||||
if (!audio)
|
||||
break;
|
||||
PRInt64 startSample = 0;
|
||||
if (!UsecsToSamples(audio->mTime, mInfo.mAudioRate, startSample)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (startSample + audio->mSamples <= targetSample) {
|
||||
// Our seek target lies after the samples in this SoundData. Pop it
|
||||
// off the queue, and keep decoding forwards.
|
||||
delete mAudioQueue.PopFront();
|
||||
audio = nsnull;
|
||||
} else {
|
||||
audio.forget();
|
||||
continue;
|
||||
}
|
||||
|
||||
// The seek target lies somewhere in this SoundData's samples, strip off
|
||||
// any samples which lie before the seek target, so we'll begin playback
|
||||
// exactly at the seek target.
|
||||
NS_ASSERTION(targetSample >= startSample, "Target must at or be after data start.");
|
||||
NS_ASSERTION(startSample + audio->mSamples > targetSample, "Data must end after target.");
|
||||
|
||||
PRInt64 samplesToPrune = targetSample - startSample;
|
||||
if (samplesToPrune > audio->mSamples) {
|
||||
// We've messed up somehow. Don't try to trim samples, the |samples|
|
||||
// variable below will overflow.
|
||||
NS_WARNING("Can't prune more samples that we have!");
|
||||
break;
|
||||
}
|
||||
PRUint32 samples = audio->mSamples - static_cast<PRUint32>(samplesToPrune);
|
||||
PRUint32 channels = audio->mChannels;
|
||||
nsAutoArrayPtr<SoundDataValue> audioData(new SoundDataValue[samples * channels]);
|
||||
memcpy(audioData.get(),
|
||||
audio->mAudioData.get() + (samplesToPrune * channels),
|
||||
samples * channels * sizeof(SoundDataValue));
|
||||
PRInt64 duration;
|
||||
if (!SamplesToUsecs(samples, mInfo.mAudioRate, duration)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsAutoPtr<SoundData> data(new SoundData(audio->mOffset,
|
||||
aTarget,
|
||||
duration,
|
||||
samples,
|
||||
audioData.forget(),
|
||||
channels));
|
||||
delete mAudioQueue.PopFront();
|
||||
mAudioQueue.PushFront(data.forget());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче