diff --git a/dom/media/platforms/agnostic/BlankDecoderModule.cpp b/dom/media/platforms/agnostic/BlankDecoderModule.cpp index 1f35eeb7ebb3..6e8f23f3fdeb 100644 --- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp +++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp @@ -4,114 +4,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "mozilla/CheckedInt.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/RefPtr.h" +#include "nsRect.h" +#include "nsSize.h" +#include "DummyMediaDataDecoder.h" #include "ImageContainer.h" -#include "MP4Decoder.h" -#include "MediaDecoderReader.h" +#include "MediaData.h" #include "MediaInfo.h" #include "PlatformDecoderModule.h" -#include "ReorderQueue.h" -#include "TimeUnits.h" #include "VideoUtils.h" -#include "mozilla/CheckedInt.h" -#include "mozilla/RefPtr.h" -#include "mozilla/TaskQueue.h" -#include "mozilla/mozalloc.h" // for operator new, and new (fallible) -#include "mp4_demuxer/AnnexB.h" -#include "mp4_demuxer/H264.h" -#include "nsAutoPtr.h" -#include "nsRect.h" namespace mozilla { -// Decoder that uses a passed in object's Create function to create blank -// MediaData objects. -template -class BlankMediaDataDecoder : public MediaDataDecoder -{ -public: - BlankMediaDataDecoder(BlankMediaDataCreator* aCreator, - const CreateDecoderParams& aParams) - : mCreator(aCreator) - , mIsH264(MP4Decoder::IsH264(aParams.mConfig.mMimeType)) - , mMaxRefFrames( - mIsH264 - ? mp4_demuxer::AnnexB::HasSPS(aParams.VideoConfig().mExtraData) - ? mp4_demuxer::H264::ComputeMaxRefFrames( - aParams.VideoConfig().mExtraData) - : 16 - : 0) - , mType(aParams.mConfig.GetType()) - { - } - - RefPtr Init() override - { - return InitPromise::CreateAndResolve(mType, __func__); - } - - RefPtr Shutdown() override - { - return ShutdownPromise::CreateAndResolve(true, __func__); - } - - RefPtr Decode(MediaRawData* aSample) override - { - RefPtr data = - mCreator->Create(media::TimeUnit::FromMicroseconds(aSample->mTime), - media::TimeUnit::FromMicroseconds(aSample->mDuration), - aSample->mOffset); - - if (!data) { - return DecodePromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY, __func__); - } - - // Frames come out in DTS order but we need to output them in PTS order. - mReorderQueue.Push(data); - - if (mReorderQueue.Length() > mMaxRefFrames) { - return DecodePromise::CreateAndResolve( - DecodedData{ mReorderQueue.Pop().get() }, __func__); - } - return DecodePromise::CreateAndResolve(DecodedData(), __func__); - } - - RefPtr Drain() override - { - DecodedData samples; - while (!mReorderQueue.IsEmpty()) { - samples.AppendElement(mReorderQueue.Pop().get()); - } - return DecodePromise::CreateAndResolve(samples, __func__); - } - - RefPtr Flush() override - { - mReorderQueue.Clear(); - return FlushPromise::CreateAndResolve(true, __func__); - } - - const char* GetDescriptionName() const override - { - return "blank media data decoder"; - } - - ConversionRequired NeedsConversion() const override - { - return mIsH264 - ? ConversionRequired::kNeedAVCC - : ConversionRequired::kNeedNone; - } - -private: - nsAutoPtr mCreator; - const bool mIsH264; - const uint32_t mMaxRefFrames; - ReorderQueue mReorderQueue; - TrackInfo::TrackType mType; -}; - -class BlankVideoDataCreator -{ +class BlankVideoDataCreator : public DummyDataCreator { public: BlankVideoDataCreator(uint32_t aFrameWidth, uint32_t aFrameHeight, @@ -124,9 +31,7 @@ public: mPicture = gfx::IntRect(0, 0, mFrameWidth, mFrameHeight); } - already_AddRefed Create(const media::TimeUnit& aDTS, - const media::TimeUnit& aDuration, - int64_t aOffsetInStream) + already_AddRefed Create(MediaRawData* aSample) override { // Create a fake YUV buffer in a 420 format. That is, an 8bpp Y plane, // with a U and V plane that are half the size of the Y plane, i.e 8 bit, @@ -166,12 +71,12 @@ public: return VideoData::CreateAndCopyData(mInfo, mImageContainer, - aOffsetInStream, - aDTS.ToMicroseconds(), - aDuration.ToMicroseconds(), + aSample->mOffset, + aSample->mTime, + aSample->mDuration, buffer, - true, - aDTS.ToMicroseconds(), + aSample->mKeyframe, + aSample->mTime, mPicture); } @@ -183,7 +88,7 @@ private: RefPtr mImageContainer; }; -class BlankAudioDataCreator +class BlankAudioDataCreator : public DummyDataCreator { public: BlankAudioDataCreator(uint32_t aChannelCount, uint32_t aSampleRate) @@ -191,14 +96,11 @@ public: { } - MediaData* Create(const media::TimeUnit& aDTS, - const media::TimeUnit& aDuration, - int64_t aOffsetInStream) + already_AddRefed Create(MediaRawData* aSample) override { // Convert duration to frames. We add 1 to duration to account for // rounding errors, so we get a consistent tone. - CheckedInt64 frames = - UsecsToFrames(aDuration.ToMicroseconds()+1, mSampleRate); + CheckedInt64 frames = UsecsToFrames(aSample->mDuration+1, mSampleRate); if (!frames.isValid() || !mChannelCount || !mSampleRate @@ -219,13 +121,14 @@ public: } mFrameSum++; } - return new AudioData(aOffsetInStream, - aDTS.ToMicroseconds(), - aDuration.ToMicroseconds(), - uint32_t(frames.value()), - Move(samples), - mChannelCount, - mSampleRate); + RefPtr data(new AudioData(aSample->mOffset, + aSample->mTime, + aSample->mDuration, + uint32_t(frames.value()), + Move(samples), + mChannelCount, + mSampleRate)); + return data.forget(); } private: @@ -243,10 +146,10 @@ public: CreateVideoDecoder(const CreateDecoderParams& aParams) override { const VideoInfo& config = aParams.VideoConfig(); - BlankVideoDataCreator* creator = new BlankVideoDataCreator( - config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer); + UniquePtr creator = + MakeUnique(config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer); RefPtr decoder = - new BlankMediaDataDecoder(creator, aParams); + new DummyMediaDataDecoder(Move(creator), "blank media data decoder", aParams); return decoder.forget(); } @@ -255,11 +158,10 @@ public: CreateAudioDecoder(const CreateDecoderParams& aParams) override { const AudioInfo& config = aParams.AudioConfig(); - BlankAudioDataCreator* creator = new BlankAudioDataCreator( - config.mChannels, config.mRate); - + UniquePtr creator = + MakeUnique(config.mChannels, config.mRate); RefPtr decoder = - new BlankMediaDataDecoder(creator, aParams); + new DummyMediaDataDecoder(Move(creator), "blank media data decoder", aParams); return decoder.forget(); } diff --git a/dom/media/platforms/agnostic/DummyMediaDataDecoder.cpp b/dom/media/platforms/agnostic/DummyMediaDataDecoder.cpp new file mode 100644 index 000000000000..fa11d760bc3d --- /dev/null +++ b/dom/media/platforms/agnostic/DummyMediaDataDecoder.cpp @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "DummyMediaDataDecoder.h" +#include "mp4_demuxer/AnnexB.h" +#include "mp4_demuxer/H264.h" + +namespace mozilla { + +DummyDataCreator::~DummyDataCreator() {} + +DummyMediaDataDecoder::DummyMediaDataDecoder(UniquePtr&& aCreator, + const char* aDescription, + const CreateDecoderParams& aParams) + : mCreator(Move(aCreator)) + , mIsH264(MP4Decoder::IsH264(aParams.mConfig.mMimeType)) + , mMaxRefFrames( + mIsH264 + ? mp4_demuxer::AnnexB::HasSPS(aParams.VideoConfig().mExtraData) + ? mp4_demuxer::H264::ComputeMaxRefFrames(aParams.VideoConfig().mExtraData) + : 16 + : 0) + , mType(aParams.mConfig.GetType()) + , mDescription(aDescription) +{ +} + +RefPtr +DummyMediaDataDecoder::Init() +{ + return InitPromise::CreateAndResolve(mType, __func__); +} + +RefPtr +DummyMediaDataDecoder::Shutdown() +{ + return ShutdownPromise::CreateAndResolve(true, __func__); +} + +RefPtr +DummyMediaDataDecoder::Decode(MediaRawData* aSample) +{ + RefPtr data = mCreator->Create(aSample); + + if (!data) { + return DecodePromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY, __func__); + } + + // Frames come out in DTS order but we need to output them in PTS order. + mReorderQueue.Push(data); + + if (mReorderQueue.Length() > mMaxRefFrames) { + return DecodePromise::CreateAndResolve( + DecodedData{ mReorderQueue.Pop().get() }, __func__); + } + return DecodePromise::CreateAndResolve(DecodedData(), __func__); +} + +RefPtr +DummyMediaDataDecoder::Drain() +{ + DecodedData samples; + while (!mReorderQueue.IsEmpty()) { + samples.AppendElement(mReorderQueue.Pop().get()); + } + return DecodePromise::CreateAndResolve(samples, __func__); +} + +RefPtr +DummyMediaDataDecoder::Flush() +{ + mReorderQueue.Clear(); + return FlushPromise::CreateAndResolve(true, __func__); +} + +const char* +DummyMediaDataDecoder::GetDescriptionName() const +{ + return "blank media data decoder"; +} + +MediaDataDecoder::ConversionRequired +DummyMediaDataDecoder::NeedsConversion() const +{ + return mIsH264 + ? ConversionRequired::kNeedAVCC + : ConversionRequired::kNeedNone; +} + +} // namespace mozilla diff --git a/dom/media/platforms/agnostic/DummyMediaDataDecoder.h b/dom/media/platforms/agnostic/DummyMediaDataDecoder.h new file mode 100644 index 000000000000..4d0f58d7cba9 --- /dev/null +++ b/dom/media/platforms/agnostic/DummyMediaDataDecoder.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if !defined(DummyMediaDataDecoder_h_) +#define DummyMediaDataDecoder_h_ + +#include "MediaInfo.h" +#include "mozilla/UniquePtr.h" +#include "PlatformDecoderModule.h" +#include "ReorderQueue.h" + +namespace mozilla { + +class MediaRawData; + +class DummyDataCreator +{ +public: + virtual ~DummyDataCreator(); + virtual already_AddRefed Create(MediaRawData* aSample) = 0; +}; + +// Decoder that uses a passed in object's Create function to create Null +// MediaData objects. +class DummyMediaDataDecoder : public MediaDataDecoder +{ +public: + DummyMediaDataDecoder(UniquePtr&& aCreator, + const char* aDescription, + const CreateDecoderParams& aParams); + + RefPtr Init() override; + + RefPtr Shutdown() override; + + RefPtr Decode(MediaRawData* aSample) override; + + RefPtr Drain() override; + + RefPtr Flush() override; + + const char* GetDescriptionName() const override; + + ConversionRequired NeedsConversion() const override; + +private: + UniquePtr mCreator; + const bool mIsH264; + const uint32_t mMaxRefFrames; + ReorderQueue mReorderQueue; + TrackInfo::TrackType mType; + nsCString mDescription; +}; + +} // namespace mozilla + +#endif // !defined(DummyMediaDataDecoder_h_) diff --git a/dom/media/platforms/moz.build b/dom/media/platforms/moz.build index 5e3a1da1d970..a42d51996c95 100644 --- a/dom/media/platforms/moz.build +++ b/dom/media/platforms/moz.build @@ -6,6 +6,7 @@ EXPORTS += [ 'agnostic/AgnosticDecoderModule.h', + 'agnostic/DummyMediaDataDecoder.h', 'agnostic/OpusDecoder.h', 'agnostic/TheoraDecoder.h', 'agnostic/VorbisDecoder.h', @@ -22,6 +23,7 @@ EXPORTS += [ UNIFIED_SOURCES += [ 'agnostic/AgnosticDecoderModule.cpp', 'agnostic/BlankDecoderModule.cpp', + 'agnostic/DummyMediaDataDecoder.cpp', 'agnostic/OpusDecoder.cpp', 'agnostic/TheoraDecoder.cpp', 'agnostic/VorbisDecoder.cpp',