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

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

Issue 2503063002: media: Inform VideoBlit/MFTransform of video color information (Closed)
Patch Set: flag controlled, updated dx11 path Created 4 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 unified diff | Download patch
« no previous file with comments | « media/gpu/dxva_video_decode_accelerator_win.h ('k') | ui/gfx/BUILD.gn » ('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 17 matching lines...) Expand all
28 #include "base/files/file_path.h" 28 #include "base/files/file_path.h"
29 #include "base/location.h" 29 #include "base/location.h"
30 #include "base/logging.h" 30 #include "base/logging.h"
31 #include "base/macros.h" 31 #include "base/macros.h"
32 #include "base/memory/shared_memory.h" 32 #include "base/memory/shared_memory.h"
33 #include "base/path_service.h" 33 #include "base/path_service.h"
34 #include "base/single_thread_task_runner.h" 34 #include "base/single_thread_task_runner.h"
35 #include "base/stl_util.h" 35 #include "base/stl_util.h"
36 #include "base/threading/thread_task_runner_handle.h" 36 #include "base/threading/thread_task_runner_handle.h"
37 #include "base/trace_event/trace_event.h" 37 #include "base/trace_event/trace_event.h"
38 #include "base/win/scoped_co_mem.h"
38 #include "base/win/windows_version.h" 39 #include "base/win/windows_version.h"
39 #include "build/build_config.h" 40 #include "build/build_config.h"
40 #include "gpu/command_buffer/service/gpu_preferences.h" 41 #include "gpu/command_buffer/service/gpu_preferences.h"
41 #include "gpu/config/gpu_driver_bug_workarounds.h" 42 #include "gpu/config/gpu_driver_bug_workarounds.h"
43 #include "media/base/media_switches.h"
42 #include "media/base/win/mf_helpers.h" 44 #include "media/base/win/mf_helpers.h"
43 #include "media/base/win/mf_initializer.h" 45 #include "media/base/win/mf_initializer.h"
44 #include "media/gpu/dxva_picture_buffer_win.h" 46 #include "media/gpu/dxva_picture_buffer_win.h"
45 #include "media/video/video_decode_accelerator.h" 47 #include "media/video/video_decode_accelerator.h"
46 #include "third_party/angle/include/EGL/egl.h" 48 #include "third_party/angle/include/EGL/egl.h"
47 #include "third_party/angle/include/EGL/eglext.h" 49 #include "third_party/angle/include/EGL/eglext.h"
50 #include "ui/gfx/color_space_win.h"
48 #include "ui/gl/gl_bindings.h" 51 #include "ui/gl/gl_bindings.h"
49 #include "ui/gl/gl_context.h" 52 #include "ui/gl/gl_context.h"
50 #include "ui/gl/gl_fence.h" 53 #include "ui/gl/gl_fence.h"
51 #include "ui/gl/gl_surface_egl.h" 54 #include "ui/gl/gl_surface_egl.h"
52 55
53 namespace { 56 namespace {
54 57
55 // AMD 58 // AMD
56 // Path is appended on to the PROGRAM_FILES base path. 59 // Path is appended on to the PROGRAM_FILES base path.
57 const wchar_t kAMDVPXDecoderDLLPath[] = 60 const wchar_t kAMDVPXDecoderDLLPath[] =
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 use_keyed_mutex_(false), 513 use_keyed_mutex_(false),
511 dx11_video_format_converter_media_type_needs_init_(true), 514 dx11_video_format_converter_media_type_needs_init_(true),
512 using_angle_device_(false), 515 using_angle_device_(false),
513 enable_accelerated_vpx_decode_( 516 enable_accelerated_vpx_decode_(
514 gpu_preferences.enable_accelerated_vpx_decode), 517 gpu_preferences.enable_accelerated_vpx_decode),
515 processing_config_changed_(false), 518 processing_config_changed_(false),
516 weak_this_factory_(this) { 519 weak_this_factory_(this) {
517 weak_ptr_ = weak_this_factory_.GetWeakPtr(); 520 weak_ptr_ = weak_this_factory_.GetWeakPtr();
518 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); 521 memset(&input_stream_info_, 0, sizeof(input_stream_info_));
519 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); 522 memset(&output_stream_info_, 0, sizeof(output_stream_info_));
523 use_color_info_ = base::FeatureList::IsEnabled(kVideoBlitColorAccuracy);
520 } 524 }
521 525
522 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { 526 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() {
523 client_ = NULL; 527 client_ = NULL;
524 } 528 }
525 529
526 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config, 530 bool DXVAVideoDecodeAccelerator::Initialize(const Config& config,
527 Client* client) { 531 Client* client) {
528 if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) { 532 if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
529 NOTREACHED() << "GL callbacks are required for this VDA"; 533 NOTREACHED() << "GL callbacks are required for this VDA";
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 hr = device_manager_->ResetDevice(d3d9_device_ex_.get(), 697 hr = device_manager_->ResetDevice(d3d9_device_ex_.get(),
694 dev_manager_reset_token_); 698 dev_manager_reset_token_);
695 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); 699 RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false);
696 700
697 hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); 701 hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive());
698 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); 702 RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false);
699 // Ensure query_ API works (to avoid an infinite loop later in 703 // Ensure query_ API works (to avoid an infinite loop later in
700 // CopyOutputSampleDataToPictureBuffer). 704 // CopyOutputSampleDataToPictureBuffer).
701 hr = query_->Issue(D3DISSUE_END); 705 hr = query_->Issue(D3DISSUE_END);
702 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false); 706 RETURN_ON_HR_FAILURE(hr, "Failed to issue END test query", false);
707
708 CreateVideoProcessor();
703 return true; 709 return true;
704 } 710 }
705 711
712 bool DXVAVideoDecodeAccelerator::CreateVideoProcessor() {
713 if (!use_color_info_)
714 return false;
715
716 // TODO(Hubbe): Don't try again if we failed tried and failed already.
717 if (video_processor_service_.get())
718 return true;
719 HRESULT hr = DXVA2CreateVideoService(d3d9_device_ex_.get(),
720 IID_IDirectXVideoProcessorService,
721 video_processor_service_.ReceiveVoid());
722 RETURN_ON_HR_FAILURE(hr, "DXVA2CreateVideoService failed", false);
723
724 // TODO(Hubbe): Use actual video settings.
725 DXVA2_VideoDesc inputDesc;
726 inputDesc.SampleWidth = 1920;
727 inputDesc.SampleHeight = 1080;
728 inputDesc.SampleFormat.VideoChromaSubsampling =
729 DXVA2_VideoChromaSubsampling_MPEG2;
730 inputDesc.SampleFormat.NominalRange = DXVA2_NominalRange_16_235;
731 inputDesc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT709;
732 inputDesc.SampleFormat.VideoLighting = DXVA2_VideoLighting_dim;
733 inputDesc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT709;
734 inputDesc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_709;
735 inputDesc.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
736 inputDesc.Format = (D3DFORMAT)MAKEFOURCC('N', 'V', '1', '2');
737 inputDesc.InputSampleFreq.Numerator = 30;
738 inputDesc.InputSampleFreq.Denominator = 1;
739 inputDesc.OutputFrameFreq.Numerator = 30;
740 inputDesc.OutputFrameFreq.Denominator = 1;
741
742 UINT guid_count = 0;
743 base::win::ScopedCoMem<GUID> guids;
744 hr = video_processor_service_->GetVideoProcessorDeviceGuids(
745 &inputDesc, &guid_count, &guids);
746 RETURN_ON_HR_FAILURE(hr, "GetVideoProcessorDeviceGuids failed", false);
747
748 for (UINT g = 0; g < guid_count; g++) {
749 DXVA2_VideoProcessorCaps caps;
750 hr = video_processor_service_->GetVideoProcessorCaps(
751 guids[g], &inputDesc, D3DFMT_X8R8G8B8, &caps);
752 if (hr)
753 continue;
754
755 if (!(caps.VideoProcessorOperations & DXVA2_VideoProcess_YUV2RGB))
756 continue;
757
758 base::win::ScopedCoMem<D3DFORMAT> formats;
759 UINT format_count = 0;
760 hr = video_processor_service_->GetVideoProcessorRenderTargets(
761 guids[g], &inputDesc, &format_count, &formats);
762 if (hr)
763 continue;
764
765 UINT f;
766 for (f = 0; f < format_count; f++) {
767 if (formats[f] == D3DFMT_X8R8G8B8) {
768 break;
769 }
770 }
771 if (f == format_count)
772 continue;
773
774 // Create video processor
775 hr = video_processor_service_->CreateVideoProcessor(
776 guids[g], &inputDesc, D3DFMT_X8R8G8B8, 0, processor_.Receive());
777 if (hr)
778 continue;
779
780 DXVA2_ValueRange range;
781 processor_->GetProcAmpRange(DXVA2_ProcAmp_Brightness, &range);
782 default_procamp_values_.Brightness = range.DefaultValue;
783 processor_->GetProcAmpRange(DXVA2_ProcAmp_Contrast, &range);
784 default_procamp_values_.Contrast = range.DefaultValue;
785 processor_->GetProcAmpRange(DXVA2_ProcAmp_Hue, &range);
786 default_procamp_values_.Hue = range.DefaultValue;
787 processor_->GetProcAmpRange(DXVA2_ProcAmp_Saturation, &range);
788 default_procamp_values_.Saturation = range.DefaultValue;
789
790 return true;
791 }
792 return false;
793 }
794
706 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() { 795 bool DXVAVideoDecodeAccelerator::CreateDX11DevManager() {
707 // The device may exist if the last state was a config change. 796 // The device may exist if the last state was a config change.
708 if (d3d11_device_.get()) 797 if (d3d11_device_.get())
709 return true; 798 return true;
710 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, 799 HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_,
711 d3d11_device_manager_.Receive()); 800 d3d11_device_manager_.Receive());
712 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); 801 RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false);
713 802
714 angle_device_ = 803 angle_device_ =
715 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE); 804 QueryDeviceObjectFromANGLE<ID3D11Device>(EGL_D3D11_DEVICE_ANGLE);
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 } 1843 }
1755 1844
1756 if (width != index->second->size().width() || 1845 if (width != index->second->size().width() ||
1757 height != index->second->size().height()) { 1846 height != index->second->size().height()) {
1758 HandleResolutionChanged(width, height); 1847 HandleResolutionChanged(width, height);
1759 return; 1848 return;
1760 } 1849 }
1761 1850
1762 pending_sample->picture_buffer_id = index->second->id(); 1851 pending_sample->picture_buffer_id = index->second->id();
1763 index->second->set_bound(); 1852 index->second->set_bound();
1764 1853 index->second->set_color_space(pending_sample->color_space);
1765 // We only propagate the input color space if we can give the raw YUV data
1766 // back to the browser process. When we cannot return the YUV data, we
1767 // have to do a copy to an RGBA texture, which makes proper color
1768 // management difficult as some fidelity is lost. Also, we currently let
1769 // the drivers decide how to actually do the YUV to RGB conversion, which
1770 // means that even if we wanted to try to color-adjust the RGB output, we
1771 // don't actually know exactly what color space it is in anymore.
1772 // TODO(hubbe): Figure out a way to always return the raw YUV data.
1773 if (share_nv12_textures_ || copy_nv12_textures_) {
1774 index->second->set_color_space(pending_sample->color_space);
1775 }
1776 1854
1777 if (share_nv12_textures_) { 1855 if (share_nv12_textures_) {
1778 main_thread_task_runner_->PostTask( 1856 main_thread_task_runner_->PostTask(
1779 FROM_HERE, 1857 FROM_HERE,
1780 base::Bind(&DXVAVideoDecodeAccelerator::BindPictureBufferToSample, 1858 base::Bind(&DXVAVideoDecodeAccelerator::BindPictureBufferToSample,
1781 weak_ptr_, pending_sample->output_sample, 1859 weak_ptr_, pending_sample->output_sample,
1782 pending_sample->picture_buffer_id, 1860 pending_sample->picture_buffer_id,
1783 pending_sample->input_buffer_id)); 1861 pending_sample->input_buffer_id));
1784 continue; 1862 continue;
1785 } 1863 }
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2216 decoder_thread_.init_com_with_mta(false); 2294 decoder_thread_.init_com_with_mta(false);
2217 decoder_thread_.Start(); 2295 decoder_thread_.Start();
2218 decoder_thread_task_runner_ = decoder_thread_.task_runner(); 2296 decoder_thread_task_runner_ = decoder_thread_.task_runner();
2219 } 2297 }
2220 2298
2221 bool DXVAVideoDecodeAccelerator::OutputSamplesPresent() { 2299 bool DXVAVideoDecodeAccelerator::OutputSamplesPresent() {
2222 base::AutoLock lock(decoder_lock_); 2300 base::AutoLock lock(decoder_lock_);
2223 return !pending_output_samples_.empty(); 2301 return !pending_output_samples_.empty();
2224 } 2302 }
2225 2303
2226 void DXVAVideoDecodeAccelerator::CopySurface(IDirect3DSurface9* src_surface, 2304 void DXVAVideoDecodeAccelerator::CopySurface(
2227 IDirect3DSurface9* dest_surface, 2305 IDirect3DSurface9* src_surface,
2228 int picture_buffer_id, 2306 IDirect3DSurface9* dest_surface,
2229 int input_buffer_id) { 2307 int picture_buffer_id,
2308 int input_buffer_id,
2309 const gfx::ColorSpace& color_space) {
2230 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopySurface"); 2310 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopySurface");
2231 if (!decoder_thread_task_runner_->BelongsToCurrentThread()) { 2311 if (!decoder_thread_task_runner_->BelongsToCurrentThread()) {
2232 decoder_thread_task_runner_->PostTask( 2312 decoder_thread_task_runner_->PostTask(
2233 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurface, 2313 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurface,
2234 base::Unretained(this), src_surface, dest_surface, 2314 base::Unretained(this), src_surface, dest_surface,
2235 picture_buffer_id, input_buffer_id)); 2315 picture_buffer_id, input_buffer_id, color_space));
2236 return; 2316 return;
2237 } 2317 }
2238 2318
2239 HRESULT hr = d3d9_device_ex_->StretchRect(src_surface, NULL, dest_surface, 2319 HRESULT hr;
2240 NULL, D3DTEXF_NONE); 2320 if (processor_) {
2241 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", ); 2321 D3DSURFACE_DESC src_desc;
2322 src_surface->GetDesc(&src_desc);
2323 int width = src_desc.Width;
2324 int height = src_desc.Height;
2325 RECT rect = {0, 0, width, height};
2326 DXVA2_VideoSample sample = {0};
2327 sample.End = 1000;
2328 if (use_color_info_) {
2329 sample.SampleFormat = gfx::ColorSpaceWin::GetExtendedFormat(color_space);
2330 } else {
2331 sample.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
2332 }
2242 2333
2334 sample.SrcSurface = src_surface;
2335 sample.SrcRect = rect;
2336 sample.DstRect = rect;
2337 sample.PlanarAlpha = DXVA2_Fixed32OpaqueAlpha();
2338
2339 DXVA2_VideoProcessBltParams params = {0};
2340 params.TargetFrame = 0;
2341 params.TargetRect = rect;
2342 params.ConstrictionSize = {width, height};
2343 params.BackgroundColor = {0, 0, 0, 0xFFFF};
2344 params.ProcAmpValues = default_procamp_values_;
2345
2346 params.Alpha = DXVA2_Fixed32OpaqueAlpha();
2347
2348 hr = processor_->VideoProcessBlt(dest_surface, &params, &sample, 1, NULL);
2349 if (hr != S_OK) {
2350 LOG(ERROR) << "VideoProcessBlt failed with code " << hr
2351 << " E_INVALIDARG= " << E_INVALIDARG;
2352
2353 // Release the processor and fall back to StretchRect()
2354 processor_ = NULL;
2355 }
2356 }
2357
2358 if (!processor_) {
2359 hr = d3d9_device_ex_->StretchRect(src_surface, NULL, dest_surface, NULL,
2360 D3DTEXF_NONE);
2361 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", );
2362 }
2243 // Ideally, this should be done immediately before the draw call that uses 2363 // Ideally, this should be done immediately before the draw call that uses
2244 // the texture. Flush it once here though. 2364 // the texture. Flush it once here though.
2245 hr = query_->Issue(D3DISSUE_END); 2365 hr = query_->Issue(D3DISSUE_END);
2246 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", ); 2366 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", );
2247 2367
2248 // If we are sharing the ANGLE device we don't need to wait for the Flush to 2368 // If we are sharing the ANGLE device we don't need to wait for the Flush to
2249 // complete. 2369 // complete.
2250 if (using_angle_device_) { 2370 if (using_angle_device_) {
2251 main_thread_task_runner_->PostTask( 2371 main_thread_task_runner_->PostTask(
2252 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2372 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2289 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(), 2409 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_cb_.Run(),
2290 "Failed to make context current", 2410 "Failed to make context current",
2291 PLATFORM_FAILURE, ); 2411 PLATFORM_FAILURE, );
2292 2412
2293 DCHECK(!output_picture_buffers_.empty()); 2413 DCHECK(!output_picture_buffers_.empty());
2294 2414
2295 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface); 2415 bool result = picture_buffer->CopySurfaceComplete(src_surface, dest_surface);
2296 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface", 2416 RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface",
2297 PLATFORM_FAILURE, ); 2417 PLATFORM_FAILURE, );
2298 2418
2299 NotifyPictureReady(picture_buffer->id(), input_buffer_id, 2419 NotifyPictureReady(
2300 picture_buffer->color_space()); 2420 picture_buffer->id(), input_buffer_id,
2421 copy_nv12_textures_ ? picture_buffer->color_space() : gfx::ColorSpace());
2301 2422
2302 { 2423 {
2303 base::AutoLock lock(decoder_lock_); 2424 base::AutoLock lock(decoder_lock_);
2304 if (!pending_output_samples_.empty()) 2425 if (!pending_output_samples_.empty())
2305 pending_output_samples_.pop_front(); 2426 pending_output_samples_.pop_front();
2306 } 2427 }
2307 2428
2308 if (pending_flush_ || processing_config_changed_) { 2429 if (pending_flush_ || processing_config_changed_) {
2309 decoder_thread_task_runner_->PostTask( 2430 decoder_thread_task_runner_->PostTask(
2310 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal, 2431 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::FlushInternal,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2490 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2370 base::Unretained(this))); 2491 base::Unretained(this)));
2371 } 2492 }
2372 2493
2373 void DXVAVideoDecodeAccelerator::CopyTexture( 2494 void DXVAVideoDecodeAccelerator::CopyTexture(
2374 ID3D11Texture2D* src_texture, 2495 ID3D11Texture2D* src_texture,
2375 ID3D11Texture2D* dest_texture, 2496 ID3D11Texture2D* dest_texture,
2376 base::win::ScopedComPtr<IDXGIKeyedMutex> dest_keyed_mutex, 2497 base::win::ScopedComPtr<IDXGIKeyedMutex> dest_keyed_mutex,
2377 uint64_t keyed_mutex_value, 2498 uint64_t keyed_mutex_value,
2378 int picture_buffer_id, 2499 int picture_buffer_id,
2379 int input_buffer_id) { 2500 int input_buffer_id,
2501 const gfx::ColorSpace& color_space) {
2380 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopyTexture"); 2502 TRACE_EVENT0("media", "DXVAVideoDecodeAccelerator::CopyTexture");
2381 DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); 2503 DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
2382 2504
2383 DCHECK(use_dx11_); 2505 DCHECK(use_dx11_);
2384 2506
2385 // The media foundation H.264 decoder outputs YUV12 textures which we 2507 // The media foundation H.264 decoder outputs YUV12 textures which we
2386 // cannot copy into ANGLE as they expect ARGB textures. In D3D land 2508 // cannot copy into ANGLE as they expect ARGB textures. In D3D land
2387 // the StretchRect API in the IDirect3DDevice9Ex interface did the color 2509 // the StretchRect API in the IDirect3DDevice9Ex interface did the color
2388 // space conversion for us. Sadly in DX11 land the API does not provide 2510 // space conversion for us. Sadly in DX11 land the API does not provide
2389 // a straightforward way to do this. 2511 // a straightforward way to do this.
2390 // We use the video processor MFT. 2512 // We use the video processor MFT.
2391 // https://msdn.microsoft.com/en-us/library/hh162913(v=vs.85).aspx 2513 // https://msdn.microsoft.com/en-us/library/hh162913(v=vs.85).aspx
2392 // This object implements a media foundation transform (IMFTransform) 2514 // This object implements a media foundation transform (IMFTransform)
2393 // which follows the same contract as the decoder. The color space 2515 // which follows the same contract as the decoder. The color space
2394 // conversion as per msdn is done in the GPU. 2516 // conversion as per msdn is done in the GPU.
2395 2517
2396 D3D11_TEXTURE2D_DESC source_desc; 2518 D3D11_TEXTURE2D_DESC source_desc;
2397 src_texture->GetDesc(&source_desc); 2519 src_texture->GetDesc(&source_desc);
2398 2520
2399 // Set up the input and output types for the video processor MFT. 2521 // Set up the input and output types for the video processor MFT.
2400 if (!InitializeDX11VideoFormatConverterMediaType(source_desc.Width, 2522 if (!InitializeDX11VideoFormatConverterMediaType(
2401 source_desc.Height)) { 2523 source_desc.Width, source_desc.Height, color_space)) {
2402 RETURN_AND_NOTIFY_ON_FAILURE( 2524 RETURN_AND_NOTIFY_ON_FAILURE(
2403 false, "Failed to initialize media types for convesion.", 2525 false, "Failed to initialize media types for convesion.",
2404 PLATFORM_FAILURE, ); 2526 PLATFORM_FAILURE, );
2405 } 2527 }
2406 2528
2407 // The input to the video processor is the output sample. 2529 // The input to the video processor is the output sample.
2408 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion; 2530 base::win::ScopedComPtr<IMFSample> input_sample_for_conversion;
2409 { 2531 {
2410 base::AutoLock lock(decoder_lock_); 2532 base::AutoLock lock(decoder_lock_);
2411 PendingSampleInfo& sample_info = pending_output_samples_.front(); 2533 PendingSampleInfo& sample_info = pending_output_samples_.front();
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2556 } 2678 }
2557 2679
2558 main_thread_task_runner_->PostTask( 2680 main_thread_task_runner_->PostTask(
2559 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete, 2681 FROM_HERE, base::Bind(&DXVAVideoDecodeAccelerator::CopySurfaceComplete,
2560 weak_ptr_, src_surface, dest_surface, 2682 weak_ptr_, src_surface, dest_surface,
2561 picture_buffer_id, input_buffer_id)); 2683 picture_buffer_id, input_buffer_id));
2562 } 2684 }
2563 2685
2564 bool DXVAVideoDecodeAccelerator::InitializeDX11VideoFormatConverterMediaType( 2686 bool DXVAVideoDecodeAccelerator::InitializeDX11VideoFormatConverterMediaType(
2565 int width, 2687 int width,
2566 int height) { 2688 int height,
2689 const gfx::ColorSpace& color_space) {
2567 if (!dx11_video_format_converter_media_type_needs_init_) 2690 if (!dx11_video_format_converter_media_type_needs_init_)
2568 return true; 2691 return true;
jbauman 2016/11/22 22:16:59 We may need to reinitialize this if the color spac
hubbe 2016/11/23 21:21:26 Done.
2569 2692
2570 CHECK(video_format_converter_mft_.get()); 2693 CHECK(video_format_converter_mft_.get());
2571 2694
2572 HRESULT hr = video_format_converter_mft_->ProcessMessage( 2695 HRESULT hr = video_format_converter_mft_->ProcessMessage(
2573 MFT_MESSAGE_SET_D3D_MANAGER, 2696 MFT_MESSAGE_SET_D3D_MANAGER,
2574 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get())); 2697 reinterpret_cast<ULONG_PTR>(d3d11_device_manager_.get()));
2575 2698
2576 if (FAILED(hr)) 2699 if (FAILED(hr))
2577 DCHECK(false); 2700 DCHECK(false);
2578 2701
(...skipping 14 matching lines...) Expand all
2593 PLATFORM_FAILURE, false); 2716 PLATFORM_FAILURE, false);
2594 2717
2595 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); 2718 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
2596 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type", 2719 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set input sub type",
2597 PLATFORM_FAILURE, false); 2720 PLATFORM_FAILURE, false);
2598 2721
2599 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height); 2722 hr = MFSetAttributeSize(media_type.get(), MF_MT_FRAME_SIZE, width, height);
2600 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes", 2723 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set media type attributes",
2601 PLATFORM_FAILURE, false); 2724 PLATFORM_FAILURE, false);
2602 2725
2726 if (use_color_info_) {
2727 DXVA2_ExtendedFormat format =
2728 gfx::ColorSpaceWin::GetExtendedFormat(color_space);
2729 media_type->SetUINT32(MF_MT_YUV_MATRIX, format.VideoTransferMatrix);
2730 media_type->SetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, format.NominalRange);
2731 media_type->SetUINT32(MF_MT_VIDEO_PRIMARIES, format.VideoPrimaries);
2732 media_type->SetUINT32(MF_MT_TRANSFER_FUNCTION,
2733 format.VideoTransferFunction);
2734 }
2735
2603 hr = video_format_converter_mft_->SetInputType(0, media_type.get(), 0); 2736 hr = video_format_converter_mft_->SetInputType(0, media_type.get(), 0);
2604 if (FAILED(hr)) 2737 if (FAILED(hr))
2605 DCHECK(false); 2738 DCHECK(false);
2606 2739
2607 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set converter input type", 2740 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to set converter input type",
2608 PLATFORM_FAILURE, false); 2741 PLATFORM_FAILURE, false);
2609 2742
2610 // It appears that we fail to set MFVideoFormat_ARGB32 as the output media 2743 // It appears that we fail to set MFVideoFormat_ARGB32 as the output media
2611 // type in certain configurations. Try to fallback to MFVideoFormat_RGB32 2744 // type in certain configurations. Try to fallback to MFVideoFormat_RGB32
2612 // in such cases. If both fail, then bail. 2745 // in such cases. If both fail, then bail.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2730 SetState(kConfigChange); 2863 SetState(kConfigChange);
2731 Invalidate(); 2864 Invalidate();
2732 Initialize(config_, client_); 2865 Initialize(config_, client_);
2733 decoder_thread_task_runner_->PostTask( 2866 decoder_thread_task_runner_->PostTask(
2734 FROM_HERE, 2867 FROM_HERE,
2735 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 2868 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
2736 base::Unretained(this))); 2869 base::Unretained(this)));
2737 } 2870 }
2738 2871
2739 } // namespace media 2872 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/dxva_video_decode_accelerator_win.h ('k') | ui/gfx/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698