Bug 951770 - Reject invalid Opus pre-skip in WebM. r=doublec

The 'pre-skip' value representing encoder delay in the Opus
format is recorded once in the .opus representation, but for
WebM it's in the file both in the CodecDelay element and in
the CodecPrivate data. We now reject files where these two
fields don't match.

Our detodos.webm file was exactly this sort of mismatched
file. It has been renamed and added to the invalid file list
to verify we now reject it. A new detodos.webm replaces it,
remuxed from detodos.opus with a bugfixed mkvmerge.

Based on a patch by Jan Gerber.

--HG--
rename : content/media/test/detodos.webm => content/media/test/invalid-preskip.webm
This commit is contained in:
Ralph Giles 2014-02-02 19:39:00 -08:00
parent 64c2ed9b8f
commit c88a2f8c99
6 changed files with 12 additions and 3 deletions

Binary file not shown.

Binary file not shown.

View File

@ -233,6 +233,7 @@ var gInvalidTests = [
{ name:"invalid-cmap-s0c0.opus", type:"audio/ogg; codecs=opus"}, { name:"invalid-cmap-s0c0.opus", type:"audio/ogg; codecs=opus"},
{ name:"invalid-cmap-s0c2.opus", type:"audio/ogg; codecs=opus"}, { name:"invalid-cmap-s0c2.opus", type:"audio/ogg; codecs=opus"},
{ name:"invalid-cmap-s1c2.opus", type:"audio/ogg; codecs=opus"}, { name:"invalid-cmap-s1c2.opus", type:"audio/ogg; codecs=opus"},
{ name:"invalid-preskip.webm", type:"audio/webm; codecs=opus"},
]; ];
// Converts a path/filename to a file:// URI which we can load from disk. // Converts a path/filename to a file:// URI which we can load from disk.

View File

@ -110,6 +110,7 @@ support-files =
invalid-m1c9.opus invalid-m1c9.opus
invalid-m2c0.opus invalid-m2c0.opus
invalid-m2c1.opus invalid-m2c1.opus
invalid-preskip.webm
long.vtt long.vtt
manifest.js manifest.js
multiple-bos.ogg multiple-bos.ogg

View File

@ -372,7 +372,7 @@ nsresult WebMReader::ReadMetadata(MediaInfo* aInfo,
mHasAudio = true; mHasAudio = true;
mInfo.mAudio.mHasAudio = true; mInfo.mAudio.mHasAudio = true;
mAudioCodec = nestegg_track_codec_id(mContext, track); mAudioCodec = nestegg_track_codec_id(mContext, track);
mCodecDelay = params.codec_delay; mCodecDelay = params.codec_delay / NS_PER_USEC;
if (mAudioCodec == NESTEGG_CODEC_VORBIS) { if (mAudioCodec == NESTEGG_CODEC_VORBIS) {
// Get the Vorbis header data // Get the Vorbis header data
@ -439,6 +439,13 @@ nsresult WebMReader::ReadMetadata(MediaInfo* aInfo,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (static_cast<int64_t>(mCodecDelay) != FramesToUsecs(mOpusParser->mPreSkip, mOpusParser->mRate).value()) {
LOG(PR_LOG_WARNING,
("Invalid Opus header: CodecDelay and pre-skip do not match!\n"));
Cleanup();
return NS_ERROR_FAILURE;
}
mInfo.mAudio.mRate = mOpusParser->mRate; mInfo.mAudio.mRate = mOpusParser->mRate;
mInfo.mAudio.mChannels = mOpusParser->mChannels; mInfo.mAudio.mChannels = mOpusParser->mChannels;
@ -718,7 +725,7 @@ bool WebMReader::DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset)
NS_WARNING("Int overflow converting WebM audio duration"); NS_WARNING("Int overflow converting WebM audio duration");
return false; return false;
} }
CheckedInt64 time = startTime - (mCodecDelay / NS_PER_USEC); CheckedInt64 time = startTime - mCodecDelay;
if (!time.isValid()) { if (!time.isValid()) {
NS_WARNING("Int overflow shifting tstamp by codec delay"); NS_WARNING("Int overflow shifting tstamp by codec delay");
nestegg_free_packet(aPacket); nestegg_free_packet(aPacket);

View File

@ -215,7 +215,7 @@ private:
// Number of audio frames we've decoded since decoding began at mAudioStartMs. // Number of audio frames we've decoded since decoding began at mAudioStartMs.
uint64_t mAudioFrames; uint64_t mAudioFrames;
// Number of nanoseconds that must be discarded from the start of the Stream. // Number of microseconds that must be discarded from the start of the Stream.
uint64_t mCodecDelay; uint64_t mCodecDelay;
// Parser state and computed offset-time mappings. Shared by multiple // Parser state and computed offset-time mappings. Shared by multiple