mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-14 14:02:47 +00:00
Bug 945863 - Handle CodecDelay and SeekPreroll for Opus in WebM. r=kinetik
This commit is contained in:
parent
38439ea439
commit
e286df484b
@ -11,6 +11,7 @@
|
||||
#include "WebMBufferedParser.h"
|
||||
#include "mozilla/dom/TimeRanges.h"
|
||||
#include "VorbisUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
#define VPX_DONT_DEFINE_STDINT_TYPES
|
||||
#include "vpx/vp8dx.h"
|
||||
@ -147,6 +148,7 @@ WebMReader::WebMReader(AbstractMediaDecoder* aDecoder)
|
||||
mOpusParser(nullptr),
|
||||
mOpusDecoder(nullptr),
|
||||
mSkip(0),
|
||||
mSeekPreroll(0),
|
||||
#endif
|
||||
mVideoTrack(0),
|
||||
mAudioTrack(0),
|
||||
@ -218,10 +220,20 @@ nsresult WebMReader::ResetDecode()
|
||||
res = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mAudioCodec == NESTEGG_CODEC_VORBIS) {
|
||||
// Ignore failed results from vorbis_synthesis_restart. They
|
||||
// aren't fatal and it fails when ResetDecode is called at a
|
||||
// time when no vorbis data has been read.
|
||||
vorbis_synthesis_restart(&mVorbisDsp);
|
||||
#ifdef MOZ_OPUS
|
||||
} else if (mAudioCodec == NESTEGG_CODEC_OPUS) {
|
||||
if (mOpusDecoder) {
|
||||
// Reset the decoder.
|
||||
opus_multistream_decoder_ctl(mOpusDecoder, OPUS_RESET_STATE);
|
||||
mSkip = mOpusParser->mPreSkip;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
mVideoPackets.Reset();
|
||||
mAudioPackets.Reset();
|
||||
@ -431,6 +443,8 @@ nsresult WebMReader::ReadMetadata(MediaInfo* aInfo,
|
||||
|
||||
mInfo.mAudio.mChannels = mOpusParser->mChannels;
|
||||
mInfo.mAudio.mChannels = mInfo.mAudio.mChannels > 2 ? 2 : mInfo.mAudio.mChannels;
|
||||
mChannels = mInfo.mAudio.mChannels;
|
||||
mSeekPreroll = params.seek_preroll;
|
||||
#endif
|
||||
} else {
|
||||
Cleanup();
|
||||
@ -627,6 +641,7 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
|
||||
if (ret < 0)
|
||||
return false;
|
||||
NS_ASSERTION(ret == frames, "Opus decoded too few audio samples");
|
||||
CheckedInt64 startTime = tstamp_usecs;
|
||||
|
||||
// Trim the initial frames while the decoder is settling.
|
||||
if (mSkip > 0) {
|
||||
@ -643,7 +658,7 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
|
||||
nsAutoArrayPtr<AudioDataValue> trimBuffer(new AudioDataValue[samples]);
|
||||
for (int i = 0; i < samples; i++)
|
||||
trimBuffer[i] = buffer[skipFrames*channels + i];
|
||||
|
||||
startTime = startTime + FramesToUsecs(skipFrames, rate);
|
||||
frames = keepFrames;
|
||||
buffer = trimBuffer;
|
||||
|
||||
@ -708,14 +723,12 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
|
||||
NS_WARNING("Int overflow converting WebM audio duration");
|
||||
return false;
|
||||
}
|
||||
|
||||
CheckedInt64 time = tstamp_usecs;
|
||||
CheckedInt64 time = startTime - (mCodecDelay / NS_PER_USEC);
|
||||
if (!time.isValid()) {
|
||||
NS_WARNING("Int overflow adding total_duration and tstamp_usecs");
|
||||
NS_WARNING("Int overflow shifting tstamp by codec delay");
|
||||
nestegg_free_packet(aPacket);
|
||||
return false;
|
||||
};
|
||||
|
||||
AudioQueue().Push(new AudioData(mDecoder->GetResource()->Tell(),
|
||||
time.value(),
|
||||
duration.value(),
|
||||
@ -982,7 +995,11 @@ nsresult WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
uint32_t trackToSeek = mHasVideo ? mVideoTrack : mAudioTrack;
|
||||
int r = nestegg_track_seek(mContext, trackToSeek, aTarget * NS_PER_USEC);
|
||||
uint64_t target = aTarget * NS_PER_USEC;
|
||||
if (mSeekPreroll) {
|
||||
target = std::max(static_cast<uint64_t>(aStartTime * NS_PER_USEC), target - mSeekPreroll);
|
||||
}
|
||||
int r = nestegg_track_seek(mContext, trackToSeek, target);
|
||||
if (r != 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -197,6 +197,7 @@ private:
|
||||
nsAutoPtr<OpusParser> mOpusParser;
|
||||
OpusMSDecoder *mOpusDecoder;
|
||||
int mSkip; // Number of samples left to trim before playback.
|
||||
uint64_t mSeekPreroll; // Number of nanoseconds that must be discarded after seeking.
|
||||
#endif
|
||||
|
||||
// Queue of video and audio packets that have been read but not decoded. These
|
||||
|
Loading…
x
Reference in New Issue
Block a user