Bug 1297311: P1. Always recreate a decoder when SPS changes. r?cpearce
This allow consistency between platforms. A decoder will now always be shutdown and another one created if the video configuration changes.
MozReview-Commit-ID: 1SPzhVuBrip
--- a/dom/media/ipc/RemoteVideoDecoder.h
+++ b/dom/media/ipc/RemoteVideoDecoder.h
@@ -27,17 +27,16 @@ public:
friend class RemoteDecoderModule;
// MediaDataDecoder
RefPtr<InitPromise> Init() override;
void Input(MediaRawData* aSample) override;
void Flush() override;
void Drain() override;
void Shutdown() override;
- void ConfigurationChanged(const TrackInfo& aConfig) override { MOZ_ASSERT(false); }
const char* GetDescriptionName() const override { return "RemoteVideoDecoder"; }
private:
explicit RemoteVideoDecoder(MediaDataDecoderCallback* aCallback);
~RemoteVideoDecoder();
RefPtr<InitPromise> InitInternal();
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -261,24 +261,16 @@ public:
// returned.
virtual void Shutdown() = 0;
// Called from the state machine task queue or main thread.
// Decoder needs to decide whether or not hardware accelearation is supported
// after creating. It doesn't need to call Init() before calling this function.
virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const { return false; }
- // ConfigurationChanged will be called to inform the video or audio decoder
- // that the format of the next input sample is about to change.
- // If video decoder, aConfig will be a VideoInfo object.
- // If audio decoder, aConfig will be a AudioInfo object.
- // It is not safe to store a reference to this object and the decoder must
- // make a copy.
- virtual void ConfigurationChanged(const TrackInfo& aConfig) {}
-
// Return the name of the MediaDataDecoder, only used for decoding.
// Only return a static const string, as the information may be accessed
// in a non thread-safe fashion.
virtual const char* GetDescriptionName() const = 0;
// Set a hint of seek target time to decoder. Decoder will drop any decoded
// data which pts is smaller than this value. This threshold needs to be clear
// after reset decoder.
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -205,37 +205,16 @@ WMFMediaDataDecoder::Drain()
bool
WMFMediaDataDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const {
MOZ_ASSERT(!mIsShutDown);
return mMFTManager && mMFTManager->IsHardwareAccelerated(aFailureReason);
}
void
-WMFMediaDataDecoder::ConfigurationChanged(const TrackInfo& aConfig)
-{
- MOZ_ASSERT(mCallback->OnReaderTaskQueue());
-
- nsCOMPtr<nsIRunnable> runnable =
- NewRunnableMethod<UniquePtr<TrackInfo>&&>(
- this,
- &WMFMediaDataDecoder::ProcessConfigurationChanged,
- aConfig.Clone());
- mTaskQueue->Dispatch(runnable.forget());
-}
-
-void
-WMFMediaDataDecoder::ProcessConfigurationChanged(UniquePtr<TrackInfo>&& aConfig)
-{
- if (mMFTManager) {
- mMFTManager->ConfigurationChanged(*aConfig);
- }
-}
-
-void
WMFMediaDataDecoder::SetSeekThreshold(const media::TimeUnit& aTime)
{
MOZ_ASSERT(mCallback->OnReaderTaskQueue());
MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
RefPtr<WMFMediaDataDecoder> self = this;
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableFunction([self, aTime]() {
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -52,18 +52,16 @@ public:
// Destroys all resources.
virtual void Shutdown() = 0;
virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const { return false; }
virtual TrackInfo::TrackType GetType() = 0;
- virtual void ConfigurationChanged(const TrackInfo& aConfig) {}
-
virtual const char* GetDescriptionName() const = 0;
virtual void SetSeekThreshold(const media::TimeUnit& aTime) {
mSeekTargetThreshold = Some(aTime);
}
protected:
// IMFTransform wrapper that performs the decoding.
@@ -91,18 +89,16 @@ public:
void Flush() override;
void Drain() override;
void Shutdown() override;
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
- void ConfigurationChanged(const TrackInfo& aConfig) override;
-
const char* GetDescriptionName() const override
{
return mMFTManager ? mMFTManager->GetDescriptionName() : "";
}
virtual void SetSeekThreshold(const media::TimeUnit& aTime) override;
private:
@@ -120,20 +116,16 @@ private:
void ProcessFlush();
// Called on the task queue. Orders the MFT to drain, and then extracts
// all available output.
void ProcessDrain();
void ProcessShutdown();
- // Called on the task queue. Tell the MFT that the next Input will have a
- // different configuration (typically resolution change).
- void ProcessConfigurationChanged(UniquePtr<TrackInfo>&& aConfig);
-
const RefPtr<TaskQueue> mTaskQueue;
MediaDataDecoderCallback* mCallback;
nsAutoPtr<MFTManager> mMFTManager;
// The last offset into the media resource that was passed into Input().
// This is used to approximate the decoder's position in the media resource.
int64_t mLastStreamOffset;
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -958,18 +958,9 @@ WMFVideoMFTManager::Shutdown()
bool
WMFVideoMFTManager::IsHardwareAccelerated(nsACString& aFailureReason) const
{
aFailureReason = mDXVAFailureReason;
return mDecoder && mUseHwAccel;
}
-void
-WMFVideoMFTManager::ConfigurationChanged(const TrackInfo& aConfig)
-{
- MOZ_ASSERT(aConfig.GetAsVideoInfo());
- mVideoInfo = *aConfig.GetAsVideoInfo();
- mImageSize = mVideoInfo.mImage;
- ValidateVideoInfo();
-}
-
} // namespace mozilla
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.h
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.h
@@ -35,18 +35,16 @@ public:
void Shutdown() override;
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
TrackInfo::TrackType GetType() override {
return TrackInfo::kVideoTrack;
}
- void ConfigurationChanged(const TrackInfo& aConfig) override;
-
const char* GetDescriptionName() const override
{
nsCString failureReason;
return IsHardwareAccelerated(failureReason)
? "wmf hardware video decoder" : "wmf software video decoder";
}
void Flush() override
--- a/dom/media/platforms/wrappers/FuzzingWrapper.cpp
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.cpp
@@ -83,25 +83,16 @@ DecoderFuzzingWrapper::Shutdown()
bool
DecoderFuzzingWrapper::IsHardwareAccelerated(nsACString& aFailureReason) const
{
DFW_LOGV("");
MOZ_ASSERT(mDecoder);
return mDecoder->IsHardwareAccelerated(aFailureReason);
}
-void
-DecoderFuzzingWrapper::ConfigurationChanged(const TrackInfo& aConfig)
-{
- DFW_LOGV("");
- MOZ_ASSERT(mDecoder);
- mDecoder->ConfigurationChanged(aConfig);
-}
-
-
DecoderCallbackFuzzingWrapper::DecoderCallbackFuzzingWrapper(MediaDataDecoderCallback* aCallback)
: mCallback(aCallback)
, mDontDelayInputExhausted(false)
, mDraining(false)
, mTaskQueue(new TaskQueue(SharedThreadPool::Get(NS_LITERAL_CSTRING("MediaFuzzingWrapper"), 1)))
{
CFW_LOGV("aCallback=%p", aCallback);
}
--- a/dom/media/platforms/wrappers/FuzzingWrapper.h
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.h
@@ -103,17 +103,16 @@ public:
// MediaDataDecoder implementation.
RefPtr<InitPromise> Init() override;
void Input(MediaRawData* aSample) override;
void Flush() override;
void Drain() override;
void Shutdown() override;
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
- void ConfigurationChanged(const TrackInfo& aConfig) override;
const char* GetDescriptionName() const override
{
return mDecoder->GetDescriptionName();
}
private:
virtual ~DecoderFuzzingWrapper();
RefPtr<MediaDataDecoder> mDecoder;
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -13,17 +13,16 @@
#include "mp4_demuxer/H264.h"
namespace mozilla
{
H264Converter::H264Converter(PlatformDecoderModule* aPDM,
const CreateDecoderParams& aParams)
: mPDM(aPDM)
- , mOriginalConfig(aParams.VideoConfig())
, mCurrentConfig(aParams.VideoConfig())
, mLayersBackend(aParams.mLayersBackend)
, mImageContainer(aParams.mImageContainer)
, mTaskQueue(aParams.mTaskQueue)
, mCallback(aParams.mCallback)
, mDecoder(nullptr)
, mGMPCrashHelper(aParams.mCrashHelper)
, mNeedAVCC(aPDM->DecoderNeedsConversion(aParams.mConfig)
@@ -161,47 +160,41 @@ H264Converter::SetSeekThreshold(const me
} else {
MediaDataDecoder::SetSeekThreshold(aTime);
}
}
nsresult
H264Converter::CreateDecoder(DecoderDoctorDiagnostics* aDiagnostics)
{
- if (mNeedAVCC && !mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.mExtraData)) {
+ if (!mp4_demuxer::AnnexB::HasSPS(mCurrentConfig.mExtraData)) {
// nothing found yet, will try again later
return NS_ERROR_NOT_INITIALIZED;
}
UpdateConfigFromExtraData(mCurrentConfig.mExtraData);
mp4_demuxer::SPSData spsdata;
if (mp4_demuxer::H264::DecodeSPSFromExtraData(mCurrentConfig.mExtraData, spsdata)) {
// Do some format check here.
// WMF H.264 Video Decoder and Apple ATDecoder do not support YUV444 format.
if (spsdata.chroma_format_idc == 3 /*YUV444*/) {
mLastError = NS_ERROR_FAILURE;
if (aDiagnostics) {
aDiagnostics->SetVideoFormatNotSupport();
}
return NS_ERROR_FAILURE;
}
- } else if (mNeedAVCC) {
+ } else {
// SPS was invalid.
mLastError = NS_ERROR_FAILURE;
return NS_ERROR_FAILURE;
}
- if (!mNeedAVCC) {
- // When using a decoder handling AnnexB, we get here only once from the
- // constructor. We do want to get the dimensions extracted from the SPS.
- mOriginalConfig = mCurrentConfig;
- }
-
mDecoder = mPDM->CreateVideoDecoder({
- mNeedAVCC ? mCurrentConfig : mOriginalConfig,
+ mCurrentConfig,
mTaskQueue,
mCallback,
aDiagnostics,
mImageContainer,
mLayersBackend,
mGMPCrashHelper
});
@@ -276,21 +269,16 @@ H264Converter::CheckForSPSChange(MediaRa
{
RefPtr<MediaByteBuffer> extra_data =
mp4_demuxer::AnnexB::ExtractExtraData(aSample);
if (!mp4_demuxer::AnnexB::HasSPS(extra_data) ||
mp4_demuxer::AnnexB::CompareExtraData(extra_data,
mCurrentConfig.mExtraData)) {
return NS_OK;
}
- if (!mNeedAVCC) {
- UpdateConfigFromExtraData(extra_data);
- mDecoder->ConfigurationChanged(mCurrentConfig);
- return NS_OK;
- }
// The SPS has changed, signal to flush the current decoder and create a
// new one.
mDecoder->Flush();
Shutdown();
return CreateDecoderAndInit(aSample);
}
void
--- a/dom/media/platforms/wrappers/H264Converter.h
+++ b/dom/media/platforms/wrappers/H264Converter.h
@@ -50,17 +50,16 @@ private:
nsresult CreateDecoderAndInit(MediaRawData* aSample);
nsresult CheckForSPSChange(MediaRawData* aSample);
void UpdateConfigFromExtraData(MediaByteBuffer* aExtraData);
void OnDecoderInitDone(const TrackType aTrackType);
void OnDecoderInitFailed(MediaResult aError);
RefPtr<PlatformDecoderModule> mPDM;
- VideoInfo mOriginalConfig;
VideoInfo mCurrentConfig;
layers::LayersBackend mLayersBackend;
RefPtr<layers::ImageContainer> mImageContainer;
const RefPtr<TaskQueue> mTaskQueue;
nsTArray<RefPtr<MediaRawData>> mMediaRawSamples;
MediaDataDecoderCallback* mCallback;
RefPtr<MediaDataDecoder> mDecoder;
MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;