Bug 1212323: P2. Have IsVideoAccelerated return a Promise. r=cpearce

This commit is contained in:
Jean-Yves Avenard 2016-01-25 21:29:28 +11:00
parent e6bdc4bb40
commit 80744c3ce0
4 changed files with 80 additions and 32 deletions

View File

@ -106,6 +106,7 @@
#include "HTMLImageElement.h"
#include "mozilla/css/ImageLoader.h"
#include "mozilla/layers/APZCTreeManager.h" // for layers::ZoomToRectBehavior
#include "mozilla/dom/Promise.h"
#ifdef XP_WIN
#undef GetClassName
@ -2150,26 +2151,29 @@ nsDOMWindowUtils::GetLayerManagerRemote(bool* retval)
}
NS_IMETHODIMP
nsDOMWindowUtils::GetSupportsHardwareH264Decoding(nsAString& aRetval)
nsDOMWindowUtils::GetSupportsHardwareH264Decoding(JS::MutableHandle<JS::Value> aPromise)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(window);
NS_ENSURE_STATE(parentObject);
#ifdef MOZ_FMP4
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
NS_ENSURE_STATE(widget);
LayerManager *mgr = widget->GetLayerManager();
if (!mgr)
return NS_ERROR_FAILURE;
nsCString failureReason;
if (MP4Decoder::IsVideoAccelerated(mgr->GetCompositorBackendType(), failureReason)) {
aRetval.AssignLiteral("Yes");
} else {
aRetval.AssignLiteral("No; ");
AppendUTF8toUTF16(failureReason, aRetval);
}
NS_ENSURE_STATE(mgr);
RefPtr<Promise> promise =
MP4Decoder::IsVideoAccelerated(mgr->GetCompositorBackendType(), parentObject);
NS_ENSURE_STATE(promise);
aPromise.setObject(*promise->GetWrapper());
#else
aRetval.AssignLiteral("No; Compiled without MP4 support.");
ErrorResult rv;
RefPtr<Promise> promise = Promise::Create(parentObject, rv);
if (rv.Failed()) {
return rv.StealNSResult();
}
promise.MaybeResolve(NS_LITERAL_STRING("No; Compiled without MP4 support."));
aPromise.setObject(*promise->GetWrapper());
#endif
return NS_OK;
}

View File

@ -49,7 +49,7 @@ interface nsIJSRAIIHelper;
interface nsIContentPermissionRequest;
interface nsIObserver;
[scriptable, uuid(ca6a458c-82e7-4979-886e-6d214eac6f0b)]
[scriptable, uuid(46b44e33-13c2-4eb3-bf80-76a4e0857ccc)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1334,11 +1334,12 @@ interface nsIDOMWindowUtils : nsISupports {
readonly attribute boolean layerManagerRemote;
/**
* True if we can initialize a hardware-backed h264 decoder for a simple
* test video, does not mean that all h264 video decoding will be done
* Returns a Promise that will be resolved with a string once the capabilities
* of the h264 decoder have been determined.
* Success does not mean that all h264 video decoding will be done
* in hardware.
*/
readonly attribute AString supportsHardwareH264Decoding;
readonly attribute jsval supportsHardwareH264Decoding;
/**
* Record (and return) frame-intervals for frames which were presented

View File

@ -213,7 +213,8 @@ static const uint8_t sTestH264ExtraData[] = {
static already_AddRefed<MediaDataDecoder>
CreateTestH264Decoder(layers::LayersBackend aBackend,
VideoInfo& aConfig)
VideoInfo& aConfig,
FlushableTaskQueue* aTaskQueue)
{
aConfig.mMimeType = "video/avc";
aConfig.mId = 1;
@ -229,23 +230,63 @@ CreateTestH264Decoder(layers::LayersBackend aBackend,
RefPtr<PDMFactory> platform = new PDMFactory();
RefPtr<MediaDataDecoder> decoder(
platform->CreateDecoder(aConfig, nullptr, nullptr, aBackend, nullptr));
platform->CreateDecoder(aConfig, aTaskQueue, nullptr, aBackend, nullptr));
return decoder.forget();
}
/* static */ bool
MP4Decoder::IsVideoAccelerated(layers::LayersBackend aBackend, nsACString& aFailureReason)
/* static */ already_AddRefed<dom::Promise>
MP4Decoder::IsVideoAccelerated(layers::LayersBackend aBackend, nsIGlobalObject* aParent)
{
VideoInfo config;
RefPtr<MediaDataDecoder> decoder(CreateTestH264Decoder(aBackend, config));
if (!decoder) {
aFailureReason.AssignLiteral("Failed to create H264 decoder");
return false;
MOZ_ASSERT(NS_IsMainThread());
ErrorResult rv;
RefPtr<dom::Promise> promise;
promise = dom::Promise::Create(aParent, rv);
if (rv.Failed()) {
rv.SuppressException();
return nullptr;
}
bool result = decoder->IsHardwareAccelerated(aFailureReason);
decoder->Shutdown();
return result;
RefPtr<FlushableTaskQueue> taskQueue =
new FlushableTaskQueue(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER));
VideoInfo config;
RefPtr<MediaDataDecoder> decoder(CreateTestH264Decoder(aBackend, config, taskQueue));
if (!decoder) {
taskQueue->BeginShutdown();
taskQueue->AwaitShutdownAndIdle();
promise->MaybeResolve(NS_LITERAL_STRING("No; Failed to create H264 decoder"));
return promise.forget();
}
decoder->Init()
->Then(AbstractThread::MainThread(), __func__,
[promise, decoder, taskQueue] (TrackInfo::TrackType aTrack) {
nsCString failureReason;
bool ok = decoder->IsHardwareAccelerated(failureReason);
nsAutoString result;
if (ok) {
result.AssignLiteral("Yes");
} else {
result.AssignLiteral("No");
if (failureReason.Length()) {
result.AppendLiteral("; ");
AppendUTF8toUTF16(failureReason, result);
}
}
decoder->Shutdown();
taskQueue->BeginShutdown();
taskQueue->AwaitShutdownAndIdle();
promise->MaybeResolve(result);
},
[promise, decoder, taskQueue] (MediaDataDecoder::DecoderFailureReason aResult) {
decoder->Shutdown();
taskQueue->BeginShutdown();
taskQueue->AwaitShutdownAndIdle();
promise->MaybeResolve(NS_LITERAL_STRING("No; Failed to initialize H264 decoder"));
});
return promise.forget();
}
void

View File

@ -8,6 +8,7 @@
#include "MediaDecoder.h"
#include "MediaFormatReader.h"
#include "mozilla/dom/Promise.h"
namespace mozilla {
@ -38,7 +39,8 @@ public:
// Returns true if the MP4 backend is preffed on.
static bool IsEnabled();
static bool IsVideoAccelerated(layers::LayersBackend aBackend, nsACString& aReason);
static already_AddRefed<dom::Promise>
IsVideoAccelerated(layers::LayersBackend aBackend, nsIGlobalObject* aParent);
void GetMozDebugReaderData(nsAString& aString) override;