mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Backed out 6 changesets (bug 1346120) for autophone Mdm tests failure in test_background_video_drawimage_with_suspended_video.html
Backed out changeset a30c73fc8d69 (bug 1346120) Backed out changeset f16556658fd9 (bug 1346120) Backed out changeset 98d212462786 (bug 1346120) Backed out changeset ba579adbed21 (bug 1346120) Backed out changeset c0758b9bf7b5 (bug 1346120) Backed out changeset 94a483ef784e (bug 1346120)
This commit is contained in:
parent
b3ae464548
commit
7f4987cc26
@ -260,10 +260,10 @@ public:
|
||||
return mOnTrackWaitingForKey;
|
||||
}
|
||||
|
||||
// Switch the video decoder to NullDecoderModule. It might takes effective
|
||||
// Switch the video decoder to BlankDecoderModule. It might takes effective
|
||||
// since a few samples later depends on how much demuxed samples are already
|
||||
// queued in the original video decoder.
|
||||
virtual void SetVideoNullDecode(bool aIsNullDecode) { }
|
||||
virtual void SetVideoBlankDecode(bool aIsBlankDecode) { }
|
||||
|
||||
protected:
|
||||
virtual ~MediaDecoderReader();
|
||||
|
@ -148,7 +148,7 @@ MediaDecoderReaderWrapper::SetVideoBlankDecode(bool aIsBlankDecode)
|
||||
{
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
NewRunnableMethod<bool>(mReader, &MediaDecoderReader::SetVideoNullDecode,
|
||||
NewRunnableMethod<bool>(mReader, &MediaDecoderReader::SetVideoBlankDecode,
|
||||
aIsBlankDecode);
|
||||
mReader->OwnerThread()->Dispatch(r.forget());
|
||||
}
|
||||
|
@ -665,7 +665,7 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(Data& aData)
|
||||
: *ownerData.mOriginalInfo->GetAsAudioInfo(),
|
||||
ownerData.mTaskQueue,
|
||||
mOwner->mCrashHelper,
|
||||
ownerData.mIsNullDecode,
|
||||
ownerData.mIsBlankDecode,
|
||||
&result,
|
||||
TrackInfo::kAudioTrack,
|
||||
&mOwner->OnTrackWaitingForKeyProducer()
|
||||
@ -684,7 +684,7 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(Data& aData)
|
||||
mOwner->mKnowsCompositor,
|
||||
mOwner->GetImageContainer(),
|
||||
mOwner->mCrashHelper,
|
||||
ownerData.mIsNullDecode,
|
||||
ownerData.mIsBlankDecode,
|
||||
&result,
|
||||
TrackType::kVideoTrack,
|
||||
&mOwner->OnTrackWaitingForKeyProducer()
|
||||
@ -3047,26 +3047,26 @@ MediaFormatReader::GetMozDebugReaderData(nsACString& aString)
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::SetVideoNullDecode(bool aIsNullDecode)
|
||||
MediaFormatReader::SetVideoBlankDecode(bool aIsBlankDecode)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
return SetNullDecode(TrackType::kVideoTrack, aIsNullDecode);
|
||||
return SetBlankDecode(TrackType::kVideoTrack, aIsBlankDecode);
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::SetNullDecode(TrackType aTrack, bool aIsNullDecode)
|
||||
MediaFormatReader::SetBlankDecode(TrackType aTrack, bool aIsBlankDecode)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
if (decoder.mIsNullDecode == aIsNullDecode) {
|
||||
if (decoder.mIsBlankDecode == aIsBlankDecode) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG("%s, decoder.mIsNullDecode = %d => aIsNullDecode = %d",
|
||||
TrackTypeToStr(aTrack), decoder.mIsNullDecode, aIsNullDecode);
|
||||
LOG("%s, decoder.mIsBlankDecode = %d => aIsBlankDecode = %d",
|
||||
TrackTypeToStr(aTrack), decoder.mIsBlankDecode, aIsBlankDecode);
|
||||
|
||||
decoder.mIsNullDecode = aIsNullDecode;
|
||||
decoder.mIsBlankDecode = aIsBlankDecode;
|
||||
ShutdownDecoder(aTrack);
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
// Used for debugging purposes.
|
||||
void GetMozDebugReaderData(nsACString& aString);
|
||||
|
||||
void SetVideoNullDecode(bool aIsNullDecode) override;
|
||||
void SetVideoBlankDecode(bool aIsBlankDecode) override;
|
||||
|
||||
private:
|
||||
nsresult InitInternal() override;
|
||||
@ -204,7 +204,7 @@ private:
|
||||
, mSizeOfQueue(0)
|
||||
, mIsHardwareAccelerated(false)
|
||||
, mLastStreamSourceID(UINT32_MAX)
|
||||
, mIsNullDecode(false)
|
||||
, mIsBlankDecode(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -386,8 +386,8 @@ private:
|
||||
UniquePtr<TrackInfo> mOriginalInfo;
|
||||
RefPtr<TrackInfoSharedPtr> mInfo;
|
||||
Maybe<media::TimeUnit> mFirstDemuxedSampleTime;
|
||||
// Use NullDecoderModule or not.
|
||||
bool mIsNullDecode;
|
||||
// Use BlankDecoderModule or not.
|
||||
bool mIsBlankDecode;
|
||||
|
||||
};
|
||||
|
||||
@ -531,7 +531,7 @@ private:
|
||||
|
||||
RefPtr<GMPCrashHelper> mCrashHelper;
|
||||
|
||||
void SetNullDecode(TrackType aTrack, bool aIsNullDecode);
|
||||
void SetBlankDecode(TrackType aTrack, bool aIsBlankDecode);
|
||||
|
||||
class DecoderFactory;
|
||||
UniquePtr<DecoderFactory> mDecoderFactory;
|
||||
|
@ -400,10 +400,7 @@ VideoSink::RenderVideoFrames(int32_t aMaxFrames,
|
||||
VSINK_LOG_V("playing video frame %" PRId64 " (id=%x) (vq-queued=%" PRIuSIZE ")",
|
||||
frame->mTime, frame->mFrameID, VideoQueue().GetSize());
|
||||
}
|
||||
|
||||
if (images.Length() > 0) {
|
||||
mContainer->SetCurrentFrames(frames[0]->As<VideoData>()->mDisplay, images);
|
||||
}
|
||||
mContainer->SetCurrentFrames(frames[0]->As<VideoData>()->mDisplay, images);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -53,7 +53,6 @@ namespace mozilla {
|
||||
|
||||
extern already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule();
|
||||
extern already_AddRefed<PlatformDecoderModule> CreateBlankDecoderModule();
|
||||
extern already_AddRefed<PlatformDecoderModule> CreateNullDecoderModule();
|
||||
|
||||
class PDMFactoryImpl final
|
||||
{
|
||||
@ -164,7 +163,7 @@ PDMFactory::PDMFactory()
|
||||
{
|
||||
EnsureInit();
|
||||
CreatePDMs();
|
||||
CreateNullPDM();
|
||||
CreateBlankPDM();
|
||||
}
|
||||
|
||||
PDMFactory::~PDMFactory()
|
||||
@ -204,9 +203,9 @@ PDMFactory::EnsureInit() const
|
||||
already_AddRefed<MediaDataDecoder>
|
||||
PDMFactory::CreateDecoder(const CreateDecoderParams& aParams)
|
||||
{
|
||||
if (aParams.mUseNullDecoder) {
|
||||
MOZ_ASSERT(mNullPDM);
|
||||
return CreateDecoderWithPDM(mNullPDM, aParams);
|
||||
if (aParams.mUseBlankDecoder) {
|
||||
MOZ_ASSERT(mBlankPDM);
|
||||
return CreateDecoderWithPDM(mBlankPDM, aParams);
|
||||
}
|
||||
|
||||
const TrackInfo& config = aParams.mConfig;
|
||||
@ -291,7 +290,7 @@ PDMFactory::CreateDecoderWithPDM(PlatformDecoderModule* aPDM,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (MP4Decoder::IsH264(config.mMimeType) && !aParams.mUseNullDecoder) {
|
||||
if (MP4Decoder::IsH264(config.mMimeType) && !aParams.mUseBlankDecoder) {
|
||||
RefPtr<H264Converter> h = new H264Converter(aPDM, aParams);
|
||||
const nsresult rv = h->GetLastError();
|
||||
if (NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_INITIALIZED) {
|
||||
@ -403,10 +402,10 @@ PDMFactory::CreatePDMs()
|
||||
}
|
||||
|
||||
void
|
||||
PDMFactory::CreateNullPDM()
|
||||
PDMFactory::CreateBlankPDM()
|
||||
{
|
||||
mNullPDM = CreateNullDecoderModule();
|
||||
MOZ_ASSERT(mNullPDM && NS_SUCCEEDED(mNullPDM->Startup()));
|
||||
mBlankPDM = CreateBlankDecoderModule();
|
||||
MOZ_ASSERT(mBlankPDM && NS_SUCCEEDED(mBlankPDM->Startup()));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
private:
|
||||
virtual ~PDMFactory();
|
||||
void CreatePDMs();
|
||||
void CreateNullPDM();
|
||||
void CreateBlankPDM();
|
||||
// Startup the provided PDM and add it to our list if successful.
|
||||
bool StartupPDM(PlatformDecoderModule* aPDM);
|
||||
// Returns the first PDM in our list supporting the mimetype.
|
||||
@ -67,7 +67,7 @@ private:
|
||||
|
||||
nsTArray<RefPtr<PlatformDecoderModule>> mCurrentPDMs;
|
||||
RefPtr<PlatformDecoderModule> mEMEPDM;
|
||||
RefPtr<PlatformDecoderModule> mNullPDM;
|
||||
RefPtr<PlatformDecoderModule> mBlankPDM;
|
||||
|
||||
bool mWMFFailedToLoad = false;
|
||||
bool mFFmpegFailedToLoad = false;
|
||||
|
@ -85,7 +85,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final
|
||||
MediaResult* mError = nullptr;
|
||||
RefPtr<layers::KnowsCompositor> mKnowsCompositor;
|
||||
RefPtr<GMPCrashHelper> mCrashHelper;
|
||||
bool mUseNullDecoder = false;
|
||||
bool mUseBlankDecoder = false;
|
||||
TrackInfo::TrackType mType = TrackInfo::kUndefinedTrack;
|
||||
MediaEventProducer<TrackInfo::TrackType>* mOnWaitingForKeyEvent = nullptr;
|
||||
OptionSet mOptions = OptionSet(Option::Default);
|
||||
@ -102,7 +102,7 @@ private:
|
||||
}
|
||||
void Set(MediaResult* aError) { mError = aError; }
|
||||
void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
|
||||
void Set(bool aUseNullDecoder) { mUseNullDecoder = aUseNullDecoder; }
|
||||
void Set(bool aUseBlankDecoder) { mUseBlankDecoder = aUseBlankDecoder; }
|
||||
void Set(OptionSet aOptions) { mOptions = aOptions; }
|
||||
void Set(layers::KnowsCompositor* aKnowsCompositor)
|
||||
{
|
||||
|
@ -4,21 +4,114 @@
|
||||
* 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 "MediaData.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "MediaDecoderReader.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 {
|
||||
|
||||
class BlankVideoDataCreator : public DummyDataCreator {
|
||||
// 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)
|
||||
, 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<InitPromise> Init() override
|
||||
{
|
||||
return InitPromise::CreateAndResolve(mType, __func__);
|
||||
}
|
||||
|
||||
RefPtr<ShutdownPromise> Shutdown() override
|
||||
{
|
||||
return ShutdownPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
RefPtr<DecodePromise> Decode(MediaRawData* aSample) override
|
||||
{
|
||||
RefPtr<MediaData> 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<DecodePromise> Drain() override
|
||||
{
|
||||
DecodedData samples;
|
||||
while (!mReorderQueue.IsEmpty()) {
|
||||
samples.AppendElement(mReorderQueue.Pop().get());
|
||||
}
|
||||
return DecodePromise::CreateAndResolve(samples, __func__);
|
||||
}
|
||||
|
||||
RefPtr<FlushPromise> 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<BlankMediaDataCreator> mCreator;
|
||||
const bool mIsH264;
|
||||
const uint32_t mMaxRefFrames;
|
||||
ReorderQueue mReorderQueue;
|
||||
TrackInfo::TrackType mType;
|
||||
};
|
||||
|
||||
class BlankVideoDataCreator
|
||||
{
|
||||
public:
|
||||
BlankVideoDataCreator(uint32_t aFrameWidth,
|
||||
uint32_t aFrameHeight,
|
||||
@ -31,14 +124,16 @@ public:
|
||||
mPicture = gfx::IntRect(0, 0, mFrameWidth, mFrameHeight);
|
||||
}
|
||||
|
||||
already_AddRefed<MediaData> Create(MediaRawData* aSample) override
|
||||
already_AddRefed<MediaData> Create(const media::TimeUnit& aDTS,
|
||||
const media::TimeUnit& aDuration,
|
||||
int64_t aOffsetInStream)
|
||||
{
|
||||
// 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. Have the data pointer of each frame point to the
|
||||
// first plane, they'll always be zero'd memory anyway.
|
||||
auto frame = MakeUnique<uint8_t[]>(mFrameWidth * mFrameHeight);
|
||||
memset(frame.get(), 0, mFrameWidth * mFrameHeight);
|
||||
// 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;
|
||||
|
||||
// Y plane.
|
||||
@ -50,7 +145,7 @@ public:
|
||||
buffer.mPlanes[0].mSkip = 0;
|
||||
|
||||
// Cb plane.
|
||||
buffer.mPlanes[1].mData = frame.get();
|
||||
buffer.mPlanes[1].mData = frame.get() + sizeY;
|
||||
buffer.mPlanes[1].mStride = (mFrameWidth + 1) / 2;
|
||||
buffer.mPlanes[1].mHeight = (mFrameHeight + 1) / 2;
|
||||
buffer.mPlanes[1].mWidth = (mFrameWidth + 1) / 2;
|
||||
@ -58,21 +153,25 @@ public:
|
||||
buffer.mPlanes[1].mSkip = 0;
|
||||
|
||||
// Cr plane.
|
||||
buffer.mPlanes[2].mData = frame.get();
|
||||
buffer.mPlanes[2].mData = frame.get() + sizeY;
|
||||
buffer.mPlanes[2].mStride = (mFrameWidth + 1) / 2;
|
||||
buffer.mPlanes[2].mHeight = (mFrameHeight + 1) / 2;
|
||||
buffer.mPlanes[2].mWidth = (mFrameWidth + 1) / 2;
|
||||
buffer.mPlanes[2].mOffset = 0;
|
||||
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,
|
||||
aSample->mOffset,
|
||||
aSample->mTime,
|
||||
aSample->mDuration,
|
||||
aOffsetInStream,
|
||||
aDTS.ToMicroseconds(),
|
||||
aDuration.ToMicroseconds(),
|
||||
buffer,
|
||||
aSample->mKeyframe,
|
||||
aSample->mTime,
|
||||
true,
|
||||
aDTS.ToMicroseconds(),
|
||||
mPicture);
|
||||
}
|
||||
|
||||
@ -84,7 +183,7 @@ private:
|
||||
RefPtr<layers::ImageContainer> mImageContainer;
|
||||
};
|
||||
|
||||
class BlankAudioDataCreator : public DummyDataCreator
|
||||
class BlankAudioDataCreator
|
||||
{
|
||||
public:
|
||||
BlankAudioDataCreator(uint32_t aChannelCount, uint32_t aSampleRate)
|
||||
@ -92,11 +191,14 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<MediaData> Create(MediaRawData* aSample) override
|
||||
MediaData* Create(const media::TimeUnit& aDTS,
|
||||
const media::TimeUnit& aDuration,
|
||||
int64_t aOffsetInStream)
|
||||
{
|
||||
// Convert duration to frames. We add 1 to duration to account for
|
||||
// rounding errors, so we get a consistent tone.
|
||||
CheckedInt64 frames = UsecsToFrames(aSample->mDuration+1, mSampleRate);
|
||||
CheckedInt64 frames =
|
||||
UsecsToFrames(aDuration.ToMicroseconds()+1, mSampleRate);
|
||||
if (!frames.isValid()
|
||||
|| !mChannelCount
|
||||
|| !mSampleRate
|
||||
@ -117,14 +219,13 @@ public:
|
||||
}
|
||||
mFrameSum++;
|
||||
}
|
||||
RefPtr<AudioData> data(new AudioData(aSample->mOffset,
|
||||
aSample->mTime,
|
||||
aSample->mDuration,
|
||||
uint32_t(frames.value()),
|
||||
Move(samples),
|
||||
mChannelCount,
|
||||
mSampleRate));
|
||||
return data.forget();
|
||||
return new AudioData(aOffsetInStream,
|
||||
aDTS.ToMicroseconds(),
|
||||
aDuration.ToMicroseconds(),
|
||||
uint32_t(frames.value()),
|
||||
Move(samples),
|
||||
mChannelCount,
|
||||
mSampleRate);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -142,10 +243,10 @@ public:
|
||||
CreateVideoDecoder(const CreateDecoderParams& aParams) override
|
||||
{
|
||||
const VideoInfo& config = aParams.VideoConfig();
|
||||
UniquePtr<DummyDataCreator> creator =
|
||||
MakeUnique<BlankVideoDataCreator>(config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer);
|
||||
BlankVideoDataCreator* creator = new BlankVideoDataCreator(
|
||||
config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer);
|
||||
RefPtr<MediaDataDecoder> decoder =
|
||||
new DummyMediaDataDecoder(Move(creator), "blank media data decoder", aParams);
|
||||
new BlankMediaDataDecoder<BlankVideoDataCreator>(creator, aParams);
|
||||
return decoder.forget();
|
||||
}
|
||||
|
||||
@ -154,10 +255,11 @@ public:
|
||||
CreateAudioDecoder(const CreateDecoderParams& aParams) override
|
||||
{
|
||||
const AudioInfo& config = aParams.AudioConfig();
|
||||
UniquePtr<DummyDataCreator> creator =
|
||||
MakeUnique<BlankAudioDataCreator>(config.mChannels, config.mRate);
|
||||
BlankAudioDataCreator* creator = new BlankAudioDataCreator(
|
||||
config.mChannels, config.mRate);
|
||||
|
||||
RefPtr<MediaDataDecoder> decoder =
|
||||
new DummyMediaDataDecoder(Move(creator), "blank media data decoder", aParams);
|
||||
new BlankMediaDataDecoder<BlankAudioDataCreator>(creator, aParams);
|
||||
return decoder.forget();
|
||||
}
|
||||
|
||||
|
@ -1,93 +0,0 @@
|
||||
/* -*- 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<DummyDataCreator>&& 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<MediaDataDecoder::InitPromise>
|
||||
DummyMediaDataDecoder::Init()
|
||||
{
|
||||
return InitPromise::CreateAndResolve(mType, __func__);
|
||||
}
|
||||
|
||||
RefPtr<ShutdownPromise>
|
||||
DummyMediaDataDecoder::Shutdown()
|
||||
{
|
||||
return ShutdownPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
RefPtr<MediaDataDecoder::DecodePromise>
|
||||
DummyMediaDataDecoder::Decode(MediaRawData* aSample)
|
||||
{
|
||||
RefPtr<MediaData> 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<MediaDataDecoder::DecodePromise>
|
||||
DummyMediaDataDecoder::Drain()
|
||||
{
|
||||
DecodedData samples;
|
||||
while (!mReorderQueue.IsEmpty()) {
|
||||
samples.AppendElement(mReorderQueue.Pop().get());
|
||||
}
|
||||
return DecodePromise::CreateAndResolve(samples, __func__);
|
||||
}
|
||||
|
||||
RefPtr<MediaDataDecoder::FlushPromise>
|
||||
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
|
@ -1,60 +0,0 @@
|
||||
/* -*- 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<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:
|
||||
DummyMediaDataDecoder(UniquePtr<DummyDataCreator>&& aCreator,
|
||||
const char* aDescription,
|
||||
const CreateDecoderParams& aParams);
|
||||
|
||||
RefPtr<InitPromise> Init() override;
|
||||
|
||||
RefPtr<ShutdownPromise> Shutdown() override;
|
||||
|
||||
RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
|
||||
|
||||
RefPtr<DecodePromise> Drain() override;
|
||||
|
||||
RefPtr<FlushPromise> Flush() override;
|
||||
|
||||
const char* GetDescriptionName() const override;
|
||||
|
||||
ConversionRequired NeedsConversion() const override;
|
||||
|
||||
private:
|
||||
UniquePtr<DummyDataCreator> mCreator;
|
||||
const bool mIsH264;
|
||||
const uint32_t mMaxRefFrames;
|
||||
ReorderQueue mReorderQueue;
|
||||
TrackInfo::TrackType mType;
|
||||
nsCString mDescription;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // !defined(DummyMediaDataDecoder_h_)
|
@ -1,63 +0,0 @@
|
||||
/* -*- 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"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class NullVideoDataCreator : public DummyDataCreator {
|
||||
public:
|
||||
NullVideoDataCreator() {}
|
||||
|
||||
already_AddRefed<MediaData> Create(MediaRawData* aSample) override
|
||||
{
|
||||
// Create a dummy VideoData with no image. This gives us something to
|
||||
// send to media streams if necessary.
|
||||
RefPtr<VideoData> v(new VideoData(aSample->mOffset,
|
||||
aSample->mTime,
|
||||
aSample->mDuration,
|
||||
aSample->mKeyframe,
|
||||
aSample->mTimecode,
|
||||
gfx::IntSize(),
|
||||
0));
|
||||
return v.forget();
|
||||
}
|
||||
};
|
||||
|
||||
class NullDecoderModule : public PlatformDecoderModule {
|
||||
public:
|
||||
|
||||
// Decode thread.
|
||||
already_AddRefed<MediaDataDecoder>
|
||||
CreateVideoDecoder(const CreateDecoderParams& aParams) override {
|
||||
UniquePtr<DummyDataCreator> creator = MakeUnique<NullVideoDataCreator>();
|
||||
RefPtr<MediaDataDecoder> decoder =
|
||||
new DummyMediaDataDecoder(Move(creator), "null media data decoder", aParams);
|
||||
return decoder.forget();
|
||||
}
|
||||
|
||||
// Decode thread.
|
||||
already_AddRefed<MediaDataDecoder>
|
||||
CreateAudioDecoder(const CreateDecoderParams& aParams) override {
|
||||
MOZ_ASSERT(false, "Audio decoders are unsupported.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
SupportsMimeType(const nsACString& aMimeType,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<PlatformDecoderModule> CreateNullDecoderModule()
|
||||
{
|
||||
RefPtr<PlatformDecoderModule> pdm = new NullDecoderModule();
|
||||
return pdm.forget();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -6,7 +6,6 @@
|
||||
|
||||
EXPORTS += [
|
||||
'agnostic/AgnosticDecoderModule.h',
|
||||
'agnostic/DummyMediaDataDecoder.h',
|
||||
'agnostic/OpusDecoder.h',
|
||||
'agnostic/TheoraDecoder.h',
|
||||
'agnostic/VorbisDecoder.h',
|
||||
@ -23,8 +22,6 @@ EXPORTS += [
|
||||
UNIFIED_SOURCES += [
|
||||
'agnostic/AgnosticDecoderModule.cpp',
|
||||
'agnostic/BlankDecoderModule.cpp',
|
||||
'agnostic/DummyMediaDataDecoder.cpp',
|
||||
'agnostic/NullDecoderModule.cpp',
|
||||
'agnostic/OpusDecoder.cpp',
|
||||
'agnostic/TheoraDecoder.cpp',
|
||||
'agnostic/VorbisDecoder.cpp',
|
||||
|
@ -1140,8 +1140,5 @@ tags = suspend
|
||||
[test_background_video_no_suspend_disabled.html]
|
||||
skip-if = toolkit == 'android' # android(bug 1304480)
|
||||
tags = suspend
|
||||
[test_background_video_drawimage_with_suspended_video.html]
|
||||
tags = suspend
|
||||
|
||||
[test_temporary_file_blob_video_plays.html]
|
||||
skip-if = toolkit == 'android' # android(bug 1232305)
|
||||
|
@ -1,78 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Background Video Displays Video Frame via drawImage When Suspended</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="manifest.js"></script>
|
||||
<script src="background_video.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
video, canvas {
|
||||
border: 1px solid black;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function drawVideoToCanvas(v) {
|
||||
console.log('drawVideoToCanvas');
|
||||
let w = v.width,
|
||||
h = v.height,
|
||||
c = document.createElement('canvas');
|
||||
c.width = 4;
|
||||
c.height = 4;
|
||||
c.style.width = 64;
|
||||
c.style.height = 64;
|
||||
document.body.appendChild(c);
|
||||
|
||||
let gfx = c.getContext('2d');
|
||||
if (!gfx) {
|
||||
throw Error("Unable to obtain context '2d' from canvas");
|
||||
}
|
||||
|
||||
gfx.drawImage(v, 0, 0, 4, 4);
|
||||
let imageData = gfx.getImageData(0, 0, 4, 4);
|
||||
let pixels = imageData.data;
|
||||
|
||||
// Check that pixels aren't all the same colour.
|
||||
// Implements by checking against rgb of the first pixel.
|
||||
let rr = pixels[0],
|
||||
gg = pixels[1],
|
||||
bb = pixels[2],
|
||||
allSame = true;
|
||||
|
||||
for (let i = 0; i < 4*4; i++) {
|
||||
let r = pixels[4*i+0];
|
||||
let g = pixels[4*i+1];
|
||||
let b = pixels[4*i+2];
|
||||
if (r != rr || g != gg || b != bb) {
|
||||
allSame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ok(!allSame, "Pixels aren't all the same color");
|
||||
}
|
||||
|
||||
startTest({
|
||||
desc: 'Test Background Video Displays Video Frame via drawImage When Suspended',
|
||||
prefs: [
|
||||
[ "media.test.video-suspend", true ],
|
||||
[ "media.suspend-bkgnd-video.enabled", true ],
|
||||
[ "media.suspend-bkgnd-video.delay-ms", 500 ]
|
||||
],
|
||||
tests: gDecodeSuspendTests,
|
||||
runTest: (test, token) => {
|
||||
let v = appendVideoToDoc(test.name, token);
|
||||
manager.started(token);
|
||||
|
||||
waitUntilPlaying(v)
|
||||
.then(() => testVideoSuspendsWhenHidden(v))
|
||||
.then(() => {
|
||||
drawVideoToCanvas(v);
|
||||
manager.finished(token);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user