Chromium Code Reviews| 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 "content/common/gpu/media/dxva_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #if !defined(OS_WIN) | 7 #if !defined(OS_WIN) |
| 8 #error This file should only be built on Windows. | 8 #error This file should only be built on Windows. |
| 9 #endif // !defined(OS_WIN) | 9 #endif // !defined(OS_WIN) |
| 10 | 10 |
| 11 #include <ks.h> | 11 #include <ks.h> |
| 12 #include <codecapi.h> | 12 #include <codecapi.h> |
| 13 #include <mfapi.h> | 13 #include <mfapi.h> |
| 14 #include <mferror.h> | 14 #include <mferror.h> |
| 15 #include <wmcodecdsp.h> | 15 #include <wmcodecdsp.h> |
| 16 | 16 |
| 17 #include "base/base_paths_win.h" | |
| 17 #include "base/bind.h" | 18 #include "base/bind.h" |
| 18 #include "base/callback.h" | 19 #include "base/callback.h" |
| 19 #include "base/command_line.h" | 20 #include "base/command_line.h" |
| 20 #include "base/debug/trace_event.h" | 21 #include "base/debug/trace_event.h" |
| 21 #include "base/file_version_info.h" | 22 #include "base/file_version_info.h" |
| 23 #include "base/files/file_path.h" | |
| 22 #include "base/logging.h" | 24 #include "base/logging.h" |
| 23 #include "base/memory/scoped_ptr.h" | 25 #include "base/memory/scoped_ptr.h" |
| 24 #include "base/memory/shared_memory.h" | 26 #include "base/memory/shared_memory.h" |
| 25 #include "base/message_loop/message_loop.h" | 27 #include "base/message_loop/message_loop.h" |
| 28 #include "base/path_service.h" | |
| 26 #include "base/win/windows_version.h" | 29 #include "base/win/windows_version.h" |
| 27 #include "media/video/video_decode_accelerator.h" | 30 #include "media/video/video_decode_accelerator.h" |
| 28 #include "ui/gl/gl_bindings.h" | 31 #include "ui/gl/gl_bindings.h" |
| 29 #include "ui/gl/gl_surface_egl.h" | 32 #include "ui/gl/gl_surface_egl.h" |
| 30 #include "ui/gl/gl_switches.h" | 33 #include "ui/gl/gl_switches.h" |
| 31 | 34 |
| 32 namespace content { | 35 namespace content { |
| 33 | 36 |
| 34 // We only request 5 picture buffers from the client which are used to hold the | 37 // We only request 5 picture buffers from the client which are used to hold the |
| 35 // decoded samples. These buffers are then reused when the client tells us that | 38 // decoded samples. These buffers are then reused when the client tells us that |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 | 427 |
| 425 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( | 428 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( |
| 426 const base::Callback<bool(void)>& make_context_current) | 429 const base::Callback<bool(void)>& make_context_current) |
| 427 : client_(NULL), | 430 : client_(NULL), |
| 428 dev_manager_reset_token_(0), | 431 dev_manager_reset_token_(0), |
| 429 egl_config_(NULL), | 432 egl_config_(NULL), |
| 430 state_(kUninitialized), | 433 state_(kUninitialized), |
| 431 pictures_requested_(false), | 434 pictures_requested_(false), |
| 432 inputs_before_decode_(0), | 435 inputs_before_decode_(0), |
| 433 make_context_current_(make_context_current), | 436 make_context_current_(make_context_current), |
| 434 weak_this_factory_(this) { | 437 weak_this_factory_(this), |
| 438 codec_(media::kUnknownVideoCodec) { | |
| 435 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); | 439 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); |
| 436 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); | 440 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); |
| 437 } | 441 } |
| 438 | 442 |
| 439 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { | 443 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { |
| 440 client_ = NULL; | 444 client_ = NULL; |
| 441 } | 445 } |
| 442 | 446 |
| 443 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, | 447 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
| 444 Client* client) { | 448 Client* client) { |
| 445 DCHECK(CalledOnValidThread()); | 449 DCHECK(CalledOnValidThread()); |
| 446 | 450 |
| 447 client_ = client; | 451 client_ = client; |
| 448 | 452 |
| 449 // Not all versions of Windows 7 and later include Media Foundation DLLs. | 453 // Not all versions of Windows 7 and later include Media Foundation DLLs. |
| 450 // Instead of crashing while delay loading the DLL when calling MFStartup() | 454 // Instead of crashing while delay loading the DLL when calling MFStartup() |
| 451 // below, probe whether we can successfully load the DLL now. | 455 // below, probe whether we can successfully load the DLL now. |
| 452 // | 456 // |
| 453 // See http://crbug.com/339678 for details. | 457 // See http://crbug.com/339678 for details. |
| 454 HMODULE mfplat_dll = ::LoadLibrary(L"MFPlat.dll"); | 458 HMODULE mfplat_dll = ::LoadLibrary(L"MFPlat.dll"); |
| 455 RETURN_ON_FAILURE(mfplat_dll, "MFPlat.dll is required for decoding", false); | 459 RETURN_ON_FAILURE(mfplat_dll, "MFPlat.dll is required for decoding", false); |
| 456 | 460 |
| 457 // TODO(ananta) | 461 // TODO(ananta) |
| 458 // H264PROFILE_HIGH video decoding is janky at times. Needs more | 462 // H264PROFILE_HIGH video decoding is janky at times. Needs more |
| 459 // investigation. http://crbug.com/426707 | 463 // investigation. http://crbug.com/426707 |
| 460 if (profile != media::H264PROFILE_BASELINE && | 464 if (profile != media::H264PROFILE_BASELINE && |
| 461 profile != media::H264PROFILE_MAIN) { | 465 profile != media::H264PROFILE_MAIN && |
| 466 profile != media::VP8PROFILE_ANY && | |
| 467 profile != media::VP9PROFILE_ANY) { | |
| 462 RETURN_AND_NOTIFY_ON_FAILURE(false, | 468 RETURN_AND_NOTIFY_ON_FAILURE(false, |
| 463 "Unsupported h264 profile", PLATFORM_FAILURE, false); | 469 "Unsupported h.264, vp8, or vp9 profile", PLATFORM_FAILURE, false); |
| 464 } | 470 } |
| 465 | 471 |
| 466 RETURN_AND_NOTIFY_ON_FAILURE( | 472 RETURN_AND_NOTIFY_ON_FAILURE( |
| 467 gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle, | 473 gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle, |
| 468 "EGL_ANGLE_surface_d3d_texture_2d_share_handle unavailable", | 474 "EGL_ANGLE_surface_d3d_texture_2d_share_handle unavailable", |
| 469 PLATFORM_FAILURE, | 475 PLATFORM_FAILURE, |
| 470 false); | 476 false); |
| 471 | 477 |
| 472 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kUninitialized), | 478 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kUninitialized), |
| 473 "Initialize: invalid state: " << state_, ILLEGAL_STATE, false); | 479 "Initialize: invalid state: " << state_, ILLEGAL_STATE, false); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 void DXVAVideoDecodeAccelerator::Destroy() { | 637 void DXVAVideoDecodeAccelerator::Destroy() { |
| 632 DCHECK(CalledOnValidThread()); | 638 DCHECK(CalledOnValidThread()); |
| 633 Invalidate(); | 639 Invalidate(); |
| 634 delete this; | 640 delete this; |
| 635 } | 641 } |
| 636 | 642 |
| 637 bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { | 643 bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { |
| 638 return false; | 644 return false; |
| 639 } | 645 } |
| 640 | 646 |
| 647 // Path is appended on to the PROGRAM_FILES base path. | |
| 648 const wchar_t kVPXDecoderDLLPath[] = L"Intel\\Media SDK\\"; | |
|
DaleCurtis
2014/11/25 00:32:55
Typically all these would go in an anonymous names
luken
2014/11/25 01:07:02
Done.
| |
| 649 | |
| 650 const wchar_t kVP8DecoderDLLName[] = | |
| 651 #if defined(ARCH_CPU_X86) | |
| 652 L"mfx_mft_vp8vd_32.dll"; | |
| 653 #elif defined(ARCH_CPU_X86_64) | |
| 654 L"mfx_mft_vp8vd_64.dll"; | |
| 655 #else | |
| 656 #error Unsupported Windows CPU Architecture | |
| 657 #endif | |
| 658 | |
| 659 const wchar_t kVP9DecoderDLLName[] = | |
| 660 #if defined(ARCH_CPU_X86) | |
| 661 L"mfx_mft_vp9vd_32.dll"; | |
| 662 #elif defined(ARCH_CPU_X86_64) | |
| 663 L"mfx_mft_vp9vd_64.dll"; | |
| 664 #else | |
| 665 #error Unsupported Windows CPU Architecture | |
| 666 #endif | |
| 667 | |
| 668 const CLSID CLSID_WebmMfVp8Dec = { | |
| 669 0x451e3cb7, | |
| 670 0x2622, | |
| 671 0x4ba5, | |
| 672 { 0x8e, 0x1d, 0x44, 0xb3, 0xc4, 0x1d, 0x09, 0x24 } | |
| 673 }; | |
| 674 | |
| 675 const CLSID CLSID_WebmMfVp9Dec = { | |
| 676 0x07ab4bd2, | |
| 677 0x1979, | |
| 678 0x4fcd, | |
| 679 { 0xa6, 0x97, 0xdf, 0x9a, 0xd1, 0x5b, 0x34, 0xfe } | |
| 680 }; | |
| 681 | |
| 641 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { | 682 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { |
| 642 if (profile < media::H264PROFILE_MIN || profile > media::H264PROFILE_MAX) | 683 HMODULE decoder_dll = NULL; |
| 643 return false; | |
| 644 | 684 |
| 645 // We mimic the steps CoCreateInstance uses to instantiate the object. This | 685 // Profile must fall within the valid range for one of the supported codecs. |
| 646 // was previously done because it failed inside the sandbox, and now is done | 686 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { |
| 647 // as a more minimal approach to avoid other side-effects CCI might have (as | 687 // We mimic the steps CoCreateInstance uses to instantiate the object. This |
| 648 // we are still in a reduced sandbox). | 688 // was previously done because it failed inside the sandbox, and now is done |
| 649 HMODULE decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll"); | 689 // as a more minimal approach to avoid other side-effects CCI might have (as |
| 650 RETURN_ON_FAILURE(decoder_dll, | 690 // we are still in a reduced sandbox). |
| 651 "msmpeg2vdec.dll required for decoding is not loaded", | 691 decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll"); |
| 652 false); | 692 RETURN_ON_FAILURE(decoder_dll, |
| 693 "msmpeg2vdec.dll required for decoding is not loaded", | |
| 694 false); | |
| 653 | 695 |
| 654 // Check version of DLL, version 6.7.7140 is blacklisted due to high crash | 696 // Check version of DLL, version 6.7.7140 is blacklisted due to high crash |
| 655 // rates in browsers loading that DLL. If that is the version installed we | 697 // rates in browsers loading that DLL. If that is the version installed we |
| 656 // fall back to software decoding. See crbug/403440. | 698 // fall back to software decoding. See crbug/403440. |
| 657 FileVersionInfo* version_info = | 699 FileVersionInfo* version_info = |
| 658 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll); | 700 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll); |
| 659 RETURN_ON_FAILURE(version_info, | 701 RETURN_ON_FAILURE(version_info, |
| 660 "unable to get version of msmpeg2vdec.dll", | 702 "unable to get version of msmpeg2vdec.dll", |
| 661 false); | 703 false); |
| 662 base::string16 file_version = version_info->file_version(); | 704 base::string16 file_version = version_info->file_version(); |
| 663 RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos, | 705 RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos, |
| 664 "blacklisted version of msmpeg2vdec.dll 6.7.7140", | 706 "blacklisted version of msmpeg2vdec.dll 6.7.7140", |
| 665 false); | 707 false); |
| 708 codec_ = media::kCodecH264; | |
| 709 } else if (profile == media::VP8PROFILE_ANY || | |
| 710 profile == media::VP9PROFILE_ANY) { | |
|
DaleCurtis
2014/11/25 00:32:55
alignment is wrong.
luken
2014/11/25 01:07:02
Done.
| |
| 711 base::FilePath dll_path; | |
| 712 RETURN_ON_FAILURE(PathService::Get(base::DIR_PROGRAM_FILES, &dll_path), | |
|
DaleCurtis
2014/11/25 00:32:55
Does this vary correctly between for "(x86)" and t
luken
2014/11/25 01:07:02
We're still a bit tentative on the path but AFAIK
| |
| 713 "failed to get path for DIR_PROGRAM_FILES", false); | |
| 714 dll_path = dll_path.Append(kVPXDecoderDLLPath); | |
| 715 if (profile == media::VP8PROFILE_ANY) { | |
| 716 codec_ = media::kCodecVP8; | |
| 717 dll_path = dll_path.Append(kVP8DecoderDLLName); | |
| 718 } else { | |
| 719 codec_ = media::kCodecVP9; | |
| 720 dll_path = dll_path.Append(kVP9DecoderDLLName); | |
| 721 } | |
| 722 decoder_dll = ::LoadLibrary(dll_path.value().data()); | |
|
DaleCurtis
2014/11/25 00:32:55
Do you want to specify LOAD_WITH_ALTERED_SEARCH_PA
luken
2014/11/25 01:07:02
Ah, good point, I'll do that.
| |
| 723 RETURN_ON_FAILURE(decoder_dll, "vpx decoder dll is not loaded", false); | |
| 724 } else { | |
| 725 RETURN_ON_FAILURE(false, "Unsupported codec.", false); | |
| 726 } | |
| 666 | 727 |
| 667 typedef HRESULT(WINAPI * GetClassObject)( | 728 typedef HRESULT(WINAPI * GetClassObject)( |
| 668 const CLSID & clsid, const IID & iid, void * *object); | 729 const CLSID & clsid, const IID & iid, void * *object); |
| 669 | 730 |
| 670 GetClassObject get_class_object = reinterpret_cast<GetClassObject>( | 731 GetClassObject get_class_object = reinterpret_cast<GetClassObject>( |
| 671 GetProcAddress(decoder_dll, "DllGetClassObject")); | 732 GetProcAddress(decoder_dll, "DllGetClassObject")); |
| 672 RETURN_ON_FAILURE( | 733 RETURN_ON_FAILURE( |
| 673 get_class_object, "Failed to get DllGetClassObject pointer", false); | 734 get_class_object, "Failed to get DllGetClassObject pointer", false); |
| 674 | 735 |
| 675 base::win::ScopedComPtr<IClassFactory> factory; | 736 base::win::ScopedComPtr<IClassFactory> factory; |
| 676 HRESULT hr = get_class_object(__uuidof(CMSH264DecoderMFT), | 737 HRESULT hr; |
| 677 __uuidof(IClassFactory), | 738 if (codec_ == media::kCodecH264) { |
| 678 reinterpret_cast<void**>(factory.Receive())); | 739 hr = get_class_object(__uuidof(CMSH264DecoderMFT), |
| 740 __uuidof(IClassFactory), | |
| 741 reinterpret_cast<void**>(factory.Receive())); | |
| 742 } else if (codec_ == media::kCodecVP8) { | |
| 743 hr = get_class_object(CLSID_WebmMfVp8Dec, | |
| 744 __uuidof(IClassFactory), | |
| 745 reinterpret_cast<void**>(factory.Receive())); | |
| 746 } else if (codec_ == media::kCodecVP9) { | |
| 747 hr = get_class_object(CLSID_WebmMfVp9Dec, | |
| 748 __uuidof(IClassFactory), | |
| 749 reinterpret_cast<void**>(factory.Receive())); | |
| 750 } else { | |
| 751 RETURN_ON_FAILURE(false, "Unsupported codec.", false); | |
| 752 } | |
| 679 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false); | 753 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false); |
| 680 | 754 |
| 681 hr = factory->CreateInstance(NULL, | 755 hr = factory->CreateInstance(NULL, |
| 682 __uuidof(IMFTransform), | 756 __uuidof(IMFTransform), |
| 683 reinterpret_cast<void**>(decoder_.Receive())); | 757 reinterpret_cast<void**>(decoder_.Receive())); |
| 684 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false); | 758 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false); |
| 685 | 759 |
| 686 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(), | 760 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(), |
| 687 "Failed to check decoder DXVA support", false); | 761 "Failed to check decoder DXVA support", false); |
| 688 | 762 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 718 | 792 |
| 719 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { | 793 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { |
| 720 base::win::ScopedComPtr<IMFAttributes> attributes; | 794 base::win::ScopedComPtr<IMFAttributes> attributes; |
| 721 HRESULT hr = decoder_->GetAttributes(attributes.Receive()); | 795 HRESULT hr = decoder_->GetAttributes(attributes.Receive()); |
| 722 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); | 796 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); |
| 723 | 797 |
| 724 UINT32 dxva = 0; | 798 UINT32 dxva = 0; |
| 725 hr = attributes->GetUINT32(MF_SA_D3D_AWARE, &dxva); | 799 hr = attributes->GetUINT32(MF_SA_D3D_AWARE, &dxva); |
| 726 RETURN_ON_HR_FAILURE(hr, "Failed to check if decoder supports DXVA", false); | 800 RETURN_ON_HR_FAILURE(hr, "Failed to check if decoder supports DXVA", false); |
| 727 | 801 |
| 728 hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); | 802 if (codec_ == media::kCodecH264) { |
| 729 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); | 803 hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); |
| 804 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); | |
| 805 } | |
| 806 | |
| 730 return true; | 807 return true; |
| 731 } | 808 } |
| 732 | 809 |
| 733 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { | 810 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { |
| 734 RETURN_ON_FAILURE(SetDecoderInputMediaType(), | 811 RETURN_ON_FAILURE(SetDecoderInputMediaType(), |
| 735 "Failed to set decoder input media type", false); | 812 "Failed to set decoder input media type", false); |
| 736 return SetDecoderOutputMediaType(MFVideoFormat_NV12); | 813 return SetDecoderOutputMediaType(MFVideoFormat_NV12); |
| 737 } | 814 } |
| 738 | 815 |
| 816 const CLSID MEDIASUBTYPE_VP80 = { | |
| 817 0x30385056, | |
| 818 0x0000, | |
| 819 0x0010, | |
| 820 { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } | |
| 821 }; | |
| 822 | |
| 823 const CLSID MEDIASUBTYPE_VP90 = { | |
| 824 0x30395056, | |
| 825 0x0000, | |
| 826 0x0010, | |
| 827 { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } | |
| 828 }; | |
| 829 | |
| 739 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { | 830 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { |
| 740 base::win::ScopedComPtr<IMFMediaType> media_type; | 831 base::win::ScopedComPtr<IMFMediaType> media_type; |
| 741 HRESULT hr = MFCreateMediaType(media_type.Receive()); | 832 HRESULT hr = MFCreateMediaType(media_type.Receive()); |
| 742 RETURN_ON_HR_FAILURE(hr, "MFCreateMediaType failed", false); | 833 RETURN_ON_HR_FAILURE(hr, "MFCreateMediaType failed", false); |
| 743 | 834 |
| 744 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); | 835 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); |
| 745 RETURN_ON_HR_FAILURE(hr, "Failed to set major input type", false); | 836 RETURN_ON_HR_FAILURE(hr, "Failed to set major input type", false); |
| 746 | 837 |
| 747 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); | 838 if (codec_ == media::kCodecH264) { |
| 839 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); | |
| 840 } else if (codec_ == media::kCodecVP8) { | |
| 841 hr = media_type->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_VP80); | |
| 842 } else if (codec_ == media::kCodecVP9) { | |
| 843 hr = media_type->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_VP90); | |
| 844 } else { | |
| 845 NOTREACHED(); | |
| 846 RETURN_ON_FAILURE(false, "Unsupported codec on input media type.", false); | |
| 847 } | |
| 748 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); | 848 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); |
| 749 | 849 |
| 750 // Not sure about this. msdn recommends setting this value on the input | 850 // Not sure about this. msdn recommends setting this value on the input |
| 751 // media type. | 851 // media type. |
| 752 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, | 852 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, |
| 753 MFVideoInterlace_MixedInterlaceOrProgressive); | 853 MFVideoInterlace_MixedInterlaceOrProgressive); |
| 754 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); | 854 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); |
| 755 | 855 |
| 756 hr = decoder_->SetInputType(0, media_type.get(), 0); // No flags | 856 hr = decoder_->SetInputType(0, media_type.get(), 0); // No flags |
| 757 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); | 857 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 791 // sure they're the correct size. We only provide decoding if DXVA is enabled. | 891 // sure they're the correct size. We only provide decoding if DXVA is enabled. |
| 792 bool DXVAVideoDecodeAccelerator::GetStreamsInfoAndBufferReqs() { | 892 bool DXVAVideoDecodeAccelerator::GetStreamsInfoAndBufferReqs() { |
| 793 HRESULT hr = decoder_->GetInputStreamInfo(0, &input_stream_info_); | 893 HRESULT hr = decoder_->GetInputStreamInfo(0, &input_stream_info_); |
| 794 RETURN_ON_HR_FAILURE(hr, "Failed to get input stream info", false); | 894 RETURN_ON_HR_FAILURE(hr, "Failed to get input stream info", false); |
| 795 | 895 |
| 796 hr = decoder_->GetOutputStreamInfo(0, &output_stream_info_); | 896 hr = decoder_->GetOutputStreamInfo(0, &output_stream_info_); |
| 797 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder output stream info", false); | 897 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder output stream info", false); |
| 798 | 898 |
| 799 DVLOG(1) << "Input stream info: "; | 899 DVLOG(1) << "Input stream info: "; |
| 800 DVLOG(1) << "Max latency: " << input_stream_info_.hnsMaxLatency; | 900 DVLOG(1) << "Max latency: " << input_stream_info_.hnsMaxLatency; |
| 801 // There should be three flags, one for requiring a whole frame be in a | 901 if (codec_ == media::kCodecH264) { |
| 802 // single sample, one for requiring there be one buffer only in a single | 902 // There should be three flags, one for requiring a whole frame be in a |
| 803 // sample, and one that specifies a fixed sample size. (as in cbSize) | 903 // single sample, one for requiring there be one buffer only in a single |
| 804 CHECK_EQ(input_stream_info_.dwFlags, 0x7u); | 904 // sample, and one that specifies a fixed sample size. (as in cbSize) |
| 905 CHECK_EQ(input_stream_info_.dwFlags, 0x7u); | |
| 906 } | |
| 805 | 907 |
| 806 DVLOG(1) << "Min buffer size: " << input_stream_info_.cbSize; | 908 DVLOG(1) << "Min buffer size: " << input_stream_info_.cbSize; |
| 807 DVLOG(1) << "Max lookahead: " << input_stream_info_.cbMaxLookahead; | 909 DVLOG(1) << "Max lookahead: " << input_stream_info_.cbMaxLookahead; |
| 808 DVLOG(1) << "Alignment: " << input_stream_info_.cbAlignment; | 910 DVLOG(1) << "Alignment: " << input_stream_info_.cbAlignment; |
| 809 | 911 |
| 810 DVLOG(1) << "Output stream info: "; | 912 DVLOG(1) << "Output stream info: "; |
| 811 // The flags here should be the same and mean the same thing, except when | 913 // The flags here should be the same and mean the same thing, except when |
| 812 // DXVA is enabled, there is an extra 0x100 flag meaning decoder will | 914 // DXVA is enabled, there is an extra 0x100 flag meaning decoder will |
| 813 // allocate its own sample. | 915 // allocate its own sample. |
| 814 DVLOG(1) << "Flags: " | 916 DVLOG(1) << "Flags: " |
| 815 << std::hex << std::showbase << output_stream_info_.dwFlags; | 917 << std::hex << std::showbase << output_stream_info_.dwFlags; |
| 816 CHECK_EQ(output_stream_info_.dwFlags, 0x107u); | 918 if (codec_ == media::kCodecH264) { |
| 919 CHECK_EQ(output_stream_info_.dwFlags, 0x107u); | |
| 920 } | |
| 817 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize; | 921 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize; |
| 818 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment; | 922 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment; |
| 819 return true; | 923 return true; |
| 820 } | 924 } |
| 821 | 925 |
| 822 void DXVAVideoDecodeAccelerator::DoDecode() { | 926 void DXVAVideoDecodeAccelerator::DoDecode() { |
| 823 // This function is also called from FlushInternal in a loop which could | 927 // This function is also called from FlushInternal in a loop which could |
| 824 // result in the state transitioning to kStopped due to no decoded output. | 928 // result in the state transitioning to kStopped due to no decoded output. |
| 825 RETURN_AND_NOTIFY_ON_FAILURE( | 929 RETURN_AND_NOTIFY_ON_FAILURE( |
| 826 (state_ == kNormal || state_ == kFlushing || | 930 (state_ == kNormal || state_ == kFlushing || |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1251 int32 picture_buffer_id) { | 1355 int32 picture_buffer_id) { |
| 1252 OutputBuffers::iterator it = stale_output_picture_buffers_.find( | 1356 OutputBuffers::iterator it = stale_output_picture_buffers_.find( |
| 1253 picture_buffer_id); | 1357 picture_buffer_id); |
| 1254 DCHECK(it != stale_output_picture_buffers_.end()); | 1358 DCHECK(it != stale_output_picture_buffers_.end()); |
| 1255 DVLOG(1) << "Dismissing picture id: " << it->second->id(); | 1359 DVLOG(1) << "Dismissing picture id: " << it->second->id(); |
| 1256 client_->DismissPictureBuffer(it->second->id()); | 1360 client_->DismissPictureBuffer(it->second->id()); |
| 1257 stale_output_picture_buffers_.erase(it); | 1361 stale_output_picture_buffers_.erase(it); |
| 1258 } | 1362 } |
| 1259 | 1363 |
| 1260 } // namespace content | 1364 } // namespace content |
| OLD | NEW |