Bug 1312958: P1. Do not modify original Audio/Video info. r=gerald
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 26 Oct 2016 20:09:41 +1100
changeset 319555 ec5530dcf06d7287b1bcc7cdc069596d3306af96
parent 319554 97578d6a43a680618b91bb8fd792c25dd146764c
child 319556 32fc9ca7a95bde34e88e91f12af428cd6361eca6
push id20745
push userphilringnalda@gmail.com
push dateThu, 27 Oct 2016 01:57:01 +0000
treeherderfx-team@3f4c3a3cabaf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1312958
milestone52.0a1
Bug 1312958: P1. Do not modify original Audio/Video info. r=gerald The issue is particularly problematic with the Apple audio decoder. The Apple decoder relies on the sampling rate to configure the CoreAudio transform. The actual output rate may be different (such as with HE-AAC). Should the decoder ever need to be reset again, future initialization would have failed as the initial rate was now incorrect. MozReview-Commit-ID: 7kTiaUYuOgf
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -283,16 +283,17 @@ MediaFormatReader::OnDemuxerInitDone(nsr
         // We have no decoder for this track. Error.
         mMetadataPromise.Reject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
         return;
       }
       mInfo.mVideo = *videoInfo->GetAsVideoInfo();
       for (const MetadataTag& tag : videoInfo->mTags) {
         tags->Put(tag.mKey, tag.mValue);
       }
+      mVideo.mOriginalInfo = Move(videoInfo);
       mVideo.mCallback = new DecoderCallback(this, TrackInfo::kVideoTrack);
       mVideo.mTimeRanges = mVideo.mTrackDemuxer->GetBuffered();
       mTrackDemuxersMayBlock |= mVideo.mTrackDemuxer->GetSamplesMayBlock();
     } else {
       mVideo.mTrackDemuxer->BreakCycles();
       mVideo.mTrackDemuxer = nullptr;
     }
   }
@@ -311,16 +312,17 @@ MediaFormatReader::OnDemuxerInitDone(nsr
                   (!platform ||
                    platform->SupportsMimeType(audioInfo->mMimeType, nullptr));
 
     if (audioActive) {
       mInfo.mAudio = *audioInfo->GetAsAudioInfo();
       for (const MetadataTag& tag : audioInfo->mTags) {
         tags->Put(tag.mKey, tag.mValue);
       }
+      mAudio.mOriginalInfo = Move(audioInfo);
       mAudio.mCallback = new DecoderCallback(this, TrackInfo::kAudioTrack);
       mAudio.mTimeRanges = mAudio.mTrackDemuxer->GetBuffered();
       mTrackDemuxersMayBlock |= mAudio.mTrackDemuxer->GetSamplesMayBlock();
     } else {
       mAudio.mTrackDemuxer->BreakCycles();
       mAudio.mTrackDemuxer = nullptr;
     }
   }
@@ -398,31 +400,35 @@ MediaFormatReader::EnsureDecoderCreated(
 
   decoder.mDecoderInitialized = false;
 
   MonitorAutoLock mon(decoder.mMonitor);
 
   switch (aTrack) {
     case TrackType::kAudioTrack: {
       decoder.mDecoder = mPlatform->CreateDecoder({
-        decoder.mInfo ? *decoder.mInfo->GetAsAudioInfo() : mInfo.mAudio,
+        decoder.mInfo
+        ? *decoder.mInfo->GetAsAudioInfo()
+        : *decoder.mOriginalInfo->GetAsAudioInfo(),
         decoder.mTaskQueue,
         decoder.mCallback.get(),
         mCrashHelper,
         decoder.mIsBlankDecode,
         &result
       });
       break;
     }
 
     case TrackType::kVideoTrack: {
       // Decoders use the layers backend to decide if they can use hardware decoding,
       // so specify LAYERS_NONE if we want to forcibly disable it.
       decoder.mDecoder = mPlatform->CreateDecoder({
-        mVideo.mInfo ? *mVideo.mInfo->GetAsVideoInfo() : mInfo.mVideo,
+        decoder.mInfo
+        ? *decoder.mInfo->GetAsVideoInfo()
+        : *decoder.mOriginalInfo->GetAsVideoInfo(),
         decoder.mTaskQueue,
         decoder.mCallback.get(),
         mKnowsCompositor,
         GetImageContainer(),
         mCrashHelper,
         decoder.mIsBlankDecode,
         &result
       });
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -420,16 +420,18 @@ private:
     // Used by the MDSM to determine if video decoding is hardware accelerated.
     // This value is updated after a frame is successfully decoded.
     Atomic<bool> mIsHardwareAccelerated;
     // Sample format monitoring.
     uint32_t mLastStreamSourceID;
     Maybe<uint32_t> mNextStreamSourceID;
     media::TimeIntervals mTimeRanges;
     Maybe<media::TimeUnit> mLastTimeRangesEnd;
+    // TrackInfo as first discovered during ReadMetadata.
+    UniquePtr<TrackInfo> mOriginalInfo;
     RefPtr<SharedTrackInfo> mInfo;
     Maybe<media::TimeUnit> mFirstDemuxedSampleTime;
     // Use BlankDecoderModule or not.
     bool mIsBlankDecode;
 
   };
 
   class DecoderDataWithPromise : public DecoderData {