Bug 1232527 - Remove GMPVideoDecoderTrialCreator and friends. r=jwwang

Remove GMPVideoDecoderTrialCreator, and the tests and IPC/IDL supporting it.
This commit is contained in:
Chris Pearce 2015-12-15 15:17:22 +13:00
parent 70555bdeaf
commit 4b77542fe5
12 changed files with 1 additions and 902 deletions

View File

@ -1,573 +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 "mozilla/dom/GMPVideoDecoderTrialCreator.h"
#include "mozilla/Preferences.h"
#include "prsystem.h"
#include "GMPVideoHost.h"
#include "mozilla/EMEUtils.h"
#include "nsServiceManagerUtils.h"
#include "GMPService.h"
#include "VideoUtils.h"
#include "nsPrintfCString.h"
#include "nsXULAppAPI.h"
namespace mozilla {
namespace dom {
static already_AddRefed<nsIThread>
GetGMPThread()
{
nsCOMPtr<mozIGeckoMediaPluginService> gmps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (!gmps) {
return nullptr;
}
nsCOMPtr<nsIThread> gmpThread;
nsresult rv = gmps->GetThread(getter_AddRefs(gmpThread));
if (NS_FAILED(rv)) {
return nullptr;
}
return gmpThread.forget();
}
#ifdef DEBUG
static bool
OnGMPThread()
{
nsCOMPtr<nsIThread> currentThread;
NS_GetCurrentThread(getter_AddRefs(currentThread));
nsCOMPtr<nsIThread> gmpThread(GetGMPThread());
return !!gmpThread && !!currentThread && gmpThread == currentThread;
}
#endif
static const char*
TrialCreatePrefName(const nsAString& aKeySystem)
{
if (aKeySystem.EqualsLiteral("com.adobe.primetime")) {
return "media.gmp-eme-adobe.trial-create";
}
if (aKeySystem.EqualsLiteral("org.w3.clearkey")) {
return "media.gmp-eme-clearkey.trial-create";
}
return nullptr;
}
/* static */
GMPVideoDecoderTrialCreator::TrialCreateState
GMPVideoDecoderTrialCreator::GetCreateTrialState(const nsAString& aKeySystem)
{
if (Preferences::GetBool("media.gmp.always-trial-create", false)) {
return Pending;
}
const char* pref = TrialCreatePrefName(aKeySystem);
if (!pref) {
return Pending;
}
switch (Preferences::GetInt(pref, (int)Pending)) {
case 0: return Pending;
case 1: return Succeeded;
case 2: return Failed;
default: return Pending;
}
}
/* static */ void
GMPVideoDecoderTrialCreator::UpdateTrialCreateState(const nsAString& aKeySystem,
uint32_t aState)
{
UpdateTrialCreateState(aKeySystem, (TrialCreateState)aState);
}
/* static */ void
GMPVideoDecoderTrialCreator::UpdateTrialCreateState(const nsAString& aKeySystem,
TrialCreateState aState)
{
MOZ_ASSERT(NS_IsMainThread());
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// Pref has to be set from the chrome process. Dispatch to chrome via
// GMPService.
nsCOMPtr<mozIGeckoMediaPluginService> service =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
NS_ENSURE_TRUE_VOID(service);
service->UpdateTrialCreateState(aKeySystem, (uint32_t)aState);
return;
}
const char* pref = TrialCreatePrefName(aKeySystem);
if (pref) {
Preferences::SetInt(pref, (int)aState);
}
}
void
GMPVideoDecoderTrialCreator::TrialCreateGMPVideoDecoderFailed(const nsAString& aKeySystem,
const nsACString& aReason)
{
MOZ_ASSERT(NS_IsMainThread());
EME_LOG("GMPVideoDecoderTrialCreator::TrialCreateGMPVideoDecoderFailed(%s)",
NS_ConvertUTF16toUTF8(aKeySystem).get());
TrialCreateData* data = mTestCreate.Get(aKeySystem);
if (!data) {
return;
}
data->mStatus = Failed;
UpdateTrialCreateState(aKeySystem, Failed);
for (RefPtr<AbstractPromiseLike>& promise: data->mPending) {
promise->Reject(NS_ERROR_DOM_NOT_SUPPORTED_ERR, aReason);
}
data->mPending.Clear();
data->mTest = nullptr;
}
void
GMPVideoDecoderTrialCreator::TrialCreateGMPVideoDecoderSucceeded(const nsAString& aKeySystem)
{
MOZ_ASSERT(NS_IsMainThread());
EME_LOG("GMPVideoDecoderTrialCreator::TrialCreateGMPVideoDecoderSucceeded(%s)",
NS_ConvertUTF16toUTF8(aKeySystem).get());
TrialCreateData* data = mTestCreate.Get(aKeySystem);
if (!data) {
return;
}
data->mStatus = Succeeded;
UpdateTrialCreateState(aKeySystem, Succeeded);
for (RefPtr<AbstractPromiseLike>& promise : data->mPending) {
promise->Resolve();
}
data->mPending.Clear();
data->mTest = nullptr;
}
nsresult
TestGMPVideoDecoder::Start()
{
MOZ_ASSERT(NS_IsMainThread());
mGMPService = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (!mGMPService) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIThread> thread(GetGMPThread());
if (!thread) {
return NS_ERROR_FAILURE;
}
RefPtr<nsIRunnable> task(NS_NewRunnableMethod(this, &TestGMPVideoDecoder::CreateGMPVideoDecoder));
return thread->Dispatch(task, NS_DISPATCH_NORMAL);
}
struct ExpectedPlaneDecodePlane {
GMPPlaneType mPlane;
size_t mLength;
uint8_t mValue;
int32_t mSize; // width & height
};
static const ExpectedPlaneDecodePlane sExpectedPlanes[3] = {
{
kGMPYPlane,
112 * 112, // 12544
0x4c,
112
},
{ // U
kGMPUPlane,
56 * 56, // 3136
0x55,
56,
},
{ // V
kGMPVPlane,
56 * 56, // 3136
0xff,
56,
}
};
static bool TestDecodedFrame(GMPVideoi420Frame* aDecodedFrame)
{
MOZ_ASSERT(OnGMPThread());
if (aDecodedFrame->Width() != 112 || aDecodedFrame->Height() != 112) {
EME_LOG("TestDecodedFrame() - Invalid decoded frame dimensions");
return false;
}
for (const ExpectedPlaneDecodePlane& plane : sExpectedPlanes) {
int32_t stride = aDecodedFrame->Stride(plane.mPlane);
if (stride < plane.mSize) {
EME_LOG("TestDecodedFrame() - Insufficient decoded frame stride");
return false;
}
int32_t length = plane.mSize * plane.mSize;
if (aDecodedFrame->AllocatedSize(plane.mPlane) < length) {
EME_LOG("TestDecodedFrame() - Insufficient decoded frame allocated size");
return false;
}
const uint8_t* data = aDecodedFrame->Buffer(plane.mPlane);
for (int32_t row = 0; row < plane.mSize; row++) {
for (int32_t i = 0; i < plane.mSize; i++) {
size_t off = (stride * row) + i;
if (data[off] != plane.mValue) {
EME_LOG("TestDecodedFrame() - Invalid decoded frame contents");
return false;
}
}
}
}
return true;
}
void
TestGMPVideoDecoder::Decoded(GMPVideoi420Frame* aDecodedFrame)
{
MOZ_ASSERT(OnGMPThread());
if (!mReceivedDecoded) {
mReceivedDecoded = true;
} else {
EME_LOG("Received multiple decoded frames");
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder received multiple decoded frames"));
return;
}
GMPUniquePtr<GMPVideoi420Frame> decodedFrame(aDecodedFrame);
if (!TestDecodedFrame(aDecodedFrame)) {
EME_LOG("decoded frame failed verification");
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder decoded frame failed verification"));
}
}
void
TestGMPVideoDecoder::DrainComplete()
{
EME_LOG("TestGMPVideoDecoder::DrainComplete()");
MOZ_ASSERT(OnGMPThread());
ReportSuccess();
}
void
TestGMPVideoDecoder::Error(GMPErr aErr)
{
EME_LOG("TestGMPVideoDecoder::ReceivedDecodedFrame()");
MOZ_ASSERT(OnGMPThread());
ReportFailure(nsPrintfCString("TestGMPVideoDecoder error %d", aErr));
}
void
TestGMPVideoDecoder::Terminated()
{
EME_LOG("TestGMPVideoDecoder::Terminated()");
MOZ_ASSERT(OnGMPThread());
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder GMP terminated"));
}
void
TestGMPVideoDecoder::ReportFailure(const nsACString& aReason)
{
MOZ_ASSERT(OnGMPThread());
if (mGMP) {
mGMP->Close();
mGMP = nullptr;
}
RefPtr<nsIRunnable> task;
task = NS_NewRunnableMethodWithArgs<nsString, nsCString>(mInstance,
&GMPVideoDecoderTrialCreator::TrialCreateGMPVideoDecoderFailed,
mKeySystem,
aReason);
NS_DispatchToMainThread(task, NS_DISPATCH_NORMAL);
}
void
TestGMPVideoDecoder::ReportSuccess()
{
MOZ_ASSERT(OnGMPThread());
if (mGMP) {
mGMP->Close();
mGMP = nullptr;
}
RefPtr<nsIRunnable> task;
task = NS_NewRunnableMethodWithArg<nsString>(mInstance,
&GMPVideoDecoderTrialCreator::TrialCreateGMPVideoDecoderSucceeded,
mKeySystem);
NS_DispatchToMainThread(task, NS_DISPATCH_NORMAL);
}
// A solid red, 112x112 frame. Display size 100x100 pixels.
// Generated with ImageMagick/ffmpeg
// $ convert -size 100x100 xc:rgb\(255, 0, 0\) red.png
// $ ffmpeg -f image2 -i red.png -r 24 -b:v 200k -c:v libx264 -profile:v baseline -level 1 -v:r 24 red.mp4 -y
static const uint8_t sTestH264Frame[] = {
0x00, 0x00, 0x02, 0x81, 0x06, 0x05, 0xff, 0xff, 0x7d, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9,
0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20,
0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x33, 0x35, 0x20, 0x72, 0x32, 0x33, 0x34,
0x35, 0x20, 0x66, 0x30, 0x63, 0x31, 0x63, 0x35, 0x33, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32,
0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63,
0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74,
0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x33, 0x20, 0x2d, 0x20, 0x68, 0x74,
0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c,
0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d,
0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61,
0x62, 0x61, 0x63, 0x3d, 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x33, 0x20, 0x64, 0x65, 0x62,
0x6c, 0x6f, 0x63, 0x6b, 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c,
0x79, 0x73, 0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d,
0x65, 0x3d, 0x68, 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70,
0x73, 0x79, 0x3d, 0x31, 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30,
0x30, 0x3a, 0x30, 0x2e, 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65,
0x66, 0x3d, 0x31, 0x20, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36,
0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72,
0x65, 0x6c, 0x6c, 0x69, 0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d,
0x30, 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e,
0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73,
0x6b, 0x69, 0x70, 0x3d, 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70,
0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65,
0x61, 0x64, 0x73, 0x3d, 0x31, 0x32, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61,
0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x31, 0x20, 0x73, 0x6c, 0x69,
0x63, 0x65, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e,
0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c,
0x75, 0x72, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63,
0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72,
0x61, 0x3d, 0x30, 0x20, 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77,
0x65, 0x69, 0x67, 0x68, 0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74,
0x3d, 0x32, 0x35, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e,
0x3d, 0x32, 0x34, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x63, 0x75, 0x74, 0x3d, 0x34, 0x30,
0x20, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x3d,
0x30, 0x20, 0x72, 0x63, 0x5f, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x3d,
0x34, 0x30, 0x20, 0x72, 0x63, 0x3d, 0x61, 0x62, 0x72, 0x20, 0x6d, 0x62, 0x74, 0x72, 0x65,
0x65, 0x3d, 0x31, 0x20, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x3d, 0x32, 0x30, 0x30,
0x20, 0x72, 0x61, 0x74, 0x65, 0x74, 0x6f, 0x6c, 0x3d, 0x31, 0x2e, 0x30, 0x20, 0x71, 0x63,
0x6f, 0x6d, 0x70, 0x3d, 0x30, 0x2e, 0x36, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x69, 0x6e, 0x3d,
0x30, 0x20, 0x71, 0x70, 0x6d, 0x61, 0x78, 0x3d, 0x36, 0x39, 0x20, 0x71, 0x70, 0x73, 0x74,
0x65, 0x70, 0x3d, 0x34, 0x20, 0x69, 0x70, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x3d, 0x31,
0x2e, 0x34, 0x30, 0x20, 0x61, 0x71, 0x3d, 0x31, 0x3a, 0x31, 0x2e, 0x30, 0x30, 0x00, 0x80,
0x00, 0x00, 0x00, 0x39, 0x65, 0x88, 0x84, 0x0c, 0xf1, 0x18, 0xa0, 0x00, 0x23, 0xbf, 0x1c,
0x00, 0x04, 0x3c, 0x63, 0x80, 0x00, 0x98, 0x44, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x75,
0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75,
0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75, 0xd7, 0x5d, 0x75,
0xe0
};
static GMPUniquePtr<GMPVideoEncodedFrame>
CreateFrame(GMPVideoHost* aHost)
{
MOZ_ASSERT(OnGMPThread());
GMPVideoFrame* ftmp = nullptr;
GMPErr err = aHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp);
if (GMP_FAILED(err)) {
return nullptr;
}
GMPUniquePtr<GMPVideoEncodedFrame> frame(static_cast<GMPVideoEncodedFrame*>(ftmp));
err = frame->CreateEmptyFrame(MOZ_ARRAY_LENGTH(sTestH264Frame));
if (GMP_FAILED(err)) {
return nullptr;
}
memcpy(frame->Buffer(), sTestH264Frame, MOZ_ARRAY_LENGTH(sTestH264Frame));
frame->SetBufferType(GMP_BufferLength32);
frame->SetEncodedWidth(100);
frame->SetEncodedHeight(100);
frame->SetTimeStamp(0);
frame->SetCompleteFrame(true);
frame->SetDuration(41666);
frame->SetFrameType(kGMPKeyFrame);
return frame;
}
static const uint8_t sTestH264CodecSpecific[] = {
0x01, 0x42, 0xc0, 0x0a, 0xff, 0xe1, 0x00, 0x18, 0x67, 0x42, 0xc0, 0x0a, 0xd9, 0x07, 0x3f,
0x9e, 0x79, 0xb2, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x60, 0x1e, 0x24,
0x4c, 0x90, 0x01, 0x00, 0x04, 0x68, 0xcb, 0x8c, 0xb2
};
void
TestGMPVideoDecoder::Callback::Done(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost)
{
MOZ_ASSERT(OnGMPThread());
if (!aHost || !aGMP) {
mInstance->ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder null host or GMP on Get"));
return;
}
RefPtr<nsIRunnable> task;
task = NS_NewRunnableMethodWithArgs<GMPVideoDecoderProxy*, GMPVideoHost*>(mInstance,
&TestGMPVideoDecoder::ActorCreated,
aGMP, aHost);
NS_DispatchToMainThread(task, NS_DISPATCH_NORMAL);
}
void
TestGMPVideoDecoder::ActorCreated(GMPVideoDecoderProxy* aGMP,
GMPVideoHost* aHost)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aHost && aGMP);
// Add crash handler.
RefPtr<gmp::GeckoMediaPluginService> service =
gmp::GeckoMediaPluginService::GetGeckoMediaPluginService();
service->AddPluginCrashedEventTarget(aGMP->GetPluginId(), mWindow);
nsCOMPtr<nsIThread> thread(GetGMPThread());
if (!thread) {
mInstance->TrialCreateGMPVideoDecoderFailed(mKeySystem,
NS_LITERAL_CSTRING("Failed to get GMP thread in TestGMPVideoDecoder::ActorCreated"));
return;
}
RefPtr<nsIRunnable> task;
task = NS_NewRunnableMethodWithArgs<GMPVideoDecoderProxy*, GMPVideoHost*>(this,
&TestGMPVideoDecoder::InitGMPDone,
aGMP, aHost);
thread->Dispatch(task, NS_DISPATCH_NORMAL);
}
void
TestGMPVideoDecoder::InitGMPDone(GMPVideoDecoderProxy* aGMP,
GMPVideoHost* aHost)
{
MOZ_ASSERT(OnGMPThread());
MOZ_ASSERT(aHost && aGMP);
mGMP = aGMP;
mHost = aHost;
GMPVideoCodec codec;
memset(&codec, 0, sizeof(codec));
codec.mGMPApiVersion = kGMPVersion33;
codec.mCodecType = kGMPVideoCodecH264;
codec.mWidth = 100;
codec.mHeight = 100;
nsTArray<uint8_t> codecSpecific;
codecSpecific.AppendElement(0); // mPacketizationMode.
codecSpecific.AppendElements(sTestH264CodecSpecific,
MOZ_ARRAY_LENGTH(sTestH264CodecSpecific));
nsresult rv = mGMP->InitDecode(codec,
codecSpecific,
this,
PR_GetNumberOfProcessors());
if (NS_FAILED(rv)) {
EME_LOG("InitGMPDone() - InitDecode() failed!");
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder InitDecode() returned failure"));
return;
}
GMPUniquePtr<GMPVideoEncodedFrame> frame = CreateFrame(aHost);
if (!frame) {
EME_LOG("InitGMPDone() - Decode() failed to create frame!");
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder Decode() failed to create frame"));
return;
}
nsTArray<uint8_t> info; // No codec specific per-frame info to pass.
rv = mGMP->Decode(Move(frame), false, info, 0);
if (NS_FAILED(rv)) {
EME_LOG("InitGMPDone() - Decode() failed to send Decode message!");
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder Decode() returned failure"));
return;
}
rv = mGMP->Drain();
if (NS_FAILED(rv)) {
EME_LOG("InitGMPDone() - Drain() failed to send Drain message!");
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder Drain() returned failure"));
return;
}
}
void
TestGMPVideoDecoder::CreateGMPVideoDecoder()
{
MOZ_ASSERT(OnGMPThread());
nsTArray<nsCString> tags;
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
UniquePtr<GetGMPVideoDecoderCallback> callback(new Callback(this));
if (NS_FAILED(mGMPService->GetGMPVideoDecoder(&tags,
NS_LITERAL_CSTRING("fakeNodeId1234567890fakeNodeId12"),
Move(callback)))) {
ReportFailure(NS_LITERAL_CSTRING("TestGMPVideoDecoder GMPService GetGMPVideoDecoder returned failure"));
}
}
void
GMPVideoDecoderTrialCreator::MaybeAwaitTrialCreate(const nsAString& aKeySystem,
AbstractPromiseLike* aPromisey,
nsPIDOMWindow* aParent)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mTestCreate.Contains(aKeySystem)) {
mTestCreate.Put(aKeySystem, new TrialCreateData(aKeySystem));
}
TrialCreateData* data = mTestCreate.Get(aKeySystem);
MOZ_ASSERT(data);
switch (data->mStatus) {
case TrialCreateState::Succeeded: {
EME_LOG("GMPVideoDecoderTrialCreator::MaybeAwaitTrialCreate(%s) already succeeded",
NS_ConvertUTF16toUTF8(aKeySystem).get());
aPromisey->Resolve();
break;
}
case TrialCreateState::Failed: {
// Something is broken about this configuration. Report as unsupported.
EME_LOG("GMPVideoDecoderTrialCreator::MaybeAwaitTrialCreate(%s) already failed",
NS_ConvertUTF16toUTF8(aKeySystem).get());
aPromisey->Reject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
NS_LITERAL_CSTRING("navigator.requestMediaKeySystemAccess trial CDM creation failed"));
break;
}
case TrialCreateState::Pending: {
EME_LOG("GMPVideoDecoderTrialCreator::MaybeAwaitTrialCreate(%s) pending",
NS_ConvertUTF16toUTF8(aKeySystem).get());
// Add request to the list of pending items waiting.
data->mPending.AppendElement(aPromisey);
if (!data->mTest) {
// Not already waiting for CDM to be created. Create and Init
// a CDM, to test whether it will work.
data->mTest = new TestGMPVideoDecoder(this, aKeySystem, aParent);
if (NS_FAILED(data->mTest->Start())) {
TrialCreateGMPVideoDecoderFailed(aKeySystem,
NS_LITERAL_CSTRING("TestGMPVideoDecoder::Start() failed"));
return;
}
// Promise will call InitMediaKeysPromiseHandler when Init()
// succeeds/fails.
}
break;
}
}
return;
}
} // namespace dom
} // namespace mozilla

View File

@ -1,179 +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/. */
#ifndef mozilla_dom_GMPVideoDecoderTrialCreator_h
#define mozilla_dom_GMPVideoDecoderTrialCreator_h
#include "mozilla/dom/MediaKeySystemAccess.h"
#include "nsIObserver.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
#include "nsITimer.h"
#include "nsClassHashtable.h"
#include "mozilla/dom/MediaKeys.h"
#include "GMPVideoDecoderProxy.h"
namespace mozilla {
namespace dom {
class TestGMPVideoDecoder;
class GMPVideoDecoderTrialCreator {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPVideoDecoderTrialCreator);
void TrialCreateGMPVideoDecoderFailed(const nsAString& aKeySystem,
const nsACString& aReason);
void TrialCreateGMPVideoDecoderSucceeded(const nsAString& aKeySystem);
template<class T>
void MaybeAwaitTrialCreate(const nsAString& aKeySystem,
MediaKeySystemAccess* aAccess,
T* aPromiseLike,
nsPIDOMWindow* aParent)
{
RefPtr<PromiseLike<T>> p(new PromiseLike<T>(aPromiseLike, aAccess));
MaybeAwaitTrialCreate(aKeySystem, p, aParent);
}
static void UpdateTrialCreateState(const nsAString& aKeySystem, uint32_t aState);
private:
class AbstractPromiseLike {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractPromiseLike);
virtual void Resolve() = 0;
virtual void Reject(nsresult aResult, const nsACString& aMessage) = 0;
protected:
virtual ~AbstractPromiseLike() {}
};
template<class T>
class PromiseLike : public AbstractPromiseLike
{
public:
explicit PromiseLike(T* aPromiseLike, MediaKeySystemAccess* aAccess)
: mPromiseLike(aPromiseLike)
, mAccess(aAccess)
{
}
void Resolve() override {
MOZ_ASSERT(NS_IsMainThread());
mPromiseLike->MaybeResolve(mAccess);
}
void Reject(nsresult aResult, const nsACString& aMessage) override {
MOZ_ASSERT(NS_IsMainThread());
mPromiseLike->MaybeReject(aResult, aMessage);
}
protected:
~PromiseLike() {}
RefPtr<T> mPromiseLike;
RefPtr<MediaKeySystemAccess> mAccess;
};
void MaybeAwaitTrialCreate(const nsAString& aKeySystem,
AbstractPromiseLike* aPromisey,
nsPIDOMWindow* aParent);
~GMPVideoDecoderTrialCreator() {}
// Note: Keep this in sync with GetCreateTrialState.
enum TrialCreateState {
Pending = 0,
Succeeded = 1,
Failed = 2,
};
static TrialCreateState GetCreateTrialState(const nsAString& aKeySystem);
static void UpdateTrialCreateState(const nsAString& aKeySystem,
TrialCreateState aState);
struct TrialCreateData {
explicit TrialCreateData(const nsAString& aKeySystem)
: mKeySystem(aKeySystem)
, mStatus(GetCreateTrialState(aKeySystem))
{}
~TrialCreateData() {}
const nsString mKeySystem;
RefPtr<TestGMPVideoDecoder> mTest;
nsTArray<RefPtr<AbstractPromiseLike>> mPending;
TrialCreateState mStatus;
private:
TrialCreateData(const TrialCreateData& aOther) = delete;
TrialCreateData() = delete;
TrialCreateData& operator =(const TrialCreateData&) = delete;
};
nsClassHashtable<nsStringHashKey, TrialCreateData> mTestCreate;
};
class TestGMPVideoDecoder : public GMPVideoDecoderCallbackProxy {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestGMPVideoDecoder);
TestGMPVideoDecoder(GMPVideoDecoderTrialCreator* aInstance,
const nsAString& aKeySystem,
nsPIDOMWindow* aParent)
: mKeySystem(aKeySystem)
, mInstance(aInstance)
, mWindow(aParent)
, mGMP(nullptr)
, mHost(nullptr)
, mReceivedDecoded(false)
{}
nsresult Start();
// GMPVideoDecoderCallbackProxy
virtual void Decoded(GMPVideoi420Frame* aDecodedFrame) override;
virtual void ReceivedDecodedReferenceFrame(const uint64_t aPictureId) override {}
virtual void ReceivedDecodedFrame(const uint64_t aPictureId) override {}
virtual void InputDataExhausted() override {}
virtual void DrainComplete() override;
virtual void ResetComplete() override {}
virtual void Error(GMPErr aErr) override;
virtual void Terminated() override;
void ActorCreated(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost); // Main thread.
class Callback : public GetGMPVideoDecoderCallback
{
public:
explicit Callback(TestGMPVideoDecoder* aInstance)
: mInstance(aInstance)
{}
~Callback() {}
void Done(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost) override;
private:
RefPtr<TestGMPVideoDecoder> mInstance;
};
private:
void InitGMPDone(GMPVideoDecoderProxy* aGMP, GMPVideoHost* aHost); // GMP thread.
void CreateGMPVideoDecoder();
~TestGMPVideoDecoder() {}
void ReportFailure(const nsACString& aReason);
void ReportSuccess();
const nsString mKeySystem;
nsCOMPtr<mozIGeckoMediaPluginService> mGMPService;
RefPtr<GMPVideoDecoderTrialCreator> mInstance;
nsCOMPtr<nsPIDOMWindow> mWindow;
GMPVideoDecoderProxy* mGMP;
GMPVideoHost* mHost;
bool mReceivedDecoded;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -51,7 +51,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
MediaKeySystemAccessManager::MediaKeySystemAccessManager(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
, mAddedObservers(false)
, mTrialCreator(new GMPVideoDecoderTrialCreator())
{
}

View File

@ -6,7 +6,6 @@
#define mozilla_dom_MediaKeySystemAccessManager_h
#include "mozilla/dom/MediaKeySystemAccess.h"
#include "mozilla/dom/GMPVideoDecoderTrialCreator.h"
#include "nsIObserver.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
@ -76,8 +75,6 @@ private:
nsCOMPtr<nsPIDOMWindow> mWindow;
bool mAddedObservers;
RefPtr<GMPVideoDecoderTrialCreator> mTrialCreator;
};
} // namespace dom

View File

@ -5,7 +5,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
'GMPVideoDecoderTrialCreator.h',
'MediaEncryptedEvent.h',
'MediaKeyError.h',
'MediaKeyMessageEvent.h',
@ -30,7 +29,6 @@ UNIFIED_SOURCES += [
'CDMProxy.cpp',
'DetailedPromise.cpp',
'EMEUtils.cpp',
'GMPVideoDecoderTrialCreator.cpp',
'MediaEncryptedEvent.cpp',
'MediaKeyError.cpp',
'MediaKeyMessageEvent.cpp',

View File

@ -186,40 +186,6 @@ GeckoMediaPluginServiceChild::GetNodeId(const nsAString& aOrigin,
return NS_OK;
}
NS_IMETHODIMP
GeckoMediaPluginServiceChild::UpdateTrialCreateState(const nsAString& aKeySystem,
uint32_t aState)
{
if (NS_GetCurrentThread() != mGMPThread) {
mGMPThread->Dispatch(NS_NewRunnableMethodWithArgs<nsString, uint32_t>(
this, &GeckoMediaPluginServiceChild::UpdateTrialCreateState,
aKeySystem, aState), NS_DISPATCH_NORMAL);
return NS_OK;
}
class Callback : public GetServiceChildCallback
{
public:
Callback(const nsAString& aKeySystem, uint32_t aState)
: mKeySystem(aKeySystem)
, mState(aState)
{ }
virtual void Done(GMPServiceChild* aService) override
{
aService->SendUpdateGMPTrialCreateState(mKeySystem, mState);
}
private:
nsString mKeySystem;
uint32_t mState;
};
UniquePtr<GetServiceChildCallback> callback(new Callback(aKeySystem, aState));
GetServiceChild(Move(callback));
return NS_OK;
}
NS_IMETHODIMP
GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
const char* aTopic,

View File

@ -50,8 +50,6 @@ public:
const nsAString& aGMPName,
bool aInPrivateBrowsingMode,
UniquePtr<GetNodeIdCallback>&& aCallback) override;
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,
uint32_t aState) override;
NS_DECL_NSIOBSERVER

View File

@ -9,9 +9,6 @@
#include "mozilla/Logging.h"
#include "GMPParent.h"
#include "GMPVideoDecoderParent.h"
#ifdef MOZ_EME
#include "mozilla/dom/GMPVideoDecoderTrialCreator.h"
#endif
#include "nsIObserverService.h"
#include "GeckoChildProcessHost.h"
#include "mozilla/Preferences.h"
@ -1392,22 +1389,6 @@ GeckoMediaPluginServiceParent::GetNodeId(const nsAString& aOrigin,
return rv;
}
NS_IMETHODIMP
GeckoMediaPluginServiceParent::UpdateTrialCreateState(const nsAString& aKeySystem,
uint32_t aState)
{
#ifdef MOZ_EME
nsString keySystem(aKeySystem);
NS_DispatchToMainThread(NS_NewRunnableFunction([keySystem, aState] {
mozilla::dom::GMPVideoDecoderTrialCreator::UpdateTrialCreateState(keySystem, aState);
}));
return NS_OK;
#else
return NS_ERROR_FAILURE;
#endif
}
static bool
ExtractHostName(const nsACString& aOrigin, nsACString& aOutData)
{
@ -1736,14 +1717,6 @@ GMPServiceParent::RecvGetGMPNodeId(const nsString& aOrigin,
return NS_SUCCEEDED(rv);
}
bool
GMPServiceParent::RecvUpdateGMPTrialCreateState(const nsString& aKeySystem,
const uint32_t& aState)
{
mService->UpdateTrialCreateState(aKeySystem, aState);
return true;
}
/* static */
bool
GMPServiceParent::RecvGetGMPPluginVersionForAPI(const nsCString& aAPI,

View File

@ -44,8 +44,6 @@ public:
const nsAString& aGMPName,
bool aInPrivateBrowsingMode,
UniquePtr<GetNodeIdCallback>&& aCallback) override;
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,
uint32_t aState) override;
NS_DECL_MOZIGECKOMEDIAPLUGINCHROMESERVICE
NS_DECL_NSIOBSERVER
@ -225,9 +223,6 @@ public:
nsTArray<nsCString>&& aTags,
bool* aHasPlugin,
nsCString* aVersion);
virtual bool RecvUpdateGMPTrialCreateState(const nsString& aKeySystem,
const uint32_t& aState) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
static PGMPServiceParent* Create(Transport* aTransport, ProcessId aOtherPid);

View File

@ -22,8 +22,6 @@ parent:
nsString gmpName,
bool inPrivateBrowsing)
returns (nsCString id);
async UpdateGMPTrialCreateState(nsString keySystem, uint32_t status);
};
} // namespace gmp

View File

@ -52,7 +52,7 @@ native GetGMPVideoDecoderCallback(mozilla::UniquePtr<GetGMPVideoDecoderCallback>
native GetGMPVideoEncoderCallback(mozilla::UniquePtr<GetGMPVideoEncoderCallback>&&);
native GetNodeIdCallback(mozilla::UniquePtr<GetNodeIdCallback>&&);
[scriptable, uuid(b5492915-2f0e-4973-9f91-a6fe61ac4749)]
[scriptable, uuid(44d362ae-937a-4803-bee6-f2512a0149d1)]
interface mozIGeckoMediaPluginService : nsISupports
{
@ -148,10 +148,4 @@ interface mozIGeckoMediaPluginService : nsISupports
in AString gmpName,
in bool inPrivateBrowsingMode,
in GetNodeIdCallback callback);
/**
* Stores the result of trying to create a decoder for the given keysystem.
*/
[noscript]
void updateTrialCreateState(in AString keySystem, in uint32_t status);
};

View File

@ -13,11 +13,6 @@
#include "GMPVideoEncoderProxy.h"
#include "GMPDecryptorProxy.h"
#include "GMPServiceParent.h"
#ifdef XP_WIN
#include "GMPVideoDecoderTrialCreator.h"
#include "mozilla/dom/MediaKeySystemAccess.h"
#include "mozilla/Monitor.h"
#endif
#include "nsAppDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "nsISimpleEnumerator.h"
@ -1494,65 +1489,3 @@ TEST(GeckoMediaPlugins, GMPStorageLongRecordNames) {
RefPtr<GMPStorageTest> runner = new GMPStorageTest();
runner->DoTest(&GMPStorageTest::TestLongRecordNames);
}
#ifdef XP_WIN
class GMPTrialCreateTest
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPStorageTest)
void DoTest() {
EnsureNSSInitializedChromeOrContent();
mCreator = new mozilla::dom::GMPVideoDecoderTrialCreator();
mCreator->MaybeAwaitTrialCreate(NS_LITERAL_STRING("broken"), nullptr, this, nullptr);
AwaitFinished();
}
GMPTrialCreateTest()
: mMonitor("GMPTrialCreateTest")
, mFinished(false)
, mPassed(false)
{
}
void MaybeResolve(mozilla::dom::MediaKeySystemAccess* aAccess) {
mPassed = false;
SetFinished();
}
void MaybeReject(nsresult aResult, const nsACString& aUnusedMessage) {
mPassed = true;
SetFinished();
}
private:
~GMPTrialCreateTest() { }
void Dummy() {
// Intentionally left blank.
}
void SetFinished() {
mFinished = true;
NS_DispatchToMainThread(NS_NewRunnableMethod(this, &GMPTrialCreateTest::Dummy));
}
void AwaitFinished() {
while (!mFinished) {
NS_ProcessNextEvent(nullptr, true);
}
mFinished = false;
}
RefPtr<mozilla::dom::GMPVideoDecoderTrialCreator> mCreator;
Monitor mMonitor;
Atomic<bool> mFinished;
bool mPassed;
};
TEST(GeckoMediaPlugins, GMPTrialCreateFail) {
RefPtr<GMPTrialCreateTest> runner = new GMPTrialCreateTest();
runner->DoTest();
}
#endif // XP_WIN