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

Side by Side Diff: media/gpu/dxva_video_decode_accelerator_win.cc

Issue 2696963002: Replace IMFTransform with ID3D11VideoProcessor (Closed)
Patch Set: all comments addressed Created 3 years, 10 months 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
« no previous file with comments | « media/gpu/dxva_video_decode_accelerator_win.h ('k') | ui/gfx/color_space_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 codec_(kUnknownVideoCodec), 493 codec_(kUnknownVideoCodec),
494 decoder_thread_("DXVAVideoDecoderThread"), 494 decoder_thread_("DXVAVideoDecoderThread"),
495 pending_flush_(false), 495 pending_flush_(false),
496 enable_low_latency_(gpu_preferences.enable_low_latency_dxva), 496 enable_low_latency_(gpu_preferences.enable_low_latency_dxva),
497 share_nv12_textures_(gpu_preferences.enable_zero_copy_dxgi_video && 497 share_nv12_textures_(gpu_preferences.enable_zero_copy_dxgi_video &&
498 !workarounds.disable_dxgi_zero_copy_video), 498 !workarounds.disable_dxgi_zero_copy_video),
499 copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video && 499 copy_nv12_textures_(gpu_preferences.enable_nv12_dxgi_video &&
500 !workarounds.disable_nv12_dxgi_video), 500 !workarounds.disable_nv12_dxgi_video),
501 use_dx11_(false), 501 use_dx11_(false),
502 use_keyed_mutex_(false), 502 use_keyed_mutex_(false),
503 dx11_video_format_converter_media_type_needs_init_(true),
504 using_angle_device_(false), 503 using_angle_device_(false),
505 enable_accelerated_vpx_decode_( 504 enable_accelerated_vpx_decode_(
506 gpu_preferences.enable_accelerated_vpx_decode), 505 gpu_preferences.enable_accelerated_vpx_decode),
507 processing_config_changed_(false), 506 processing_config_changed_(false),
508 weak_this_factory_(this) { 507 weak_this_factory_(this) {
509 weak_ptr_ = weak_this_factory_.GetWeakPtr(); 508 weak_ptr_ = weak_this_factory_.GetWeakPtr();
510 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); 509 memset(&input_stream_info_, 0, sizeof(input_stream_info_));
511 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); 510 memset(&output_stream_info_, 0, sizeof(output_stream_info_));
512 use_color_info_ = base::FeatureList::IsEnabled(kVideoBlitColorAccuracy); 511 use_color_info_ = base::FeatureList::IsEnabled(kVideoBlitColorAccuracy);
513 } 512 }
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), 861 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(),
863 dx11_dev_manager_reset_token_); 862 dx11_dev_manager_reset_token_);
864 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 863 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
865 864
866 D3D11_QUERY_DESC query_desc; 865 D3D11_QUERY_DESC query_desc;
867 query_desc.Query = D3D11_QUERY_EVENT; 866 query_desc.Query = D3D11_QUERY_EVENT;
868 query_desc.MiscFlags = 0; 867 query_desc.MiscFlags = 0;
869 hr = d3d11_device_->CreateQuery(&query_desc, d3d11_query_.Receive()); 868 hr = d3d11_device_->CreateQuery(&query_desc, d3d11_query_.Receive());
870 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); 869 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false);
871 870
872 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); 871 hr = d3d11_device_.QueryInterface(video_device_.Receive());
873 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", 872 RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false);
874 false);
875 873
876 hr = CreateCOMObjectFromDll(video_processor_dll, CLSID_VideoProcessorMFT, 874 hr = d3d11_device_context_.QueryInterface(video_context_.Receive());
877 __uuidof(IMFTransform), 875 RETURN_ON_HR_FAILURE(hr, "Failed to get video context", false);
878 video_format_converter_mft_.ReceiveVoid());
879 RETURN_ON_HR_FAILURE(hr, "Failed to create video format converter", false);
880 876
881 base::win::ScopedComPtr<IMFAttributes> converter_attributes;
882 hr = video_format_converter_mft_->GetAttributes(
883 converter_attributes.Receive());
884 RETURN_ON_HR_FAILURE(hr, "Failed to get converter attributes", false);
885
886 hr = converter_attributes->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE);
887 RETURN_ON_HR_FAILURE(
888 hr, "Failed to set MF_XVP_PLAYBACK_MODE attribute on converter", false);
889
890 hr = converter_attributes->SetUINT32(MF_LOW_LATENCY, FALSE);
891 RETURN_ON_HR_FAILURE(
892 hr, "Failed to set MF_LOW_LATENCY attribute on converter", false);
893 return true; 877 return true;
894 } 878 }
895 879
896 void DXVAVideoDecodeAccelerator::Decode( 880 void DXVAVideoDecodeAccelerator::Decode(
897 const BitstreamBuffer& bitstream_buffer) { 881 const BitstreamBuffer& bitstream_buffer) {
898 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::Decode"); 882 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::Decode");
899 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 883 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
900 884
901 // SharedMemory will take over the ownership of handle. 885 // SharedMemory will take over the ownership of handle.
902 base::SharedMemory shm(bitstream_buffer.handle(), true); 886 base::SharedMemory shm(bitstream_buffer.handle(), true);
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 // resolution changes. We already handle that in the 1943 // resolution changes. We already handle that in the
1960 // HandleResolutionChanged() function. 1944 // HandleResolutionChanged() function.
1961 if (GetState() != kConfigChange) { 1945 if (GetState() != kConfigChange) {
1962 output_picture_buffers_.clear(); 1946 output_picture_buffers_.clear();
1963 stale_output_picture_buffers_.clear(); 1947 stale_output_picture_buffers_.clear();
1964 // We want to continue processing pending input after detecting a config 1948 // We want to continue processing pending input after detecting a config
1965 // change. 1949 // change.
1966 pending_input_buffers_.clear(); 1950 pending_input_buffers_.clear();
1967 pictures_requested_ = false; 1951 pictures_requested_ = false;
1968 if (use_dx11_) { 1952 if (use_dx11_) {
1969 if (video_format_converter_mft_.get()) { 1953 d3d11_processor_.Release();
1970 video_format_converter_mft_->ProcessMessage( 1954 enumerator_.Release();
1971 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); 1955 video_context_.Release();
1972 video_format_converter_mft_.Release(); 1956 video_device_.Release();
1973 }
1974 d3d11_device_context_.Release(); 1957 d3d11_device_context_.Release();
1975 d3d11_device_.Release(); 1958 d3d11_device_.Release();
1976 d3d11_device_manager_.Release(); 1959 d3d11_device_manager_.Release();
1977 d3d11_query_.Release(); 1960 d3d11_query_.Release();
1978 multi_threaded_.Release(); 1961 multi_threaded_.Release();
1979 dx11_video_format_converter_media_type_needs_init_ = true; 1962 processor_width_ = processor_height_ = 0;
1980 } else { 1963 } else {
1981 d3d9_.Release(); 1964 d3d9_.Release();
1982 d3d9_device_ex_.Release(); 1965 d3d9_device_ex_.Release();
1983 device_manager_.Release(); 1966 device_manager_.Release();
1984 query_.Release(); 1967 query_.Release();
1985 } 1968 }
1986 } 1969 }
1987 sent_drain_message_ = false; 1970 sent_drain_message_ = false;
1988 SetState(kUninitialized); 1971 SetState(kUninitialized);
1989 } 1972 }
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 // decoder to emit an output packet for every input packet. 2253 // decoder to emit an output packet for every input packet.
2271 // http://code.google.com/p/chromium/issues/detail?id=108121 2254 // http://code.google.com/p/chromium/issues/detail?id=108121
2272 // http://code.google.com/p/chromium/issues/detail?id=150925 2255 // http://code.google.com/p/chromium/issues/detail?id=150925
2273 main_thread_task_runner_->PostTask( 2256 main_thread_task_runner_->PostTask(
2274 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::NotifyInputBufferRead, 2257 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::NotifyInputBufferRead,
2275 weak_ptr_, input_buffer_id)); 2258 weak_ptr_, input_buffer_id));
2276 } 2259 }
2277 2260
2278 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width, 2261 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width,
2279 int height) { 2262 int height) {
2280 dx11_video_format_converter_media_type_needs_init_ = true;
2281
2282 main_thread_task_runner_->PostTask( 2263 main_thread_task_runner_->PostTask(
2283 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers, 2264 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers,
2284 weak_ptr_, false)); 2265 weak_ptr_, false));
2285 2266
2286 main_thread_task_runner_->PostTask( 2267 main_thread_task_runner_->PostTask(
2287 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers, 2268 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
2288 weak_ptr_, width, height)); 2269 weak_ptr_, width, height));
2289 } 2270 }
2290 2271
2291 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) { 2272 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
2556 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopyTexture"); 2537 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopyTexture");
2557 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2538 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2558 2539
2559 DCHECK(use_dx11_); 2540 DCHECK(use_dx11_);
2560 2541
2561 // The media foundation H.264 decoder outputs YUV12 textures which we 2542 // The media foundation H.264 decoder outputs YUV12 textures which we
2562 // cannot copy into ANGLE as they expect ARGB textures. In D3D land 2543 // cannot copy into ANGLE as they expect ARGB textures. In D3D land
2563 // the StretchRect API in the IDirect3DDevice9Ex interface did the color 2544 // the StretchRect API in the IDirect3DDevice9Ex interface did the color
2564 // space conversion for us. Sadly in DX11 land the API does not provide 2545 // space conversion for us. Sadly in DX11 land the API does not provide
2565 // a straightforward way to do this. 2546 // a straightforward way to do this.
2566 // We use the video processor MFT.
2567 // https://msdn.microsoft.com/en-us/library/hh162913(v=vs.85).aspx
2568 // This object implements a media foundation transform (IMFTransform)
2569 // which follows the same contract as the decoder. The color space
2570 // conversion as per msdn is done in the GPU.
2571 2547
2572 D3D11_TEXTURE2D_DESC source_desc; 2548 D3D11_TEXTURE2D_DESC source_desc;
2573 src_texture->GetDesc(&source_desc); 2549 src_texture->GetDesc(&source_desc);
2574 2550 if (!InitializeID3D11VideoProcessor(source_desc.Width, source_desc.Height,
2575 // Set up the input and output types for the video processor MFT. 2551 » » » » color_space)) {
2576 if (!InitializeDX11VideoFormatConverterMediaType( 2552 RETURN_AND_NOTIFY_ON_FAILURE(false,
2577 source_desc.Width, source_desc.Height, color_space)) { 2553 "Failed to initialize D3D11 video processor.",
2578 RETURN_AND_NOTIFY_ON_FAILURE( 2554 PLATFORM_FAILURE, );
2579 false, "Failed to initialize media types for convesion.",
2580 PLATFORM_FAILURE, );
2581 } 2555 }
2582 2556
2583 // The input to the video processor is the output sample. 2557 // The input to the video processor is the output sample.
2584 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion; 2558 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion;
2585 { 2559 {
2586 base::AutoLock lock(decoder_lock_); 2560 base::AutoLock lock(decoder_lock_);
2587 PendingSampleInfo& sample_info = pending_output_samples_.front(); 2561 PendingSampleInfo& sample_info = pending_output_samples_.front();
2588 input_sample_for_conversion = sample_info.output_sample; 2562 input_sample_for_conversion = sample_info.output_sample;
2589 } 2563 }
2590 2564
(...skipping 12 matching lines...) Expand all
2603 base::win::ScopedComPtr<IMFSample> input_sample, 2577 base::win::ScopedComPtr<IMFSample> input_sample,
2604 int picture_buffer_id, 2578 int picture_buffer_id,
2605 int input_buffer_id) { 2579 int input_buffer_id) {
2606 TRACE_EVENT0("media", 2580 TRACE_EVENT0("media",
2607 "DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread"); 2581 "DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread");
2608 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2582 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2609 HRESULT hr = E_FAIL; 2583 HRESULT hr = E_FAIL;
2610 2584
2611 DCHECK(use_dx11_); 2585 DCHECK(use_dx11_);
2612 DCHECK(!!input_sample); 2586 DCHECK(!!input_sample);
2613 DCHECK(video_format_converter_mft_.get()); 2587 DCHECK(d3d11_processor_.get());
2614 2588
2615 if (dest_keyed_mutex) { 2589 if (dest_keyed_mutex) {
2616 HRESULT hr = 2590 HRESULT hr =
2617 dest_keyed_mutex->AcquireSync(keyed_mutex_value, kAcquireSyncWaitMs); 2591 dest_keyed_mutex->AcquireSync(keyed_mutex_value, kAcquireSyncWaitMs);
2618 RETURN_AND_NOTIFY_ON_FAILURE( 2592 RETURN_AND_NOTIFY_ON_FAILURE(
2619 hr == S_OK, "D3D11 failed to acquire keyed mutex for texture.", 2593 hr == S_OK, "D3D11 failed to acquire keyed mutex for texture.",
2620 PLATFORM_FAILURE, ); 2594 PLATFORM_FAILURE, );
2621 } 2595 }
2622 // The video processor MFT requires output samples to be allocated by the
2623 // caller. We create a sample with a buffer backed with the ID3D11Texture2D
2624 // interface exposed by ANGLE. This works nicely as this ensures that the
2625 // video processor coverts the color space of the output frame and copies
2626 // the result into the ANGLE texture.
2627 base::win::ScopedComPtr<IMFSample> output_sample;
2628 hr = MFCreateSample(output_sample.Receive());
2629 if (FAILED(hr)) {
2630 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.",
2631 PLATFORM_FAILURE, );
2632 }
2633 2596
2634 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2597 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2635 hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), dest_texture, 0, 2598 hr = input_sample->GetBufferByIndex(0, output_buffer.Receive());
2636 FALSE, output_buffer.Receive()); 2599 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to get buffer from output sample",
2637 if (FAILED(hr)) { 2600 PLATFORM_FAILURE, );
2638 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.",
2639 PLATFORM_FAILURE, );
2640 }
2641 2601
2642 output_sample->AddBuffer(output_buffer.get()); 2602 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer;
2603 hr = dxgi_buffer.QueryFrom(output_buffer.get());
2604 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2605 hr, "Failed to get DXGIBuffer from output sample", PLATFORM_FAILURE, );
2606 UINT index = 0;
2607 hr = dxgi_buffer->GetSubresourceIndex(&index);
2608 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to get resource index",
2609 PLATFORM_FAILURE, );
2643 2610
2644 hr = video_format_converter_mft_->ProcessInput(0, input_sample.get(), 0); 2611 base::win::ScopedComPtr<ID3D11Texture2D> dx11_decoding_texture;
2645 if (FAILED(hr)) { 2612 hr = dxgi_buffer->GetResource(IID_PPV_ARGS(dx11_decoding_texture.Receive()));
2646 DCHECK(false); 2613 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2647 RETURN_AND_NOTIFY_ON_HR_FAILURE( 2614 hr, "Failed to get resource from output sample", PLATFORM_FAILURE, );
2648 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, );
2649 }
2650 2615
2651 input_sample.Release(); 2616 D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_view_desc = {
2617 D3D11_VPOV_DIMENSION_TEXTURE2D};
2618 output_view_desc.Texture2D.MipSlice = 0;
2619 base::win::ScopedComPtr<ID3D11VideoProcessorOutputView> output_view;
2620 hr = video_device_->CreateVideoProcessorOutputView(
2621 dest_texture, enumerator_.get(), &output_view_desc,
2622 output_view.Receive());
2623 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to get output view",
2624 PLATFORM_FAILURE, );
2652 2625
2653 DWORD status = 0; 2626 D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_view_desc = {0};
2654 MFT_OUTPUT_DATA_BUFFER format_converter_output = {}; 2627 input_view_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
2655 format_converter_output.pSample = output_sample.get(); 2628 input_view_desc.Texture2D.ArraySlice = index;
2656 hr = video_format_converter_mft_->ProcessOutput( 2629 input_view_desc.Texture2D.MipSlice = 0;
2657 0, // No flags 2630 base::win::ScopedComPtr<ID3D11VideoProcessorInputView> input_view;
2658 1, // # of out streams to pull from 2631 hr = video_device_->CreateVideoProcessorInputView(
2659 &format_converter_output, &status); 2632 dx11_decoding_texture.get(), enumerator_.get(), &input_view_desc,
2633 input_view.Receive());
2634 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to get input view",
2635 PLATFORM_FAILURE, );
2660 2636
2661 if (FAILED(hr)) { 2637 D3D11_VIDEO_PROCESSOR_STREAM streams = {0};
2662 DCHECK(false); 2638 streams.Enable = TRUE;
2663 RETURN_AND_NOTIFY_ON_HR_FAILURE( 2639 streams.pInputSurface = input_view.get();
2664 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, ); 2640
2665 } 2641 hr = video_context_->VideoProcessorBlt(d3d11_processor_.get(),
2642 output_view.get(), 0, 1, &streams);
2643
2644 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "VideoProcessBlit failed",
2645 PLATFORM_FAILURE, );
2666 2646
2667 if (dest_keyed_mutex) { 2647 if (dest_keyed_mutex) {
2668 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1); 2648 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1);
2669 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.", 2649 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.",
2670 PLATFORM_FAILURE, ); 2650 PLATFORM_FAILURE, );
2671 2651
2672 main_thread_task_runner_->PostTask( 2652 main_thread_task_runner_->PostTask(
2673 FROM_HERE, 2653 FROM_HERE,
2674 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, weak_ptr_, 2654 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, weak_ptr_,
2675 nullptr, nullptr, picture_buffer_id, input_buffer_id)); 2655 nullptr, nullptr, picture_buffer_id, input_buffer_id));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs)); 2708 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
2729 return; 2709 return;
2730 } 2710 }
2731 2711
2732 main_thread_task_runner_->PostTask( 2712 main_thread_task_runner_->PostTask(
2733 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2713 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
2734 weak_ptr_, src_surface, dest_surface, 2714 weak_ptr_, src_surface, dest_surface,
2735 picture_buffer_id, input_buffer_id)); 2715 picture_buffer_id, input_buffer_id));
2736 } 2716 }
2737 2717
2738 bool DXVAVideoDecodeAccelerator::InitializeDX11VideoFormatConverterMediaType( 2718 bool DXVAVideoDecodeAccelerator::InitializeID3D11VideoProcessor(
2739 int width, 2719 int width,
2740 int height, 2720 int height,
2741 const gfx::ColorSpace& color_space) { 2721 const gfx::ColorSpace& color_space) {
2742 if (!dx11_video_format_converter_media_type_needs_init_ && 2722 if (width < processor_width_ || height != processor_height_) {
2743 (!use_color_info_ || color_space == dx11_converter_color_space_)) { 2723 d3d11_processor_.Release();
2744 return true; 2724 enumerator_.Release();
2725 processor_width_ = 0;
2726 processor_height_ = 0;
2727
2728 D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc;
2729 desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
2730 desc.InputFrameRate.Numerator = 60;
2731 desc.InputFrameRate.Denominator = 1;
2732 desc.InputWidth = width;
2733 desc.InputHeight = height;
2734 desc.OutputFrameRate.Numerator = 60;
2735 desc.OutputFrameRate.Denominator = 1;
2736 desc.OutputWidth = width;
2737 desc.OutputHeight = height;
2738 desc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL;
2739
2740 HRESULT hr = video_device_->CreateVideoProcessorEnumerator(
2741 &desc, enumerator_.Receive());
2742 RETURN_ON_HR_FAILURE(hr, "Failed to enumerate video processors", false);
2743
2744 // TODO(Hubbe): Find correct index
2745 hr = video_device_->CreateVideoProcessor(enumerator_.get(), 0,
2746 d3d11_processor_.Receive());
2747 RETURN_ON_HR_FAILURE(hr, "Failed to create video processor.", false);
2748 processor_width_ = width;
2749 processor_height_ = height;
2750
2751 video_context_->VideoProcessorSetStreamAutoProcessingMode(
2752 d3d11_processor_.get(), 0, false);
2745 } 2753 }
2746 2754
2747 CHECK(video_format_converter_mft_.get()); 2755 if (copy_nv12_textures_) {
2756 // If we're copying NV12 textures, make sure we set the same
2757 // color space on input and output.
2758 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = {0};
2759 d3d11_color_space.RGB_Range = 1;
2760 d3d11_color_space.Nominal_Range = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255;
2748 2761
2749 HRESULT hr = video_format_converter_mft_->ProcessMessage( 2762 video_context_->VideoProcessorSetOutputColorSpace(d3d11_processor_.get(),
2750 MFT_MESSAGE_SET_D3D_MANAGER, 2763 &d3d11_color_space);
2751 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get()));
2752 2764
2753 if (FAILED(hr)) 2765 video_context_->VideoProcessorSetStreamColorSpace(d3d11_processor_.get(), 0,
2754 DCHECK(false); 2766 &d3d11_color_space);
2755 2767 } else {
2756 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, 2768 // Not sure if this call is expensive, let's only do it if the color
2757 "Failed to initialize video format converter", 2769 // space changes.
2758 PLATFORM_FAILURE, false); 2770 gfx::ColorSpace output_color_space = gfx::ColorSpace::CreateSRGB();
2759 2771 if (use_color_info_ && dx11_converter_color_space_ != color_space) {
2760 video_format_converter_mft_->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, 2772 base::win::ScopedComPtr<ID3D11VideoContext1> video_context1;
2761 0); 2773 HRESULT hr = video_context_.QueryInterface(video_context1.Receive());
2762 2774 if (!FAILED(hr)) {
jbauman 2017/02/16 02:15:34 Nit: "if (SUCCEEDED(hr)) {"
2763 base::win::ScopedComPtr<IMFMediaType> media_type; 2775 video_context1->VideoProcessorSetStreamColorSpace1(
2764 hr = MFCreateMediaType(media_type.Receive()); 2776 d3d11_processor_.get(), 0,
2765 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "MFCreateMediaType failed", 2777 gfx::ColorSpaceWin::GetDXGIColorSpace(color_space));
2766 PLATFORM_FAILURE, false); 2778 video_context1->VideoProcessorSetOutputColorSpace1(
2767 2779 d3d11_processor_.get(),
2768 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); 2780 gfx::ColorSpaceWin::GetDXGIColorSpace(output_color_space));
2769 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set major input type", 2781 } else {
2770 PLATFORM_FAILURE, false); 2782 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space =
2771 2783 gfx::ColorSpaceWin::GetD3D11ColorSpace(color_space);
2772 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); 2784 video_context_->VideoProcessorSetStreamColorSpace(
2773 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type", 2785 d3d11_processor_.get(), 0, &d3d11_color_space);
2774 PLATFORM_FAILURE, false); 2786 d3d11_color_space =
2775 2787 gfx::ColorSpaceWin::GetD3D11ColorSpace(output_color_space);
2776 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height); 2788 video_context_->VideoProcessorSetOutputColorSpace(
2777 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes", 2789 d3d11_processor_.get(), &d3d11_color_space);
2778 PLATFORM_FAILURE, false); 2790 }
2779 2791 dx11_converter_color_space_ = color_space;
2780 if (use_color_info_) { 2792 }
2781 DXVA2_ExtendedFormat format =
2782 gfx::ColorSpaceWin::GetExtendedFormat(color_space);
2783 media_type->SetUINT32(MF_MT_YUV_MATRIX, format.VideoTransferMatrix);
2784 media_type->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, format.NominalRange);
2785 media_type->SetUINT32(MF_MT_VIDEO_PRIMARIES, format.VideoPrimaries);
2786 media_type->SetUINT32(MF_MT_TRANSFER_FUNCTION,
2787 format.VideoTransferFunction);
2788 dx11_converter_color_space_ = color_space;
2789 } 2793 }
2790
2791 hr = video_format_converter_mft_->SetInputType(0, media_type.get(), 0);
2792 if (FAILED(hr))
2793 DCHECK(false);
2794
2795 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set converter input type",
2796 PLATFORM_FAILURE, false);
2797
2798 // It appears that we fail to set MFVideoFormat_ARGB32 as the output media
2799 // type in certain configurations. Try to fallback to MFVideoFormat_RGB32
2800 // in such cases. If both fail, then bail.
2801
2802 bool media_type_set = false;
2803 if (copy_nv12_textures_) {
2804 media_type_set = SetTransformOutputType(video_format_converter_mft_.get(),
2805 MFVideoFormat_NV12, width, height);
2806 RETURN_AND_NOTIFY_ON_FAILURE(media_type_set,
2807 "Failed to set NV12 converter output type",
2808 PLATFORM_FAILURE, false);
2809 }
2810
2811 if (!media_type_set) {
2812 media_type_set = SetTransformOutputType(
2813 video_format_converter_mft_.get(), MFVideoFormat_ARGB32, width, height);
2814 }
2815 if (!media_type_set) {
2816 media_type_set = SetTransformOutputType(video_format_converter_mft_.get(),
2817 MFVideoFormat_RGB32, width, height);
2818 }
2819
2820 if (!media_type_set) {
2821 LOG(ERROR) << "Failed to find a matching RGB output type in the converter";
2822 return false;
2823 }
2824
2825 dx11_video_format_converter_media_type_needs_init_ = false;
2826 return true; 2794 return true;
2827 } 2795 }
2828 2796
2829 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(IMFSample* sample, 2797 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(IMFSample* sample,
2830 int* width, 2798 int* width,
2831 int* height) { 2799 int* height) {
2832 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2800 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2833 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive()); 2801 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive());
2834 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); 2802 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false);
2835 2803
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2924 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2892 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2925 base::Unretained(this))); 2893 base::Unretained(this)));
2926 } 2894 }
2927 2895
2928 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { 2896 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const {
2929 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; 2897 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_;
2930 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; 2898 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
2931 } 2899 }
2932 2900
2933 } // namespace media 2901 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/dxva_video_decode_accelerator_win.h ('k') | ui/gfx/color_space_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698