Files
palemoon27/dom/media/platforms/wmf/WMFDecoderModule.cpp
T
roytam1 76c2cfb906 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1232902. Update ANGLE to chromium/2592 (89d3d3cfad)
- Bug 1251375. Update to ANGLE/2653 (98691dfd84)
- bits of Bug 1225280. Update ANGLE to chromium/2572. (b5eeadcb4e)
- Bug 1251375 - Cross compilation fixup. r=upstream (737d8f8554)
- rename back (e1ef46b16a)
- Bug 1261129: Make VP9 sample data const. r=kentuckyfriedtakahe (811eead31b)
- Bug 1263839 - WebM is now actually a VP9 sample; r=me (c6568d6d98)
- Bug 1263839: P2. Force re-run of VP9 benchmark based on a version check. r=kentuckyfriedtakahe (358409a235)
- Bug 1235503 - Fix -Wunreachable-code warnings in dom/media/. r=jya (dc6bebb141)
- Bug 1251184: [quicktime] P1. Report video/quicktime mimetype when sniffing. r=cpearce (056dda066a)
- Bug 1251184: [quicktime] P2. Use external plugin if available over native playback. r=cpearce (6f34c09ab6)
- Bug 1255050 - [1.1] Restrict media plugin decoder usage to Android ICS. r=snorp (ae801e040c)
- Bug 1229657: [MSE] Returns NotSupportedError if mimetype is invalid or not supported. r=gerald (a81df7babf)
- change errors returns (18b81f684e)
- rearrange to match gecko code (333c4c5f3a)
- Bug 1239607 - Let platform layer decide which codec to support and how to configure it. r=sotaro (63812a44d1)
- Bug 1248507 - p1. Pass DecoderDoctorDiagnostics to PDMs&more - r=jya (4175551833)
- Bug 1248507 - p2. DecoderDoctorDiagnostics boilerplate - r=jya (cb25b71956)
- Bug 1208371 - Forward declare DOMMediaStream in HTMLMediaElement.h. r=jesup (896080a020)
- Bug 1248507 - p3. Use DecoderDoctorDiagnostics - r=jya,bz (181966589e)
- Bug 1248507 - p4. DecoderDoctor base console message - r=bz (c5704ad2fe)
- Bug 1055776 - Move namespaceURI, prefix, localName from Node to Element; r=bz (ba7a18385d)
- Bug 842818 - Expose WebCrypto API to workers r=baku (966e5f3e75)
- Bug 1227790 - Update MediaKeyStatuses to include "released", "output-restricted" and "status-pending". r=bz (d9e7ddb298)
- Bug 1256046 - Hide MozPowerManager from the Web; r=khuey,bzbarsky (ec1da24251)
- Bug 1259581: Remove MOZ_MEDIA_NAVIGATOR. r=jesup (023a114462)
- Bug 1254956 - Implement Node.rootNode. r=Ms2ger,smaug (0133a41059)
- Bug 1264409 - Make last transaction ID available via nsIDOMWindowUtils, and pass transaction ID through MozAfterPaint. r=mattwoodrow,mrbkap (51184de1af)
2024-05-16 23:59:56 +08:00

226 lines
6.1 KiB
C++

/* -*- 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 "WMF.h"
#include "WMFDecoderModule.h"
#include "WMFVideoMFTManager.h"
#include "WMFAudioMFTManager.h"
#include "MFTDecoder.h"
#include "mozilla/Preferences.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Services.h"
#include "WMFMediaDataDecoder.h"
#include "nsIWindowsRegKey.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIGfxInfo.h"
#include "GfxDriverInfo.h"
#include "gfxWindowsPlatform.h"
#include "MediaInfo.h"
#include "prsystem.h"
#include "mozilla/Maybe.h"
#include "mozilla/StaticMutex.h"
namespace mozilla {
static bool sDXVAEnabled = false;
static int sNumDecoderThreads = -1;
static bool sIsIntelDecoderEnabled = false;
static bool sLowLatencyMFTEnabled = false;
WMFDecoderModule::WMFDecoderModule()
: mWMFInitialized(false)
{
}
WMFDecoderModule::~WMFDecoderModule()
{
if (mWMFInitialized) {
DebugOnly<HRESULT> hr = wmf::MFShutdown();
NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");
}
}
static void
SetNumOfDecoderThreads()
{
MOZ_ASSERT(NS_IsMainThread(), "Preferences can only be read on main thread");
int32_t numCores = PR_GetNumberOfProcessors();
// If we have more than 4 cores, let the decoder decide how many threads.
// On an 8 core machine, WMF chooses 4 decoder threads
const int WMF_DECODER_DEFAULT = -1;
int32_t prefThreadCount = Preferences::GetInt("media.wmf.decoder.thread-count", -1);
if (prefThreadCount != WMF_DECODER_DEFAULT) {
sNumDecoderThreads = std::max(prefThreadCount, 1);
} else if (numCores > 4) {
sNumDecoderThreads = WMF_DECODER_DEFAULT;
} else {
sNumDecoderThreads = std::max(numCores - 1, 1);
}
}
/* static */
void
WMFDecoderModule::Init()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
sDXVAEnabled = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding();
Preferences::AddBoolVarCache(&sIsIntelDecoderEnabled,
"media.webm.intel_decoder.enabled");
sLowLatencyMFTEnabled = Preferences::GetBool("media.wmf.low-latency.enabled", false);
SetNumOfDecoderThreads();
}
/* static */
int
WMFDecoderModule::GetNumDecoderThreads()
{
return sNumDecoderThreads;
}
/* static */
bool
WMFDecoderModule::LowLatencyMFTEnabled()
{
return sLowLatencyMFTEnabled;
}
nsresult
WMFDecoderModule::Startup()
{
mWMFInitialized = SUCCEEDED(wmf::MFStartup());
return mWMFInitialized ? NS_OK : NS_ERROR_FAILURE;
}
already_AddRefed<MediaDataDecoder>
WMFDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig,
layers::LayersBackend aLayersBackend,
layers::ImageContainer* aImageContainer,
FlushableTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback,
DecoderDoctorDiagnostics* aDiagnostics)
{
nsAutoPtr<WMFVideoMFTManager> manager(
new WMFVideoMFTManager(aConfig,
aLayersBackend,
aImageContainer,
sDXVAEnabled));
if (!manager->Init()) {
return nullptr;
}
RefPtr<MediaDataDecoder> decoder =
new WMFMediaDataDecoder(manager.forget(), aVideoTaskQueue, aCallback);
return decoder.forget();
}
already_AddRefed<MediaDataDecoder>
WMFDecoderModule::CreateAudioDecoder(const AudioInfo& aConfig,
FlushableTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback,
DecoderDoctorDiagnostics* aDiagnostics)
{
nsAutoPtr<WMFAudioMFTManager> manager(new WMFAudioMFTManager(aConfig));
if (!manager->Init()) {
return nullptr;
}
RefPtr<MediaDataDecoder> decoder =
new WMFMediaDataDecoder(manager.forget(), aAudioTaskQueue, aCallback);
return decoder.forget();
}
static bool
CanCreateMFTDecoder(const GUID& aGuid)
{
if (FAILED(wmf::MFStartup())) {
return false;
}
bool hasdecoder = false;
{
RefPtr<MFTDecoder> decoder(new MFTDecoder());
hasdecoder = SUCCEEDED(decoder->Create(aGuid));
}
wmf::MFShutdown();
return hasdecoder;
}
template<const GUID& aGuid>
static bool
CanCreateWMFDecoder()
{
static StaticMutex sMutex;
StaticMutexAutoLock lock(sMutex);
static Maybe<bool> result;
if (result.isNothing()) {
result.emplace(CanCreateMFTDecoder(aGuid));
}
return result.value();
}
/* static */ bool
WMFDecoderModule::HasH264()
{
return CanCreateWMFDecoder<CLSID_CMSH264DecoderMFT>();
}
/* static */ bool
WMFDecoderModule::HasAAC()
{
return CanCreateWMFDecoder<CLSID_CMSAACDecMFT>();
}
bool
WMFDecoderModule::SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const
{
if ((aMimeType.EqualsLiteral("audio/mp4a-latm") ||
aMimeType.EqualsLiteral("audio/mp4")) &&
WMFDecoderModule::HasAAC()) {
return true;
}
if ((aMimeType.EqualsLiteral("video/avc") ||
aMimeType.EqualsLiteral("video/mp4")) &&
WMFDecoderModule::HasH264()) {
return true;
}
if (aMimeType.EqualsLiteral("audio/mpeg") &&
CanCreateWMFDecoder<CLSID_CMP3DecMediaObject>()) {
return true;
}
if (sIsIntelDecoderEnabled && sDXVAEnabled) {
if (aMimeType.EqualsLiteral("video/webm; codecs=vp8") &&
CanCreateWMFDecoder<CLSID_WebmMfVp8Dec>()) {
return true;
}
if (aMimeType.EqualsLiteral("video/webm; codecs=vp9") &&
CanCreateWMFDecoder<CLSID_WebmMfVp9Dec>()) {
return true;
}
}
// Some unsupported codec.
return false;
}
PlatformDecoderModule::ConversionRequired
WMFDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
{
if (aConfig.IsVideo() &&
(aConfig.mMimeType.EqualsLiteral("video/avc") ||
aConfig.mMimeType.EqualsLiteral("video/mp4"))) {
return kNeedAnnexB;
} else {
return kNeedNone;
}
}
} // namespace mozilla