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

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

Issue 2696963002: Replace IMFTransform with ID3D11VideoProcessor (Closed)
Patch Set: 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 851 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(), 862 hr = d3d11_device_manager_->ResetDevice(d3d11_device_.get(),
863 dx11_dev_manager_reset_token_); 863 dx11_dev_manager_reset_token_);
864 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 864 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
865 865
866 D3D11_QUERY_DESC query_desc; 866 D3D11_QUERY_DESC query_desc;
867 query_desc.Query = D3D11_QUERY_EVENT; 867 query_desc.Query = D3D11_QUERY_EVENT;
868 query_desc.MiscFlags = 0; 868 query_desc.MiscFlags = 0;
869 hr = d3d11_device_->CreateQuery(&query_desc, d3d11_query_.Receive()); 869 hr = d3d11_device_->CreateQuery(&query_desc, d3d11_query_.Receive());
870 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); 870 RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false);
871 871
872 HMODULE video_processor_dll = ::GetModuleHandle(L"msvproc.dll"); 872 base::win::ScopedComPtr<ID3D11Device1> device1;
873 RETURN_ON_FAILURE(video_processor_dll, "Failed to load video processor", 873 hr = d3d11_device_.QueryInterface(__uuidof(ID3D11Device1),
jbauman 2017/02/14 23:43:34 device1 isn't actually used.
hubbe 2017/02/15 01:37:13 Well spotted, gone.
874 false); 874 device1.ReceiveVoid());
875 RETURN_ON_HR_FAILURE(hr, "Failed to get device1", false);
875 876
876 hr = CreateCOMObjectFromDll(video_processor_dll, CLSID_VideoProcessorMFT, 877 base::win::ScopedComPtr<ID3D11DeviceContext1> device_context1;
877 __uuidof(IMFTransform), 878 hr = d3d11_device_context_.QueryInterface(__uuidof(ID3D11DeviceContext1),
878 video_format_converter_mft_.ReceiveVoid()); 879 device1.ReceiveVoid());
jbauman 2017/02/14 23:43:34 device_context1 here. Though through the transitiv
hubbe 2017/02/15 01:37:13 Fixed. Though through the transitive property of
879 RETURN_ON_HR_FAILURE(hr, "Failed to create video format converter", false); 880 RETURN_ON_HR_FAILURE(hr, "Failed to get device context", false);
881 hr = d3d11_device_.QueryInterface(__uuidof(ID3D11VideoDevice),
jbauman 2017/02/14 23:43:34 ScopedComPtr has a template specialization for Que
hubbe 2017/02/15 01:37:13 nice, done.
882 video_device_.ReceiveVoid());
883 RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false);
880 884
881 base::win::ScopedComPtr<IMFAttributes> converter_attributes; 885 hr = device1.QueryInterface(__uuidof(ID3D11VideoContext1),
jbauman 2017/02/14 23:43:34 We need to be able to fall back to ID3D11VideoCont
hubbe 2017/02/15 01:37:13 What's the right way to do that?
882 hr = video_format_converter_mft_->GetAttributes( 886 video_context_.ReceiveVoid());
883 converter_attributes.Receive()); 887 RETURN_ON_HR_FAILURE(hr, "Failed to get video context", false);
884 RETURN_ON_HR_FAILURE(hr, "Failed to get converter attributes", false);
885 888
886 hr = converter_attributes->SetUINT32(MF_XVP_PLAYBACK_MODE, TRUE); 889 // TODO(hubbe): Use actual video format.
887 RETURN_ON_HR_FAILURE( 890 D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc;
888 hr, "Failed to set MF_XVP_PLAYBACK_MODE attribute on converter", false); 891 desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
jbauman 2017/02/14 23:43:34 I'm curious - do we ever support hardware decoding
hubbe 2017/02/15 01:37:13 We do, we just put our fingers in our ears and hum
892 desc.InputFrameRate.Numerator = 60;
893 desc.InputFrameRate.Denominator = 1;
894 desc.InputWidth = 1920;
jbauman 2017/02/14 23:43:34 I think we need to use the actual video size when
hubbe 2017/02/15 01:37:12 Done.
895 desc.InputHeight = 1080;
896 desc.OutputFrameRate.Numerator = 60;
897 desc.OutputFrameRate.Denominator = 1;
898 desc.OutputWidth = 1920;
899 desc.OutputHeight = 1080;
900 desc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL;
889 901
890 hr = converter_attributes->SetUINT32(MF_LOW_LATENCY, FALSE); 902 hr = video_device_->CreateVideoProcessorEnumerator(&desc,
891 RETURN_ON_HR_FAILURE( 903 enumerator_.Receive());
892 hr, "Failed to set MF_LOW_LATENCY attribute on converter", false); 904 RETURN_ON_HR_FAILURE(hr, "Failed to enumerate video processors", false);
905
906 // TODO(Hubbe): Find correct index
907 hr = video_device_->CreateVideoProcessor(enumerator_.get(), 0,
908 d3d11_processor_.Receive());
909 RETURN_ON_HR_FAILURE(hr, "Failed to create video processor.", false);
jbauman 2017/02/14 23:43:34 I've found that you need to set ID3D11VideoContext
hubbe 2017/02/15 01:37:13 Thanks for the tip!
910
893 return true; 911 return true;
894 } 912 }
895 913
896 void DXVAVideoDecodeAccelerator::Decode( 914 void DXVAVideoDecodeAccelerator::Decode(
897 const BitstreamBuffer& bitstream_buffer) { 915 const BitstreamBuffer& bitstream_buffer) {
898 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::Decode"); 916 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::Decode");
899 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 917 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
900 918
901 // SharedMemory will take over the ownership of handle. 919 // SharedMemory will take over the ownership of handle.
902 base::SharedMemory shm(bitstream_buffer.handle(), true); 920 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 1977 // resolution changes. We already handle that in the
1960 // HandleResolutionChanged() function. 1978 // HandleResolutionChanged() function.
1961 if (GetState() != kConfigChange) { 1979 if (GetState() != kConfigChange) {
1962 output_picture_buffers_.clear(); 1980 output_picture_buffers_.clear();
1963 stale_output_picture_buffers_.clear(); 1981 stale_output_picture_buffers_.clear();
1964 // We want to continue processing pending input after detecting a config 1982 // We want to continue processing pending input after detecting a config
1965 // change. 1983 // change.
1966 pending_input_buffers_.clear(); 1984 pending_input_buffers_.clear();
1967 pictures_requested_ = false; 1985 pictures_requested_ = false;
1968 if (use_dx11_) { 1986 if (use_dx11_) {
1969 if (video_format_converter_mft_.get()) { 1987 d3d11_processor_.Release();
1970 video_format_converter_mft_->ProcessMessage( 1988 enumerator_.Release();
1971 MFT_MESSAGE_NOTIFY_END_STREAMING, 0); 1989 video_context_.Release();
1972 video_format_converter_mft_.Release(); 1990 video_device_.Release();
1973 }
1974 d3d11_device_context_.Release(); 1991 d3d11_device_context_.Release();
1975 d3d11_device_.Release(); 1992 d3d11_device_.Release();
1976 d3d11_device_manager_.Release(); 1993 d3d11_device_manager_.Release();
1977 d3d11_query_.Release(); 1994 d3d11_query_.Release();
1978 multi_threaded_.Release(); 1995 multi_threaded_.Release();
1979 dx11_video_format_converter_media_type_needs_init_ = true; 1996 dx11_video_format_converter_media_type_needs_init_ = true;
1980 } else { 1997 } else {
1981 d3d9_.Release(); 1998 d3d9_.Release();
1982 d3d9_device_ex_.Release(); 1999 d3d9_device_ex_.Release();
1983 device_manager_.Release(); 2000 device_manager_.Release();
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
2556 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopyTexture"); 2573 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopyTexture");
2557 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2574 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2558 2575
2559 DCHECK(use_dx11_); 2576 DCHECK(use_dx11_);
2560 2577
2561 // The media foundation H.264 decoder outputs YUV12 textures which we 2578 // The media foundation H.264 decoder outputs YUV12 textures which we
2562 // cannot copy into ANGLE as they expect ARGB textures. In D3D land 2579 // cannot copy into ANGLE as they expect ARGB textures. In D3D land
2563 // the StretchRect API in the IDirect3DDevice9Ex interface did the color 2580 // the StretchRect API in the IDirect3DDevice9Ex interface did the color
2564 // space conversion for us. Sadly in DX11 land the API does not provide 2581 // space conversion for us. Sadly in DX11 land the API does not provide
2565 // a straightforward way to do this. 2582 // 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
2572 D3D11_TEXTURE2D_DESC source_desc;
2573 src_texture->GetDesc(&source_desc);
2574
2575 // Set up the input and output types for the video processor MFT.
2576 if (!InitializeDX11VideoFormatConverterMediaType(
2577 source_desc.Width, source_desc.Height, color_space)) {
2578 RETURN_AND_NOTIFY_ON_FAILURE(
2579 false, "Failed to initialize media types for convesion.",
2580 PLATFORM_FAILURE, );
2581 }
2582 2583
2583 // The input to the video processor is the output sample. 2584 // The input to the video processor is the output sample.
2584 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion; 2585 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion;
2585 { 2586 {
2586 base::AutoLock lock(decoder_lock_); 2587 base::AutoLock lock(decoder_lock_);
2587 PendingSampleInfo& sample_info = pending_output_samples_.front(); 2588 PendingSampleInfo& sample_info = pending_output_samples_.front();
2588 input_sample_for_conversion = sample_info.output_sample; 2589 input_sample_for_conversion = sample_info.output_sample;
2589 } 2590 }
2590 2591
2591 decoder_thread_task_runner_->PostTask( 2592 decoder_thread_task_runner_->PostTask(
2592 FROM_HERE, 2593 FROM_HERE,
2593 base::Bind(&DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread, 2594 base::Bind(&DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread,
2594 base::Unretained(this), dest_texture, dest_keyed_mutex, 2595 base::Unretained(this), dest_texture, dest_keyed_mutex,
2595 keyed_mutex_value, input_sample_for_conversion, 2596 keyed_mutex_value, input_sample_for_conversion,
2596 picture_buffer_id, input_buffer_id)); 2597 picture_buffer_id, input_buffer_id, color_space));
2597 } 2598 }
2598 2599
2599 void DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread( 2600 void DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread(
2600 ID3D11Texture2D* dest_texture, 2601 ID3D11Texture2D* dest_texture,
2601 base::win::ScopedComPtr<IDXGIKeyedMutex> dest_keyed_mutex, 2602 base::win::ScopedComPtr<IDXGIKeyedMutex> dest_keyed_mutex,
2602 uint64_t keyed_mutex_value, 2603 uint64_t keyed_mutex_value,
2603 base::win::ScopedComPtr<IMFSample> input_sample, 2604 base::win::ScopedComPtr<IMFSample> input_sample,
2604 int picture_buffer_id, 2605 int picture_buffer_id,
2605 int input_buffer_id) { 2606 int input_buffer_id,
2607 const gfx::ColorSpace& color_space) {
2606 TRACE_EVENT0("media", 2608 TRACE_EVENT0("media",
2607 "DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread"); 2609 "DXVAVideoDecodeAccelerator::CopyTextureOnDecoderThread");
2608 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); 2610 DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
2609 HRESULT hr = E_FAIL; 2611 HRESULT hr = E_FAIL;
2610 2612
2611 DCHECK(use_dx11_); 2613 DCHECK(use_dx11_);
2612 DCHECK(!!input_sample); 2614 DCHECK(!!input_sample);
2613 DCHECK(video_format_converter_mft_.get()); 2615 DCHECK(d3d11_processor_.get());
2614 2616
2615 if (dest_keyed_mutex) { 2617 if (dest_keyed_mutex) {
2616 HRESULT hr = 2618 HRESULT hr =
2617 dest_keyed_mutex->AcquireSync(keyed_mutex_value, kAcquireSyncWaitMs); 2619 dest_keyed_mutex->AcquireSync(keyed_mutex_value, kAcquireSyncWaitMs);
2618 RETURN_AND_NOTIFY_ON_FAILURE( 2620 RETURN_AND_NOTIFY_ON_FAILURE(
2619 hr == S_OK, "D3D11 failed to acquire keyed mutex for texture.", 2621 hr == S_OK, "D3D11 failed to acquire keyed mutex for texture.",
2620 PLATFORM_FAILURE, ); 2622 PLATFORM_FAILURE, );
2621 } 2623 }
2622 // The video processor MFT requires output samples to be allocated by the 2624
2623 // caller. We create a sample with a buffer backed with the ID3D11Texture2D 2625 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2624 // interface exposed by ANGLE. This works nicely as this ensures that the 2626 hr = input_sample->GetBufferByIndex(0, output_buffer.Receive());
2625 // video processor coverts the color space of the output frame and copies 2627 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", );
2626 // the result into the ANGLE texture. 2628
2627 base::win::ScopedComPtr<IMFSample> output_sample; 2629 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer;
2628 hr = MFCreateSample(output_sample.Receive()); 2630 hr = dxgi_buffer.QueryFrom(output_buffer.get());
2629 if (FAILED(hr)) { 2631 RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample", );
2630 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.", 2632 UINT index = 0;
2631 PLATFORM_FAILURE, ); 2633 hr = dxgi_buffer->GetSubresourceIndex(&index);
2634 RETURN_ON_HR_FAILURE(hr, "Failed to get resource index", );
2635
2636 base::win::ScopedComPtr<ID3D11Texture2D> dx11_decoding_texture;
2637 hr = dxgi_buffer->GetResource(IID_PPV_ARGS(dx11_decoding_texture.Receive()));
2638 RETURN_ON_HR_FAILURE(hr, "Failed to get resource from output sample", );
2639
2640 D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputViewDesc = {
2641 D3D11_VPOV_DIMENSION_TEXTURE2D};
2642 outputViewDesc.Texture2D.MipSlice = 0;
jbauman 2017/02/14 23:43:34 Variable naming style (here and elsewhere).
hubbe 2017/02/15 01:37:12 Done.
2643 base::win::ScopedComPtr<ID3D11VideoProcessorOutputView> videoProcOutputView;
2644 hr = video_device_->CreateVideoProcessorOutputView(
2645 dest_texture, enumerator_.get(), &outputViewDesc,
2646 videoProcOutputView.Receive());
2647 RETURN_ON_HR_FAILURE(hr, "Failed to get output view", );
jbauman 2017/02/14 23:43:34 RETURN_AND_NOTIFY_ON_HR_FAILURE here and elsewhere
hubbe 2017/02/15 01:37:13 Done.
2648
2649 D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = {0};
2650 inputViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
2651 inputViewDesc.FourCC = 0; // MAKEFOURCC('P', '0', '1', '0');
jbauman 2017/02/14 23:43:34 Remove
hubbe 2017/02/15 01:37:13 Done.
2652 inputViewDesc.Texture2D.ArraySlice = index; // ??
2653 inputViewDesc.Texture2D.MipSlice = 0;
2654 base::win::ScopedComPtr<ID3D11VideoProcessorInputView> videoProcInputView;
2655 hr = video_device_->CreateVideoProcessorInputView(
2656 dx11_decoding_texture.get(), enumerator_.get(), &inputViewDesc,
2657 videoProcInputView.Receive());
2658 RETURN_ON_HR_FAILURE(hr, "Failed to get input view", );
2659
2660 if (use_color_info_) {
2661 video_context_->VideoProcessorSetStreamColorSpace1(
2662 d3d11_processor_.get(), 0,
2663 gfx::ColorSpaceWin::GetDXGIColorSpace(color_space));
2664
2665 if (share_nv12_textures_) {
jbauman 2017/02/14 23:43:34 We should never hit this code with share_nv12_text
hubbe 2017/02/15 01:37:13 Done.
2666 video_context_->VideoProcessorSetOutputColorSpace1(
2667 d3d11_processor_.get(),
2668 gfx::ColorSpaceWin::GetDXGIColorSpace(color_space));
2669 } else {
2670 video_context_->VideoProcessorSetOutputColorSpace1(
2671 d3d11_processor_.get(), DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
2672 }
2632 } 2673 }
2633 2674
2634 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2675 D3D11_VIDEO_PROCESSOR_STREAM streams = {0};
2635 hr = MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), dest_texture, 0, 2676 streams.Enable = TRUE;
2636 FALSE, output_buffer.Receive()); 2677 streams.pInputSurface = videoProcInputView.get();
2637 if (FAILED(hr)) {
2638 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to create output sample.",
2639 PLATFORM_FAILURE, );
2640 }
2641 2678
2642 output_sample->AddBuffer(output_buffer.get()); 2679 hr = video_context_->VideoProcessorBlt(
2680 d3d11_processor_.get(), videoProcOutputView.get(), 0, 1, &streams);
2643 2681
2644 hr = video_format_converter_mft_->ProcessInput(0, input_sample.get(), 0); 2682 RETURN_ON_HR_FAILURE(hr, "VideoProcessBlit failed", );
2645 if (FAILED(hr)) {
2646 DCHECK(false);
2647 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2648 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, );
2649 }
2650
2651 input_sample.Release();
2652
2653 DWORD status = 0;
2654 MFT_OUTPUT_DATA_BUFFER format_converter_output = {};
2655 format_converter_output.pSample = output_sample.get();
2656 hr = video_format_converter_mft_->ProcessOutput(
2657 0, // No flags
2658 1, // # of out streams to pull from
2659 &format_converter_output, &status);
2660
2661 if (FAILED(hr)) {
2662 DCHECK(false);
2663 RETURN_AND_NOTIFY_ON_HR_FAILURE(
2664 hr, "Failed to convert output sample format.", PLATFORM_FAILURE, );
2665 }
2666 2683
2667 if (dest_keyed_mutex) { 2684 if (dest_keyed_mutex) {
2668 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1); 2685 HRESULT hr = dest_keyed_mutex->ReleaseSync(keyed_mutex_value + 1);
2669 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.", 2686 RETURN_AND_NOTIFY_ON_FAILURE(hr == S_OK, "Failed to release keyed mutex.",
2670 PLATFORM_FAILURE, ); 2687 PLATFORM_FAILURE, );
2671 2688
2672 main_thread_task_runner_->PostTask( 2689 main_thread_task_runner_->PostTask(
2673 FROM_HERE, 2690 FROM_HERE,
2674 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, weak_ptr_, 2691 base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, weak_ptr_,
2675 nullptr, nullptr, picture_buffer_id, input_buffer_id)); 2692 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)); 2745 base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
2729 return; 2746 return;
2730 } 2747 }
2731 2748
2732 main_thread_task_runner_->PostTask( 2749 main_thread_task_runner_->PostTask(
2733 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2750 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
2734 weak_ptr_, src_surface, dest_surface, 2751 weak_ptr_, src_surface, dest_surface,
2735 picture_buffer_id, input_buffer_id)); 2752 picture_buffer_id, input_buffer_id));
2736 } 2753 }
2737 2754
2738 bool DXVAVideoDecodeAccelerator::InitializeDX11VideoFormatConverterMediaType(
2739 int width,
2740 int height,
2741 const gfx::ColorSpace& color_space) {
2742 if (!dx11_video_format_converter_media_type_needs_init_ &&
jbauman 2017/02/14 23:43:34 dx11_video_format_converter_media_type_needs_init_
hubbe 2017/02/15 01:37:13 Done.
2743 (!use_color_info_ || color_space == dx11_converter_color_space_)) {
2744 return true;
2745 }
2746
2747 CHECK(video_format_converter_mft_.get());
2748
2749 HRESULT hr = video_format_converter_mft_->ProcessMessage(
2750 MFT_MESSAGE_SET_D3D_MANAGER,
2751 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get()));
2752
2753 if (FAILED(hr))
2754 DCHECK(false);
2755
2756 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr,
2757 "Failed to initialize video format converter",
2758 PLATFORM_FAILURE, false);
2759
2760 video_format_converter_mft_->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING,
2761 0);
2762
2763 base::win::ScopedComPtr<IMFMediaType> media_type;
2764 hr = MFCreateMediaType(media_type.Receive());
2765 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "MFCreateMediaType failed",
2766 PLATFORM_FAILURE, false);
2767
2768 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
2769 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set major input type",
2770 PLATFORM_FAILURE, false);
2771
2772 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
2773 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type",
2774 PLATFORM_FAILURE, false);
2775
2776 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height);
2777 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes",
2778 PLATFORM_FAILURE, false);
2779
2780 if (use_color_info_) {
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 }
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;
2827 }
2828
2829 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(IMFSample* sample, 2755 bool DXVAVideoDecodeAccelerator::GetVideoFrameDimensions(IMFSample* sample,
2830 int* width, 2756 int* width,
2831 int* height) { 2757 int* height) {
2832 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer; 2758 base::win::ScopedComPtr<IMFMediaBuffer> output_buffer;
2833 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive()); 2759 HRESULT hr = sample->GetBufferByIndex(0, output_buffer.Receive());
2834 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); 2760 RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false);
2835 2761
2836 if (use_dx11_) { 2762 if (use_dx11_) {
2837 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer; 2763 base::win::ScopedComPtr<IMFDXGIBuffer> dxgi_buffer;
2838 base::win::ScopedComPtr<ID3D11Texture2D> d3d11_texture; 2764 base::win::ScopedComPtr<ID3D11Texture2D> d3d11_texture;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2924 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2850 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2925 base::Unretained(this))); 2851 base::Unretained(this)));
2926 } 2852 }
2927 2853
2928 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const { 2854 uint32_t DXVAVideoDecodeAccelerator::GetTextureTarget() const {
2929 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_; 2855 bool provide_nv12_textures = share_nv12_textures_ || copy_nv12_textures_;
2930 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; 2856 return provide_nv12_textures ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
2931 } 2857 }
2932 2858
2933 } // namespace media 2859 } // 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