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 |