Bug 951770 - Reject invalid Opus pre-skip in WebM. r=doublec
authorRalph Giles <giles@mozilla.com>
Sun, 02 Feb 2014 19:39:00 -0800
changeset 166814 06e99d1896ce003326d24eebd7854104748d8f3a
parent 166813 c8abc650f217bf737ba0c4e0cf60b028d0f420e2
child 166815 b54e8c328c327943fe5662e9e84bf748a1f97564
push id26152
push usercbook@mozilla.com
push dateWed, 05 Feb 2014 12:20:14 +0000
treeherdermozilla-central@8f7033c595b9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdoublec
bugs951770
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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.
content/media/test/detodos.webm
content/media/test/invalid-preskip.webm
content/media/test/manifest.js
content/media/test/mochitest.ini
content/media/webm/WebMReader.cpp
content/media/webm/WebMReader.h
index 99b4f2ca71707b499ad1297f97448d27d29c5750..39cfa7f537aa168155dd8d2f51f3ef06aabacb02
GIT binary patch
literal 11701
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
b;WX3-Fg#>(eF(03cyr9(A#l$D9Pj8qY(S-g
copy from content/media/test/detodos.webm
copy to content/media/test/invalid-preskip.webm
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -228,16 +228,17 @@ var gInvalidTests = [
   { name:"invalid-m1c0.opus", type:"audio/ogg; codecs=opus"},
   { name:"invalid-m1c9.opus", type:"audio/ogg; codecs=opus"},
   { name:"invalid-m2c0.opus", type:"audio/ogg; codecs=opus"},
   { name:"invalid-m2c1.opus", type:"audio/ogg; codecs=opus"},
   { name:"invalid-cmap-short.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-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.
 // Optionally checks whether the file actually exists on disk at the location
 // we've specified.
 function fileUriToSrc(path, mustExist) {
   // android mochitest doesn't support file://
   if (navigator.appVersion.indexOf("Android") != -1 || SpecialPowers.Services.appinfo.name == "B2G")
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -105,16 +105,17 @@ support-files =
   invalid-cmap-s1c2.opus
   invalid-cmap-short.opus
   invalid-m0c0.opus
   invalid-m0c3.opus
   invalid-m1c0.opus
   invalid-m1c9.opus
   invalid-m2c0.opus
   invalid-m2c1.opus
+  invalid-preskip.webm
   long.vtt
   manifest.js
   multiple-bos.ogg
   no-cues.webm
   noContentLength.sjs
   notags.mp3
   owl-funnier-id3.mp3
   owl-funny-id3.mp3
--- a/content/media/webm/WebMReader.cpp
+++ b/content/media/webm/WebMReader.cpp
@@ -367,17 +367,17 @@ nsresult WebMReader::ReadMetadata(MediaI
         Cleanup();
         return NS_ERROR_FAILURE;
       }
 
       mAudioTrack = track;
       mHasAudio = true;
       mInfo.mAudio.mHasAudio = true;
       mAudioCodec = nestegg_track_codec_id(mContext, track);
-      mCodecDelay = params.codec_delay;
+      mCodecDelay = params.codec_delay / NS_PER_USEC;
 
       if (mAudioCodec == NESTEGG_CODEC_VORBIS) {
         // Get the Vorbis header data
         unsigned int nheaders = 0;
         r = nestegg_track_codec_data_count(mContext, track, &nheaders);
         if (r == -1 || nheaders != 3) {
           Cleanup();
           return NS_ERROR_FAILURE;
@@ -434,16 +434,23 @@ nsresult WebMReader::ReadMetadata(MediaI
           return NS_ERROR_FAILURE;
         }
 
         if (!InitOpusDecoder()) {
           Cleanup();
           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.mChannels = mOpusParser->mChannels;
         mChannels = mInfo.mAudio.mChannels;
         mSeekPreroll = params.seek_preroll;
 #endif
       } else {
         Cleanup();
@@ -713,17 +720,17 @@ bool WebMReader::DecodeAudioPacket(neste
         return false;
       }
 
       CheckedInt64 duration = FramesToUsecs(frames, rate);
       if (!duration.isValid()) {
         NS_WARNING("Int overflow converting WebM audio duration");
         return false;
       }
-      CheckedInt64 time = startTime - (mCodecDelay / NS_PER_USEC);
+      CheckedInt64 time = startTime - mCodecDelay;
       if (!time.isValid()) {
         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(),
--- a/content/media/webm/WebMReader.h
+++ b/content/media/webm/WebMReader.h
@@ -210,17 +210,17 @@ private:
   uint32_t mAudioTrack;
 
   // Time in microseconds of the start of the first audio frame we've decoded.
   int64_t mAudioStartUsec;
 
   // Number of audio frames we've decoded since decoding began at mAudioStartMs.
   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;
 
   // Parser state and computed offset-time mappings.  Shared by multiple
   // readers when decoder has been cloned.  Main thread only.
   nsRefPtr<WebMBufferedState> mBufferedState;
 
   // Size of the frame initially present in the stream. The picture region
   // is defined as a ratio relative to this.