OLD | NEW |
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 "media/gpu/dxva_video_decode_accelerator_win.h" | 5 #include "media/gpu/dxva_video_decode_accelerator_win.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #if !defined(OS_WIN) | 9 #if !defined(OS_WIN) |
10 #error This file should only be built on Windows. | 10 #error This file should only be built on Windows. |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 hr = d3d11_device_->CreateQuery(&query_desc, d3d11_query_.Receive()); | 822 hr = d3d11_device_->CreateQuery(&query_desc, d3d11_query_.Receive()); |
823 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); | 823 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); |
824 | 824 |
825 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); | 825 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); |
826 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", | 826 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", |
827 false); | 827 false); |
828 | 828 |
829 hr = CreateCOMObjectFromDll(video_processor_dll, CLSID_VideoProcessorMFT, | 829 hr = CreateCOMObjectFromDll(video_processor_dll, CLSID_VideoProcessorMFT, |
830 __uuidof(IMFTransform), | 830 __uuidof(IMFTransform), |
831 video_format_converter_mft_.ReceiveVoid()); | 831 video_format_converter_mft_.ReceiveVoid()); |
832 if (FAILED(hr)) { | |
833 base::debug::Alias(&hr); | |
834 // TODO(ananta) | |
835 // Remove this CHECK when the change to use DX11 for H/W decoding | |
836 // stablizes. | |
837 CHECK(false); | |
838 } | |
839 | |
840 RETURN_ON_HR_FAILURE(hr, "Failed to create video format converter", false); | 832 RETURN_ON_HR_FAILURE(hr, "Failed to create video format converter", false); |
841 | 833 |
842 base::win::ScopedComPtr<IMFAttributes> converter_attributes; | 834 base::win::ScopedComPtr<IMFAttributes> converter_attributes; |
843 hr = video_format_converter_mft_->GetAttributes( | 835 hr = video_format_converter_mft_->GetAttributes( |
844 converter_attributes.Receive()); | 836 converter_attributes.Receive()); |
845 RETURN_ON_HR_FAILURE(hr, "Failed to get converter attributes", false); | 837 RETURN_ON_HR_FAILURE(hr, "Failed to get converter attributes", false); |
846 | 838 |
847 hr = converter_attributes->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE); | 839 hr = converter_attributes->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE); |
848 RETURN_ON_HR_FAILURE( | 840 RETURN_ON_HR_FAILURE( |
849 hr, "Failed to set MF_XVP_PLAYBACK_MODE attribute on converter", false); | 841 hr, "Failed to set MF_XVP_PLAYBACK_MODE attribute on converter", false); |
(...skipping 1540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2390 hr = MFCreateSample(output_sample.Receive()); | 2382 hr = MFCreateSample(output_sample.Receive()); |
2391 if (FAILED(hr)) { | 2383 if (FAILED(hr)) { |
2392 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.", | 2384 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.", |
2393 PLATFORM_FAILURE, ); | 2385 PLATFORM_FAILURE, ); |
2394 } | 2386 } |
2395 | 2387 |
2396 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; | 2388 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; |
2397 hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), dest_texture, 0, | 2389 hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), dest_texture, 0, |
2398 FALSE, output_buffer.Receive()); | 2390 FALSE, output_buffer.Receive()); |
2399 if (FAILED(hr)) { | 2391 if (FAILED(hr)) { |
2400 base::debug::Alias(&hr); | |
2401 // TODO(ananta) | |
2402 // Remove this CHECK when the change to use DX11 for H/W decoding | |
2403 // stablizes. | |
2404 CHECK(false); | |
2405 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.", | 2392 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.", |
2406 PLATFORM_FAILURE, ); | 2393 PLATFORM_FAILURE, ); |
2407 } | 2394 } |
2408 | 2395 |
2409 output_sample->AddBuffer(output_buffer.get()); | 2396 output_sample->AddBuffer(output_buffer.get()); |
2410 | 2397 |
2411 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0); | 2398 hr = video_format_converter_mft_->ProcessInput(0, video_frame, 0); |
2412 if (FAILED(hr)) { | 2399 if (FAILED(hr)) { |
2413 DCHECK(false); | 2400 DCHECK(false); |
2414 RETURN_AND_NOTIFY_ON_HR_FAILURE( | 2401 RETURN_AND_NOTIFY_ON_HR_FAILURE( |
2415 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, ); | 2402 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, ); |
2416 } | 2403 } |
2417 | 2404 |
2418 DWORD status = 0; | 2405 DWORD status = 0; |
2419 MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; | 2406 MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; |
2420 format_converter_output.pSample = output_sample.get(); | 2407 format_converter_output.pSample = output_sample.get(); |
2421 hr = video_format_converter_mft_->ProcessOutput( | 2408 hr = video_format_converter_mft_->ProcessOutput( |
2422 0, // No flags | 2409 0, // No flags |
2423 1, // # of out streams to pull from | 2410 1, // # of out streams to pull from |
2424 &format_converter_output, &status); | 2411 &format_converter_output, &status); |
2425 | 2412 |
2426 if (FAILED(hr)) { | 2413 if (FAILED(hr)) { |
2427 base::debug::Alias(&hr); | 2414 DCHECK(false); |
2428 // TODO(ananta) | |
2429 // Remove this CHECK when the change to use DX11 for H/W decoding | |
2430 // stablizes. | |
2431 CHECK(false); | |
2432 RETURN_AND_NOTIFY_ON_HR_FAILURE( | 2415 RETURN_AND_NOTIFY_ON_HR_FAILURE( |
2433 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, ); | 2416 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, ); |
2434 } | 2417 } |
2435 | 2418 |
2436 if (dest_keyed_mutex) { | 2419 if (dest_keyed_mutex) { |
2437 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1); | 2420 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1); |
2438 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.", | 2421 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.", |
2439 PLATFORM_FAILURE, ); | 2422 PLATFORM_FAILURE, ); |
2440 | 2423 |
2441 main_thread_task_runner_->PostTask( | 2424 main_thread_task_runner_->PostTask( |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2476 // return success occassionally on multi core machines, leading to an | 2459 // return success occassionally on multi core machines, leading to an |
2477 // infinite loop. | 2460 // infinite loop. |
2478 // Workaround is to have an upper limit of 4 on the number of iterations to | 2461 // Workaround is to have an upper limit of 4 on the number of iterations to |
2479 // wait for the Flush to finish. | 2462 // wait for the Flush to finish. |
2480 | 2463 |
2481 HRESULT hr = E_FAIL; | 2464 HRESULT hr = E_FAIL; |
2482 if (use_dx11_) { | 2465 if (use_dx11_) { |
2483 BOOL query_data = 0; | 2466 BOOL query_data = 0; |
2484 hr = d3d11_device_context_->GetData(d3d11_query_.get(), &query_data, | 2467 hr = d3d11_device_context_->GetData(d3d11_query_.get(), &query_data, |
2485 sizeof(BOOL), 0); | 2468 sizeof(BOOL), 0); |
2486 if (FAILED(hr)) { | 2469 if (FAILED(hr)) |
2487 base::debug::Alias(&hr); | 2470 DCHECK(false); |
2488 // TODO(ananta) | |
2489 // Remove this CHECK when the change to use DX11 for H/W decoding | |
2490 // stablizes. | |
2491 CHECK(false); | |
2492 } | |
2493 } else { | 2471 } else { |
2494 hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); | 2472 hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); |
2495 } | 2473 } |
2496 | 2474 |
2497 if ((hr == S_FALSE) && (++iterations < kMaxIterationsForD3DFlush)) { | 2475 if ((hr == S_FALSE) && (++iterations < kMaxIterationsForD3DFlush)) { |
2498 decoder_thread_task_runner_->PostDelayedTask( | 2476 decoder_thread_task_runner_->PostDelayedTask( |
2499 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, | 2477 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushDecoder, |
2500 base::Unretained(this), iterations, src_surface, | 2478 base::Unretained(this), iterations, src_surface, |
2501 dest_surface, picture_buffer_id, input_buffer_id), | 2479 dest_surface, picture_buffer_id, input_buffer_id), |
2502 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); | 2480 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); |
(...skipping 11 matching lines...) Expand all Loading... |
2514 int height) { | 2492 int height) { |
2515 if (!dx11_video_format_converter_media_type_needs_init_) | 2493 if (!dx11_video_format_converter_media_type_needs_init_) |
2516 return true; | 2494 return true; |
2517 | 2495 |
2518 CHECK(video_format_converter_mft_.get()); | 2496 CHECK(video_format_converter_mft_.get()); |
2519 | 2497 |
2520 HRESULT hr = video_format_converter_mft_->ProcessMessage( | 2498 HRESULT hr = video_format_converter_mft_->ProcessMessage( |
2521 MFT_MESSAGE_SET_D3D_MANAGER, | 2499 MFT_MESSAGE_SET_D3D_MANAGER, |
2522 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get())); | 2500 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get())); |
2523 | 2501 |
2524 if (FAILED(hr)) { | 2502 if (FAILED(hr)) |
2525 base::debug::Alias(&hr); | 2503 DCHECK(false); |
2526 // TODO(ananta) | 2504 |
2527 // Remove this CHECK when the change to use DX11 for H/W decoding | |
2528 // stablizes. | |
2529 CHECK(false); | |
2530 } | |
2531 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, | 2505 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, |
2532 "Failed to initialize video format converter", | 2506 "Failed to initialize video format converter", |
2533 PLATFORM_FAILURE, false); | 2507 PLATFORM_FAILURE, false); |
2534 | 2508 |
2535 video_format_converter_mft_->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, | 2509 video_format_converter_mft_->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, |
2536 0); | 2510 0); |
2537 | 2511 |
2538 base::win::ScopedComPtr<IMFMediaType> media_type; | 2512 base::win::ScopedComPtr<IMFMediaType> media_type; |
2539 hr = MFCreateMediaType(media_type.Receive()); | 2513 hr = MFCreateMediaType(media_type.Receive()); |
2540 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "MFCreateMediaType failed", | 2514 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "MFCreateMediaType failed", |
2541 PLATFORM_FAILURE, false); | 2515 PLATFORM_FAILURE, false); |
2542 | 2516 |
2543 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); | 2517 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); |
2544 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set major input type", | 2518 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set major input type", |
2545 PLATFORM_FAILURE, false); | 2519 PLATFORM_FAILURE, false); |
2546 | 2520 |
2547 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); | 2521 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); |
2548 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type", | 2522 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type", |
2549 PLATFORM_FAILURE, false); | 2523 PLATFORM_FAILURE, false); |
2550 | 2524 |
2551 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height); | 2525 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height); |
2552 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes", | 2526 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes", |
2553 PLATFORM_FAILURE, false); | 2527 PLATFORM_FAILURE, false); |
2554 | 2528 |
2555 hr = video_format_converter_mft_->SetInputType(0, media_type.get(), 0); | 2529 hr = video_format_converter_mft_->SetInputType(0, media_type.get(), 0); |
2556 if (FAILED(hr)) { | 2530 if (FAILED(hr)) |
2557 base::debug::Alias(&hr); | 2531 DCHECK(false); |
2558 // TODO(ananta) | 2532 |
2559 // Remove this CHECK when the change to use DX11 for H/W decoding | |
2560 // stablizes. | |
2561 CHECK(false); | |
2562 } | |
2563 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set converter input type", | 2533 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set converter input type", |
2564 PLATFORM_FAILURE, false); | 2534 PLATFORM_FAILURE, false); |
2565 | 2535 |
2566 // It appears that we fail to set MFVideoFormat_ARGB32 as the output media | 2536 // It appears that we fail to set MFVideoFormat_ARGB32 as the output media |
2567 // type in certain configurations. Try to fallback to MFVideoFormat_RGB32 | 2537 // type in certain configurations. Try to fallback to MFVideoFormat_RGB32 |
2568 // in such cases. If both fail, then bail. | 2538 // in such cases. If both fail, then bail. |
2569 bool media_type_set = SetTransformOutputType( | 2539 bool media_type_set = SetTransformOutputType( |
2570 video_format_converter_mft_.get(), MFVideoFormat_ARGB32, width, height); | 2540 video_format_converter_mft_.get(), MFVideoFormat_ARGB32, width, height); |
2571 if (!media_type_set) { | 2541 if (!media_type_set) { |
2572 media_type_set = SetTransformOutputType(video_format_converter_mft_.get(), | 2542 media_type_set = SetTransformOutputType(video_format_converter_mft_.get(), |
2573 MFVideoFormat_RGB32, width, height); | 2543 MFVideoFormat_RGB32, width, height); |
2574 } | 2544 } |
2575 | 2545 |
2576 if (!media_type_set) { | 2546 if (!media_type_set) { |
2577 // Remove this once this stabilizes in the field. | |
2578 CHECK(false); | |
2579 LOG(ERROR) << "Failed to find a matching RGB output type in the converter"; | 2547 LOG(ERROR) << "Failed to find a matching RGB output type in the converter"; |
2580 return false; | 2548 return false; |
2581 } | 2549 } |
2582 | 2550 |
2583 dx11_video_format_converter_media_type_needs_init_ = false; | 2551 dx11_video_format_converter_media_type_needs_init_ = false; |
2584 return true; | 2552 return true; |
2585 } | 2553 } |
2586 | 2554 |
2587 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(IMFSample* sample, | 2555 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(IMFSample* sample, |
2588 int* width, | 2556 int* width, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2677 DismissStaleBuffers(true); | 2645 DismissStaleBuffers(true); |
2678 Invalidate(); | 2646 Invalidate(); |
2679 Initialize(config_, client_); | 2647 Initialize(config_, client_); |
2680 decoder_thread_task_runner_->PostTask( | 2648 decoder_thread_task_runner_->PostTask( |
2681 FROM_HERE, | 2649 FROM_HERE, |
2682 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, | 2650 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, |
2683 base::Unretained(this))); | 2651 base::Unretained(this))); |
2684 } | 2652 } |
2685 | 2653 |
2686 } // namespace media | 2654 } // namespace media |
OLD | NEW |