Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2265)

Unified Diff: content/common/gpu/media/dxva_video_decode_accelerator.cc

Issue 719273003: adds vp8 and vp9 dxva accelerated decode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: load with altered search path Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/media/dxva_video_decode_accelerator.cc
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc
index fffceb706fa9f1746844ccc2f7974c98684b6831..2fc53e7188acfd223d8cb847dd96e2b866adc4c9 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
@@ -14,21 +14,77 @@
#include <mferror.h>
#include <wmcodecdsp.h>
+#include "base/base_paths_win.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/file_version_info.h"
+#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
#include "base/win/windows_version.h"
#include "media/video/video_decode_accelerator.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_switches.h"
+namespace {
+
+// Path is appended on to the PROGRAM_FILES base path.
+const wchar_t kVPXDecoderDLLPath[] = L"Intel\\Media SDK\\";
+
+const wchar_t kVP8DecoderDLLName[] =
+#if defined(ARCH_CPU_X86)
+ L"mfx_mft_vp8vd_32.dll";
+#elif defined(ARCH_CPU_X86_64)
+ L"mfx_mft_vp8vd_64.dll";
+#else
+#error Unsupported Windows CPU Architecture
+#endif
+
+const wchar_t kVP9DecoderDLLName[] =
+#if defined(ARCH_CPU_X86)
+ L"mfx_mft_vp9vd_32.dll";
+#elif defined(ARCH_CPU_X86_64)
+ L"mfx_mft_vp9vd_64.dll";
+#else
+#error Unsupported Windows CPU Architecture
+#endif
+
+const CLSID CLSID_WebmMfVp8Dec = {
+ 0x451e3cb7,
+ 0x2622,
+ 0x4ba5,
+ { 0x8e, 0x1d, 0x44, 0xb3, 0xc4, 0x1d, 0x09, 0x24 }
+};
+
+const CLSID CLSID_WebmMfVp9Dec = {
+ 0x07ab4bd2,
+ 0x1979,
+ 0x4fcd,
+ { 0xa6, 0x97, 0xdf, 0x9a, 0xd1, 0x5b, 0x34, 0xfe }
+};
+
+const CLSID MEDIASUBTYPE_VP80 = {
+ 0x30385056,
+ 0x0000,
+ 0x0010,
+ { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+};
+
+const CLSID MEDIASUBTYPE_VP90 = {
+ 0x30395056,
+ 0x0000,
+ 0x0010,
+ { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+};
+
+}
+
namespace content {
// We only request 5 picture buffers from the client which are used to hold the
@@ -431,7 +487,8 @@ DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
pictures_requested_(false),
inputs_before_decode_(0),
make_context_current_(make_context_current),
- weak_this_factory_(this) {
+ weak_this_factory_(this),
+ codec_(media::kUnknownVideoCodec) {
memset(&input_stream_info_, 0, sizeof(input_stream_info_));
memset(&output_stream_info_, 0, sizeof(output_stream_info_));
}
@@ -458,9 +515,11 @@ bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
// H264PROFILE_HIGH video decoding is janky at times. Needs more
// investigation. http://crbug.com/426707
if (profile != media::H264PROFILE_BASELINE &&
- profile != media::H264PROFILE_MAIN) {
+ profile != media::H264PROFILE_MAIN &&
+ profile != media::VP8PROFILE_ANY &&
+ profile != media::VP9PROFILE_ANY) {
RETURN_AND_NOTIFY_ON_FAILURE(false,
- "Unsupported h264 profile", PLATFORM_FAILURE, false);
+ "Unsupported h.264, vp8, or vp9 profile", PLATFORM_FAILURE, false);
}
RETURN_AND_NOTIFY_ON_FAILURE(
@@ -639,30 +698,51 @@ bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() {
}
bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
- if (profile < media::H264PROFILE_MIN || profile > media::H264PROFILE_MAX)
- return false;
-
- // We mimic the steps CoCreateInstance uses to instantiate the object. This
- // was previously done because it failed inside the sandbox, and now is done
- // as a more minimal approach to avoid other side-effects CCI might have (as
- // we are still in a reduced sandbox).
- HMODULE decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll");
- RETURN_ON_FAILURE(decoder_dll,
- "msmpeg2vdec.dll required for decoding is not loaded",
- false);
-
- // Check version of DLL, version 6.7.7140 is blacklisted due to high crash
- // rates in browsers loading that DLL. If that is the version installed we
- // fall back to software decoding. See crbug/403440.
- FileVersionInfo* version_info =
- FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll);
- RETURN_ON_FAILURE(version_info,
- "unable to get version of msmpeg2vdec.dll",
- false);
- base::string16 file_version = version_info->file_version();
- RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos,
- "blacklisted version of msmpeg2vdec.dll 6.7.7140",
- false);
+ HMODULE decoder_dll = NULL;
+
+ // Profile must fall within the valid range for one of the supported codecs.
+ if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) {
+ // We mimic the steps CoCreateInstance uses to instantiate the object. This
+ // was previously done because it failed inside the sandbox, and now is done
+ // as a more minimal approach to avoid other side-effects CCI might have (as
+ // we are still in a reduced sandbox).
+ decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll");
+ RETURN_ON_FAILURE(decoder_dll,
+ "msmpeg2vdec.dll required for decoding is not loaded",
+ false);
+
+ // Check version of DLL, version 6.7.7140 is blacklisted due to high crash
+ // rates in browsers loading that DLL. If that is the version installed we
+ // fall back to software decoding. See crbug/403440.
+ FileVersionInfo* version_info =
+ FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll);
+ RETURN_ON_FAILURE(version_info,
+ "unable to get version of msmpeg2vdec.dll",
+ false);
+ base::string16 file_version = version_info->file_version();
+ RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos,
+ "blacklisted version of msmpeg2vdec.dll 6.7.7140",
+ false);
+ codec_ = media::kCodecH264;
+ } else if (profile == media::VP8PROFILE_ANY ||
+ profile == media::VP9PROFILE_ANY) {
+ base::FilePath dll_path;
+ RETURN_ON_FAILURE(PathService::Get(base::DIR_PROGRAM_FILES, &dll_path),
+ "failed to get path for DIR_PROGRAM_FILES", false);
+ dll_path = dll_path.Append(kVPXDecoderDLLPath);
+ if (profile == media::VP8PROFILE_ANY) {
+ codec_ = media::kCodecVP8;
+ dll_path = dll_path.Append(kVP8DecoderDLLName);
+ } else {
+ codec_ = media::kCodecVP9;
+ dll_path = dll_path.Append(kVP9DecoderDLLName);
+ }
+ decoder_dll = ::LoadLibraryEx(dll_path.value().data(), NULL,
+ LOAD_WITH_ALTERED_SEARCH_PATH);
+ RETURN_ON_FAILURE(decoder_dll, "vpx decoder dll is not loaded", false);
+ } else {
+ RETURN_ON_FAILURE(false, "Unsupported codec.", false);
+ }
typedef HRESULT(WINAPI * GetClassObject)(
const CLSID & clsid, const IID & iid, void * *object);
@@ -673,9 +753,22 @@ bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) {
get_class_object, "Failed to get DllGetClassObject pointer", false);
base::win::ScopedComPtr<IClassFactory> factory;
- HRESULT hr = get_class_object(__uuidof(CMSH264DecoderMFT),
- __uuidof(IClassFactory),
- reinterpret_cast<void**>(factory.Receive()));
+ HRESULT hr;
+ if (codec_ == media::kCodecH264) {
+ hr = get_class_object(__uuidof(CMSH264DecoderMFT),
+ __uuidof(IClassFactory),
+ reinterpret_cast<void**>(factory.Receive()));
+ } else if (codec_ == media::kCodecVP8) {
+ hr = get_class_object(CLSID_WebmMfVp8Dec,
+ __uuidof(IClassFactory),
+ reinterpret_cast<void**>(factory.Receive()));
+ } else if (codec_ == media::kCodecVP9) {
+ hr = get_class_object(CLSID_WebmMfVp9Dec,
+ __uuidof(IClassFactory),
+ reinterpret_cast<void**>(factory.Receive()));
+ } else {
+ RETURN_ON_FAILURE(false, "Unsupported codec.", false);
+ }
RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false);
hr = factory->CreateInstance(NULL,
@@ -725,8 +818,11 @@ bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() {
hr = attributes->GetUINT32(MF_SA_D3D_AWARE, &dxva);
RETURN_ON_HR_FAILURE(hr, "Failed to check if decoder supports DXVA", false);
- hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE);
- RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false);
+ if (codec_ == media::kCodecH264) {
+ hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE);
+ RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false);
+ }
+
return true;
}
@@ -744,7 +840,16 @@ bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() {
hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
RETURN_ON_HR_FAILURE(hr, "Failed to set major input type", false);
- hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
+ if (codec_ == media::kCodecH264) {
+ hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
+ } else if (codec_ == media::kCodecVP8) {
+ hr = media_type->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_VP80);
+ } else if (codec_ == media::kCodecVP9) {
+ hr = media_type->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_VP90);
+ } else {
+ NOTREACHED();
+ RETURN_ON_FAILURE(false, "Unsupported codec on input media type.", false);
+ }
RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false);
// Not sure about this. msdn recommends setting this value on the input
@@ -798,10 +903,12 @@ bool DXVAVideoDecodeAccelerator::GetStreamsInfoAndBufferReqs() {
DVLOG(1) << "Input stream info: ";
DVLOG(1) << "Max latency: " << input_stream_info_.hnsMaxLatency;
- // There should be three flags, one for requiring a whole frame be in a
- // single sample, one for requiring there be one buffer only in a single
- // sample, and one that specifies a fixed sample size. (as in cbSize)
- CHECK_EQ(input_stream_info_.dwFlags, 0x7u);
+ if (codec_ == media::kCodecH264) {
+ // There should be three flags, one for requiring a whole frame be in a
+ // single sample, one for requiring there be one buffer only in a single
+ // sample, and one that specifies a fixed sample size. (as in cbSize)
+ CHECK_EQ(input_stream_info_.dwFlags, 0x7u);
+ }
DVLOG(1) << "Min buffer size: " << input_stream_info_.cbSize;
DVLOG(1) << "Max lookahead: " << input_stream_info_.cbMaxLookahead;
@@ -813,7 +920,9 @@ bool DXVAVideoDecodeAccelerator::GetStreamsInfoAndBufferReqs() {
// allocate its own sample.
DVLOG(1) << "Flags: "
<< std::hex << std::showbase << output_stream_info_.dwFlags;
- CHECK_EQ(output_stream_info_.dwFlags, 0x107u);
+ if (codec_ == media::kCodecH264) {
+ CHECK_EQ(output_stream_info_.dwFlags, 0x107u);
+ }
DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize;
DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment;
return true;
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698