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

Side by Side Diff: content/common/gpu/media/dxva_video_decode_accelerator.cc

Issue 11411249: Do DXVA pre-sandbox initialization off the main thread. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h"
6 6
7 #if !defined(OS_WIN) 7 #if !defined(OS_WIN)
8 #error This file should only be built on Windows. 8 #error This file should only be built on Windows.
9 #endif // !defined(OS_WIN) 9 #endif // !defined(OS_WIN)
10 10
11 #include <ks.h> 11 #include <ks.h>
12 #include <codecapi.h> 12 #include <codecapi.h>
13 #include <mfapi.h> 13 #include <mfapi.h>
14 #include <mferror.h> 14 #include <mferror.h>
15 #include <wmcodecdsp.h> 15 #include <wmcodecdsp.h>
16 16
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/callback.h" 18 #include "base/callback.h"
19 #include "base/command_line.h" 19 #include "base/command_line.h"
20 #include "base/debug/trace_event.h" 20 #include "base/debug/trace_event.h"
21 #include "base/logging.h" 21 #include "base/logging.h"
22 #include "base/memory/scoped_handle.h" 22 #include "base/memory/scoped_handle.h"
23 #include "base/memory/scoped_ptr.h" 23 #include "base/memory/scoped_ptr.h"
24 #include "base/message_loop.h" 24 #include "base/message_loop.h"
25 #include "base/process_util.h" 25 #include "base/process_util.h"
26 #include "base/shared_memory.h" 26 #include "base/shared_memory.h"
27 #include "base/threading/worker_pool.h"
27 #include "media/video/video_decode_accelerator.h" 28 #include "media/video/video_decode_accelerator.h"
28 #include "third_party/angle/include/EGL/egl.h" 29 #include "third_party/angle/include/EGL/egl.h"
29 #include "third_party/angle/include/EGL/eglext.h" 30 #include "third_party/angle/include/EGL/eglext.h"
30 #include "ui/gl/gl_bindings.h" 31 #include "ui/gl/gl_bindings.h"
31 #include "ui/gl/gl_surface.h" 32 #include "ui/gl/gl_surface.h"
32 #include "ui/gl/gl_switches.h" 33 #include "ui/gl/gl_switches.h"
33 34
34 namespace content { 35 namespace content {
35 36
36 // We only request 5 picture buffers from the client which are used to hold the 37 // We only request 5 picture buffers from the client which are used to hold the
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 361
361 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo( 362 DXVAVideoDecodeAccelerator::PendingSampleInfo::PendingSampleInfo(
362 int32 buffer_id, IMFSample* sample) 363 int32 buffer_id, IMFSample* sample)
363 : input_buffer_id(buffer_id) { 364 : input_buffer_id(buffer_id) {
364 output_sample.Attach(sample); 365 output_sample.Attach(sample);
365 } 366 }
366 367
367 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {} 368 DXVAVideoDecodeAccelerator::PendingSampleInfo::~PendingSampleInfo() {}
368 369
369 // static 370 // static
370 void DXVAVideoDecodeAccelerator::PreSandboxInitialization() { 371 // Initializes DXVA on a separate thread.
372 void DXVAVideoDecodeAccelerator::PreSandboxInitialization(
373 const base::Closure& completion_task) {
371 // Should be called only once during program startup. 374 // Should be called only once during program startup.
372 DCHECK(!pre_sandbox_init_done_); 375 DCHECK(!pre_sandbox_init_done_);
373 376
377 base::ScopedClosureRunner scoped_completion_runner(completion_task);
378
374 static wchar_t* decoding_dlls[] = { 379 static wchar_t* decoding_dlls[] = {
375 L"d3d9.dll", 380 L"d3d9.dll",
376 L"dxva2.dll", 381 L"dxva2.dll",
377 L"mf.dll", 382 L"mf.dll",
378 L"mfplat.dll", 383 L"mfplat.dll",
379 L"msmpeg2vdec.dll", 384 L"msmpeg2vdec.dll",
380 }; 385 };
381 386
382 for (int i = 0; i < arraysize(decoding_dlls); ++i) { 387 for (int i = 0; i < arraysize(decoding_dlls); ++i) {
383 if (!::LoadLibrary(decoding_dlls[i])) { 388 if (!::LoadLibrary(decoding_dlls[i])) {
384 DLOG(ERROR) << "Failed to load decoder dll: " << decoding_dlls[i] 389 DLOG(ERROR) << "Failed to load decoder dll: " << decoding_dlls[i]
385 << ", Error: " << ::GetLastError(); 390 << ", Error: " << ::GetLastError();
386 return; 391 return;
387 } 392 }
388 } 393 }
389 394
390 RETURN_ON_FAILURE(CreateD3DDevManager(), 395 HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9_);
391 "Failed to initialize D3D device and manager",); 396 RETURN_ON_HR_FAILURE(hr,
392 pre_sandbox_init_done_ = true; 397 "Failed to initialize D3D9.",);
398
399 // Initialize H/W video decoding stuff which fails in the sandbox. This is
400 // done on a worker thread because it takes 10s of ms.
401 scoped_completion_runner.Release();
402 base::WorkerPool::PostTask(
403 FROM_HERE,
404 base::Bind(&DXVAVideoDecodeAccelerator::CreateD3DDevManager,
405 completion_task),
406 true);
393 } 407 }
394 408
395 // static 409 // static
396 bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() { 410 void DXVAVideoDecodeAccelerator::CreateD3DDevManager(
397 HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9_); 411 const base::Closure& completion_task) {
398 RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); 412 base::ScopedClosureRunner scoped_completion_runner(completion_task);
399 413
400 D3DPRESENT_PARAMETERS present_params = {0}; 414 D3DPRESENT_PARAMETERS present_params = {0};
401 present_params.BackBufferWidth = 1; 415 present_params.BackBufferWidth = 1;
402 present_params.BackBufferHeight = 1; 416 present_params.BackBufferHeight = 1;
403 present_params.BackBufferFormat = D3DFMT_UNKNOWN; 417 present_params.BackBufferFormat = D3DFMT_UNKNOWN;
404 present_params.BackBufferCount = 1; 418 present_params.BackBufferCount = 1;
405 present_params.SwapEffect = D3DSWAPEFFECT_DISCARD; 419 present_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
406 present_params.hDeviceWindow = ::GetShellWindow(); 420 present_params.hDeviceWindow = ::GetShellWindow();
407 present_params.Windowed = TRUE; 421 present_params.Windowed = TRUE;
408 present_params.Flags = D3DPRESENTFLAG_VIDEO; 422 present_params.Flags = D3DPRESENTFLAG_VIDEO;
409 present_params.FullScreen_RefreshRateInHz = 0; 423 present_params.FullScreen_RefreshRateInHz = 0;
410 present_params.PresentationInterval = 0; 424 present_params.PresentationInterval = 0;
411 425
412 hr = d3d9_->CreateDeviceEx(D3DADAPTER_DEFAULT, 426 HRESULT hr = d3d9_->CreateDeviceEx(D3DADAPTER_DEFAULT,
413 D3DDEVTYPE_HAL, 427 D3DDEVTYPE_HAL,
414 ::GetShellWindow(), 428 ::GetShellWindow(),
415 D3DCREATE_FPU_PRESERVE | 429 D3DCREATE_FPU_PRESERVE |
416 D3DCREATE_SOFTWARE_VERTEXPROCESSING | 430 D3DCREATE_SOFTWARE_VERTEXPROCESSING |
417 D3DCREATE_DISABLE_PSGP_THREADING | 431 D3DCREATE_DISABLE_PSGP_THREADING |
418 D3DCREATE_MULTITHREADED, 432 D3DCREATE_MULTITHREADED,
419 &present_params, 433 &present_params,
420 NULL, 434 NULL,
421 &device_); 435 &device_);
422 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false); 436 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device",);
423 437
424 hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_, 438 hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_,
425 &device_manager_); 439 &device_manager_);
426 RETURN_ON_HR_FAILURE(hr, "DXVA2CreateDirect3DDeviceManager9 failed", false); 440 RETURN_ON_HR_FAILURE(hr, "DXVA2CreateDirect3DDeviceManager9 failed",);
427 441
428 hr = device_manager_->ResetDevice(device_, dev_manager_reset_token_); 442 hr = device_manager_->ResetDevice(device_, dev_manager_reset_token_);
429 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 443 RETURN_ON_HR_FAILURE(hr, "Failed to reset device",);
430 444
431 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, &query_); 445 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, &query_);
432 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); 446 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query",);
447
433 // Ensure query_ API works (to avoid an infinite loop later in 448 // Ensure query_ API works (to avoid an infinite loop later in
434 // CopyOutputSampleDataToPictureBuffer). 449 // CopyOutputSampleDataToPictureBuffer).
435 hr = query_->Issue(D3DISSUE_END); 450 hr = query_->Issue(D3DISSUE_END);
436 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); 451 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query",);
437 return true; 452
453 pre_sandbox_init_done_ = true;
438 } 454 }
439 455
440 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( 456 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
441 media::VideoDecodeAccelerator::Client* client, 457 media::VideoDecodeAccelerator::Client* client,
442 const base::Callback<bool(void)>& make_context_current) 458 const base::Callback<bool(void)>& make_context_current)
443 : client_(client), 459 : client_(client),
444 egl_config_(NULL), 460 egl_config_(NULL),
445 state_(kUninitialized), 461 state_(kUninitialized),
446 pictures_requested_(false), 462 pictures_requested_(false),
447 inputs_before_decode_(0), 463 inputs_before_decode_(0),
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 return; 1090 return;
1075 } 1091 }
1076 1092
1077 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 1093 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
1078 &DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this))); 1094 &DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this)));
1079 1095
1080 state_ = kNormal; 1096 state_ = kNormal;
1081 } 1097 }
1082 1098
1083 } // namespace content 1099 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698