Bug 1295921 - P8: Extract BlankMediaDataDecoder so it can be shared. r?jwwang
Change name to 'Dummy' to signify it's base for decoders that don't
decode.
MozReview-Commit-ID: 8RY8eKpWJE3
--- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp
@@ -1,14 +1,15 @@
/* -*- 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 "ImageContainer.h"
#include "MediaDecoderReader.h"
#include "MediaInfo.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/mozalloc.h" // for operator new, and new (fallible)
#include "mozilla/RefPtr.h"
#include "mozilla/TaskQueue.h"
#include "mp4_demuxer/AnnexB.h"
@@ -20,109 +21,31 @@
#include "ReorderQueue.h"
#include "TimeUnits.h"
#include "VideoUtils.h"
namespace mozilla {
// Decoder that uses a passed in object's Create function to create blank
// MediaData objects.
-template<class BlankMediaDataCreator>
-class BlankMediaDataDecoder : public MediaDataDecoder {
-public:
- BlankMediaDataDecoder(BlankMediaDataCreator* aCreator,
- const CreateDecoderParams& aParams)
- : mCreator(aCreator)
- , mCallback(aParams.mCallback)
- , mMaxRefFrames(aParams.mConfig.GetType() == TrackInfo::kVideoTrack &&
- MP4Decoder::IsH264(aParams.mConfig.mMimeType)
- ? mp4_demuxer::AnnexB::HasSPS(aParams.VideoConfig().mExtraData)
- ? mp4_demuxer::H264::ComputeMaxRefFrames(aParams.VideoConfig().mExtraData)
- : 16
- : 0)
- , mType(aParams.mConfig.GetType())
- {
- }
-
- RefPtr<InitPromise> Init() override {
- return InitPromise::CreateAndResolve(mType, __func__);
- }
-
- void Shutdown() override {}
-
- void Input(MediaRawData* aSample) override
- {
- RefPtr<MediaData> data =
- mCreator->Create(media::TimeUnit::FromMicroseconds(aSample->mTime),
- media::TimeUnit::FromMicroseconds(aSample->mDuration),
- aSample->mOffset);
-
- OutputFrame(data);
- }
-
- void Flush() override
- {
- mReorderQueue.Clear();
- }
-
- void Drain() override
- {
- while (!mReorderQueue.IsEmpty()) {
- mCallback->Output(mReorderQueue.Pop().get());
- }
-
- mCallback->DrainComplete();
- }
-
- const char* GetDescriptionName() const override
- {
- return "blank media data decoder";
- }
-
-private:
- void OutputFrame(MediaData* aData)
- {
- if (!aData) {
- mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
- return;
- }
-
- // Frames come out in DTS order but we need to output them in PTS order.
- mReorderQueue.Push(aData);
-
- while (mReorderQueue.Length() > mMaxRefFrames) {
- mCallback->Output(mReorderQueue.Pop().get());
- }
- mCallback->InputExhausted();
- }
-
-private:
- nsAutoPtr<BlankMediaDataCreator> mCreator;
- MediaDataDecoderCallback* mCallback;
- const uint32_t mMaxRefFrames;
- ReorderQueue mReorderQueue;
- TrackInfo::TrackType mType;
-};
-
-class BlankVideoDataCreator {
+class BlankVideoDataCreator : public DummyDataCreator {
public:
BlankVideoDataCreator(uint32_t aFrameWidth,
uint32_t aFrameHeight,
layers::ImageContainer* aImageContainer)
: mFrameWidth(aFrameWidth)
, mFrameHeight(aFrameHeight)
, mImageContainer(aImageContainer)
{
mInfo.mDisplay = nsIntSize(mFrameWidth, mFrameHeight);
mPicture = gfx::IntRect(0, 0, mFrameWidth, mFrameHeight);
}
- already_AddRefed<MediaData>
- Create(const media::TimeUnit& aDTS, const media::TimeUnit& aDuration, int64_t aOffsetInStream)
+ already_AddRefed<MediaData> Create(MediaRawData* aSample)
{
// 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,
// 2x2 subsampled.
const int sizeY = mFrameWidth * mFrameHeight;
const int sizeCbCr = ((mFrameWidth + 1) / 2) * ((mFrameHeight + 1) / 2);
auto frame = MakeUnique<uint8_t[]>(sizeY + sizeCbCr);
VideoData::YCbCrBuffer buffer;
@@ -152,48 +75,45 @@ public:
buffer.mPlanes[2].mSkip = 0;
// Set to color white.
memset(buffer.mPlanes[0].mData, 255, sizeY);
memset(buffer.mPlanes[1].mData, 128, sizeCbCr);
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);
}
private:
VideoInfo mInfo;
gfx::IntRect mPicture;
uint32_t mFrameWidth;
uint32_t mFrameHeight;
RefPtr<layers::ImageContainer> mImageContainer;
};
-class BlankAudioDataCreator {
+class BlankAudioDataCreator : public DummyDataCreator {
public:
BlankAudioDataCreator(uint32_t aChannelCount, uint32_t aSampleRate)
: mFrameSum(0), mChannelCount(aChannelCount), mSampleRate(aSampleRate)
{
}
- MediaData* Create(const media::TimeUnit& aDTS,
- const media::TimeUnit& aDuration,
- int64_t aOffsetInStream)
+ already_AddRefed<MediaData> 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 ||
frames.value() > (UINT32_MAX / mChannelCount)) {
return nullptr;
}
AlignedAudioBuffer samples(frames.value() * mChannelCount);
if (!samples) {
@@ -204,54 +124,59 @@ public:
static const float noteHz = 440.0f;
for (int i = 0; i < frames.value(); i++) {
float f = sin(2 * pi * noteHz * mFrameSum / mSampleRate);
for (unsigned c = 0; c < mChannelCount; c++) {
samples[i * mChannelCount + c] = AudioDataValue(f);
}
mFrameSum++;
}
- return new AudioData(aOffsetInStream,
- aDTS.ToMicroseconds(),
- aDuration.ToMicroseconds(),
- uint32_t(frames.value()),
- Move(samples),
- mChannelCount,
- mSampleRate);
+ RefPtr<AudioData> a(new AudioData(aSample->mOffset,
+ aSample->mTime,
+ aSample->mDuration,
+ uint32_t(frames.value()),
+ Move(samples),
+ mChannelCount,
+ mSampleRate));
+ return a.forget();
}
private:
int64_t mFrameSum;
uint32_t mChannelCount;
uint32_t mSampleRate;
};
class BlankDecoderModule : public PlatformDecoderModule {
public:
// Decode thread.
already_AddRefed<MediaDataDecoder>
CreateVideoDecoder(const CreateDecoderParams& aParams) override {
const VideoInfo& config = aParams.VideoConfig();
- BlankVideoDataCreator* creator = new BlankVideoDataCreator(
- config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer);
+ auto creator = UniquePtr<DummyDataCreator>{
+ MakeUnique<BlankVideoDataCreator>(config.mDisplay.width,
+ config.mDisplay.height,
+ aParams.mImageContainer)
+ };
RefPtr<MediaDataDecoder> decoder =
- new BlankMediaDataDecoder<BlankVideoDataCreator>(creator, aParams);
+ new DummyMediaDataDecoder(Move(creator), "blank media data decoder", aParams);
return decoder.forget();
}
// Decode thread.
already_AddRefed<MediaDataDecoder>
CreateAudioDecoder(const CreateDecoderParams& aParams) override {
const AudioInfo& config = aParams.AudioConfig();
- BlankAudioDataCreator* creator = new BlankAudioDataCreator(
- config.mChannels, config.mRate);
+ auto creator = UniquePtr<DummyDataCreator>{
+ MakeUnique<BlankAudioDataCreator>(config.mChannels, config.mRate)
+ };
RefPtr<MediaDataDecoder> decoder =
- new BlankMediaDataDecoder<BlankAudioDataCreator>(creator, aParams);
+ new DummyMediaDataDecoder(Move(creator), "blank media data decoder", aParams);
return decoder.forget();
}
bool
SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override
{
return true;
new file mode 100644
--- /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"
+#include "MP4Decoder.h"
+
+namespace mozilla {
+
+DummyDataCreator::~DummyDataCreator()
+{ }
+
+DummyMediaDataDecoder::DummyMediaDataDecoder(UniquePtr<DummyDataCreator>&& aCreator,
+ const char* aDescription,
+ const CreateDecoderParams& aParams)
+ : mCreator(Move(aCreator))
+ , mCallback(aParams.mCallback)
+ , mMaxRefFrames(
+ aParams.mConfig.GetType() == TrackInfo::kVideoTrack &&
+ MP4Decoder::IsH264(aParams.mConfig.mMimeType)
+ ? mp4_demuxer::AnnexB::HasSPS(aParams.VideoConfig().mExtraData)
+ ? mp4_demuxer::H264::ComputeMaxRefFrames(
+ aParams.VideoConfig().mExtraData)
+ : 16
+ : 0)
+ , mType(aParams.mConfig.GetType())
+ , mDescription(aDescription)
+{
+}
+
+RefPtr<DummyMediaDataDecoder::InitPromise>
+DummyMediaDataDecoder::Init()
+{
+ return InitPromise::CreateAndResolve(mType, __func__);
+}
+
+void
+DummyMediaDataDecoder::Shutdown()
+{
+}
+
+void
+DummyMediaDataDecoder::Input(MediaRawData* aSample)
+{
+ RefPtr<MediaData> data = mCreator->Create(aSample);
+ OutputFrame(data);
+}
+
+void
+DummyMediaDataDecoder::Flush()
+{
+ mReorderQueue.Clear();
+}
+
+void
+DummyMediaDataDecoder::Drain()
+{
+ while (!mReorderQueue.IsEmpty()) {
+ mCallback->Output(mReorderQueue.Pop().get());
+ }
+
+ mCallback->DrainComplete();
+}
+
+const char*
+DummyMediaDataDecoder::GetDescriptionName() const
+{
+ return mDescription.get();
+}
+
+void
+DummyMediaDataDecoder::OutputFrame(MediaData* aData)
+{
+ if (!aData) {
+ mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
+ return;
+ }
+
+ // Frames come out in DTS order but we need to output them in PTS order.
+ mReorderQueue.Push(aData);
+
+ while (mReorderQueue.Length() > mMaxRefFrames) {
+ mCallback->Output(mReorderQueue.Pop().get());
+ }
+ mCallback->InputExhausted();
+}
+
+} // namespace Mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/platforms/agnostic/DummyMediaDataDecoder.h
@@ -0,0 +1,56 @@
+/* -*- 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 "PlatformDecoderModule.h"
+#include "ReorderQueue.h"
+
+namespace mozilla {
+
+class MediaData;
+
+class DummyDataCreator {
+public:
+ virtual ~DummyDataCreator();
+ virtual already_AddRefed<MediaData> Create(MediaRawData* aSample) = 0;
+};
+
+// Decoder that uses a passed in object's Create function to create Null
+// MediaData objects.
+class DummyMediaDataDecoder : public MediaDataDecoder {
+public:
+
+ typedef MediaDataDecoder::InitPromise InitPromise;
+
+ DummyMediaDataDecoder(UniquePtr<DummyDataCreator>&& aCreator,
+ const char* aDescription,
+ const CreateDecoderParams& aParams);
+
+ RefPtr<InitPromise> Init() override;
+ void Shutdown() override;
+
+ void Input(MediaRawData* aSample) override;
+ void Flush() override;
+ void Drain() override;
+
+ const char* GetDescriptionName() const override;
+
+private:
+ void OutputFrame(MediaData* aData);
+
+private:
+ UniquePtr<DummyDataCreator> mCreator;
+ MediaDataDecoderCallback* mCallback;
+ const uint32_t mMaxRefFrames;
+ ReorderQueue mReorderQueue;
+ TrackInfo::TrackType mType;
+ nsCString mDescription;
+};
+
+} // namespace mozilla
+
+#endif // !defined(DummyMediaDataDecoder_h_)
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -1,30 +1,32 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS += [
'agnostic/AgnosticDecoderModule.h',
+ 'agnostic/DummyMediaDataDecoder.h',
'agnostic/OpusDecoder.h',
'agnostic/TheoraDecoder.h',
'agnostic/VorbisDecoder.h',
'agnostic/VPXDecoder.h',
'MediaTelemetryConstants.h',
'PDMFactory.h',
'PlatformDecoderModule.h',
'wrappers/FuzzingWrapper.h',
'wrappers/H264Converter.h'
]
UNIFIED_SOURCES += [
'agnostic/AgnosticDecoderModule.cpp',
'agnostic/BlankDecoderModule.cpp',
+ 'agnostic/DummyMediaDataDecoder.cpp',
'agnostic/OpusDecoder.cpp',
'agnostic/TheoraDecoder.cpp',
'agnostic/VorbisDecoder.cpp',
'agnostic/VPXDecoder.cpp',
'agnostic/WAVDecoder.cpp',
'PDMFactory.cpp',
'wrappers/FuzzingWrapper.cpp',
'wrappers/H264Converter.cpp'
--- a/dom/media/platforms/wrappers/FuzzingWrapper.cpp
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.cpp
@@ -1,15 +1,16 @@
/* -*- 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 "FuzzingWrapper.h"
+#include "mozilla/SharedThreadPool.h"
mozilla::LogModule* GetFuzzingWrapperLog() {
static mozilla::LazyLogModule log("MediaFuzzingWrapper");
return log;
}
#define DFW_LOGD(arg, ...) MOZ_LOG(GetFuzzingWrapperLog(), mozilla::LogLevel::Debug, ("DecoderFuzzingWrapper(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
#define DFW_LOGV(arg, ...) MOZ_LOG(GetFuzzingWrapperLog(), mozilla::LogLevel::Verbose, ("DecoderFuzzingWrapper(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
#define CFW_LOGD(arg, ...) MOZ_LOG(GetFuzzingWrapperLog(), mozilla::LogLevel::Debug, ("DecoderCallbackFuzzingWrapper(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -2,16 +2,17 @@
/* 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 "mozilla/TaskQueue.h"
#include "H264Converter.h"
+#include "DecoderDoctorDiagnostics.h"
#include "ImageContainer.h"
#include "MediaInfo.h"
#include "MediaPrefs.h"
#include "mp4_demuxer/AnnexB.h"
#include "mp4_demuxer/H264.h"
namespace mozilla
{