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 |
| 35 namespace { |
| 36 |
| 37 // Path is appended on to the PROGRAM_FILES base path. |
| 38 const wchar_t kVPXDecoderDLLPath[] = L"Intel\\Media SDK\\"; |
| 39 |
| 40 const wchar_t kVP8DecoderDLLName[] = |
| 41 #if defined(ARCH_CPU_X86) |
| 42 L"mfx_mft_vp8vd_32.dll"; |
| 43 #elif defined(ARCH_CPU_X86_64) |
| 44 L"mfx_mft_vp8vd_64.dll"; |
| 45 #else |
| 46 #error Unsupported Windows CPU Architecture |
| 47 #endif |
| 48 |
| 49 const wchar_t kVP9DecoderDLLName[] = |
| 50 #if defined(ARCH_CPU_X86) |
| 51 L"mfx_mft_vp9vd_32.dll"; |
| 52 #elif defined(ARCH_CPU_X86_64) |
| 53 L"mfx_mft_vp9vd_64.dll"; |
| 54 #else |
| 55 #error Unsupported Windows CPU Architecture |
| 56 #endif |
| 57 |
| 58 const CLSID CLSID_WebmMfVp8Dec = { |
| 59 0x451e3cb7, |
| 60 0x2622, |
| 61 0x4ba5, |
| 62 { 0x8e, 0x1d, 0x44, 0xb3, 0xc4, 0x1d, 0x09, 0x24 } |
| 63 }; |
| 64 |
| 65 const CLSID CLSID_WebmMfVp9Dec = { |
| 66 0x07ab4bd2, |
| 67 0x1979, |
| 68 0x4fcd, |
| 69 { 0xa6, 0x97, 0xdf, 0x9a, 0xd1, 0x5b, 0x34, 0xfe } |
| 70 }; |
| 71 |
| 72 const CLSID MEDIASUBTYPE_VP80 = { |
| 73 0x30385056, |
| 74 0x0000, |
| 75 0x0010, |
| 76 { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } |
| 77 }; |
| 78 |
| 79 const CLSID MEDIASUBTYPE_VP90 = { |
| 80 0x30395056, |
| 81 0x0000, |
| 82 0x0010, |
| 83 { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } |
| 84 }; |
| 85 |
| 86 } |
| 87 |
32 namespace content { | 88 namespace content { |
33 | 89 |
34 // We only request 5 picture buffers from the client which are used to hold the | 90 // 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 | 91 // decoded samples. These buffers are then reused when the client tells us that |
36 // it is done with the buffer. | 92 // it is done with the buffer. |
37 static const int kNumPictureBuffers = 5; | 93 static const int kNumPictureBuffers = 5; |
38 | 94 |
39 #define RETURN_ON_FAILURE(result, log, ret) \ | 95 #define RETURN_ON_FAILURE(result, log, ret) \ |
40 do { \ | 96 do { \ |
41 if (!(result)) { \ | 97 if (!(result)) { \ |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 | 480 |
425 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( | 481 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( |
426 const base::Callback<bool(void)>& make_context_current) | 482 const base::Callback<bool(void)>& make_context_current) |
427 : client_(NULL), | 483 : client_(NULL), |
428 dev_manager_reset_token_(0), | 484 dev_manager_reset_token_(0), |
429 egl_config_(NULL), | 485 egl_config_(NULL), |
430 state_(kUninitialized), | 486 state_(kUninitialized), |
431 pictures_requested_(false), | 487 pictures_requested_(false), |
432 inputs_before_decode_(0), | 488 inputs_before_decode_(0), |
433 make_context_current_(make_context_current), | 489 make_context_current_(make_context_current), |
434 weak_this_factory_(this) { | 490 weak_this_factory_(this), |
| 491 codec_(media::kUnknownVideoCodec) { |
435 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); | 492 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); |
436 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); | 493 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); |
437 } | 494 } |
438 | 495 |
439 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { | 496 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { |
440 client_ = NULL; | 497 client_ = NULL; |
441 } | 498 } |
442 | 499 |
443 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, | 500 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
444 Client* client) { | 501 Client* client) { |
445 DCHECK(CalledOnValidThread()); | 502 DCHECK(CalledOnValidThread()); |
446 | 503 |
447 client_ = client; | 504 client_ = client; |
448 | 505 |
449 // Not all versions of Windows 7 and later include Media Foundation DLLs. | 506 // Not all versions of Windows 7 and later include Media Foundation DLLs. |
450 // Instead of crashing while delay loading the DLL when calling MFStartup() | 507 // Instead of crashing while delay loading the DLL when calling MFStartup() |
451 // below, probe whether we can successfully load the DLL now. | 508 // below, probe whether we can successfully load the DLL now. |
452 // | 509 // |
453 // See http://crbug.com/339678 for details. | 510 // See http://crbug.com/339678 for details. |
454 HMODULE mfplat_dll = ::LoadLibrary(L"MFPlat.dll"); | 511 HMODULE mfplat_dll = ::LoadLibrary(L"MFPlat.dll"); |
455 RETURN_ON_FAILURE(mfplat_dll, "MFPlat.dll is required for decoding", false); | 512 RETURN_ON_FAILURE(mfplat_dll, "MFPlat.dll is required for decoding", false); |
456 | 513 |
457 // TODO(ananta) | 514 // TODO(ananta) |
458 // H264PROFILE_HIGH video decoding is janky at times. Needs more | 515 // H264PROFILE_HIGH video decoding is janky at times. Needs more |
459 // investigation. http://crbug.com/426707 | 516 // investigation. http://crbug.com/426707 |
460 if (profile != media::H264PROFILE_BASELINE && | 517 if (profile != media::H264PROFILE_BASELINE && |
461 profile != media::H264PROFILE_MAIN) { | 518 profile != media::H264PROFILE_MAIN && |
| 519 profile != media::VP8PROFILE_ANY && |
| 520 profile != media::VP9PROFILE_ANY) { |
462 RETURN_AND_NOTIFY_ON_FAILURE(false, | 521 RETURN_AND_NOTIFY_ON_FAILURE(false, |
463 "Unsupported h264 profile", PLATFORM_FAILURE, false); | 522 "Unsupported h.264, vp8, or vp9 profile", PLATFORM_FAILURE, false); |
464 } | 523 } |
465 | 524 |
466 RETURN_AND_NOTIFY_ON_FAILURE( | 525 RETURN_AND_NOTIFY_ON_FAILURE( |
467 gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle, | 526 gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle, |
468 "EGL_ANGLE_surface_d3d_texture_2d_share_handle unavailable", | 527 "EGL_ANGLE_surface_d3d_texture_2d_share_handle unavailable", |
469 PLATFORM_FAILURE, | 528 PLATFORM_FAILURE, |
470 false); | 529 false); |
471 | 530 |
472 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kUninitialized), | 531 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kUninitialized), |
473 "Initialize: invalid state: " << state_, ILLEGAL_STATE, false); | 532 "Initialize: invalid state: " << state_, ILLEGAL_STATE, false); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 DCHECK(CalledOnValidThread()); | 691 DCHECK(CalledOnValidThread()); |
633 Invalidate(); | 692 Invalidate(); |
634 delete this; | 693 delete this; |
635 } | 694 } |
636 | 695 |
637 bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { | 696 bool DXVAVideoDecodeAccelerator::CanDecodeOnIOThread() { |
638 return false; | 697 return false; |
639 } | 698 } |
640 | 699 |
641 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { | 700 bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { |
642 if (profile < media::H264PROFILE_MIN || profile > media::H264PROFILE_MAX) | 701 HMODULE decoder_dll = NULL; |
643 return false; | |
644 | 702 |
645 // We mimic the steps CoCreateInstance uses to instantiate the object. This | 703 // 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 | 704 if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { |
647 // as a more minimal approach to avoid other side-effects CCI might have (as | 705 // We mimic the steps CoCreateInstance uses to instantiate the object. This |
648 // we are still in a reduced sandbox). | 706 // was previously done because it failed inside the sandbox, and now is done |
649 HMODULE decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll"); | 707 // as a more minimal approach to avoid other side-effects CCI might have (as |
650 RETURN_ON_FAILURE(decoder_dll, | 708 // we are still in a reduced sandbox). |
651 "msmpeg2vdec.dll required for decoding is not loaded", | 709 decoder_dll = ::LoadLibrary(L"msmpeg2vdec.dll"); |
652 false); | 710 RETURN_ON_FAILURE(decoder_dll, |
| 711 "msmpeg2vdec.dll required for decoding is not loaded", |
| 712 false); |
653 | 713 |
654 // Check version of DLL, version 6.7.7140 is blacklisted due to high crash | 714 // 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 | 715 // rates in browsers loading that DLL. If that is the version installed we |
656 // fall back to software decoding. See crbug/403440. | 716 // fall back to software decoding. See crbug/403440. |
657 FileVersionInfo* version_info = | 717 FileVersionInfo* version_info = |
658 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll); | 718 FileVersionInfo::CreateFileVersionInfoForModule(decoder_dll); |
659 RETURN_ON_FAILURE(version_info, | 719 RETURN_ON_FAILURE(version_info, |
660 "unable to get version of msmpeg2vdec.dll", | 720 "unable to get version of msmpeg2vdec.dll", |
661 false); | 721 false); |
662 base::string16 file_version = version_info->file_version(); | 722 base::string16 file_version = version_info->file_version(); |
663 RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos, | 723 RETURN_ON_FAILURE(file_version.find(L"6.1.7140") == base::string16::npos, |
664 "blacklisted version of msmpeg2vdec.dll 6.7.7140", | 724 "blacklisted version of msmpeg2vdec.dll 6.7.7140", |
665 false); | 725 false); |
| 726 codec_ = media::kCodecH264; |
| 727 } else if (profile == media::VP8PROFILE_ANY || |
| 728 profile == media::VP9PROFILE_ANY) { |
| 729 base::FilePath dll_path; |
| 730 RETURN_ON_FAILURE(PathService::Get(base::DIR_PROGRAM_FILES, &dll_path), |
| 731 "failed to get path for DIR_PROGRAM_FILES", false); |
| 732 dll_path = dll_path.Append(kVPXDecoderDLLPath); |
| 733 if (profile == media::VP8PROFILE_ANY) { |
| 734 codec_ = media::kCodecVP8; |
| 735 dll_path = dll_path.Append(kVP8DecoderDLLName); |
| 736 } else { |
| 737 codec_ = media::kCodecVP9; |
| 738 dll_path = dll_path.Append(kVP9DecoderDLLName); |
| 739 } |
| 740 decoder_dll = ::LoadLibraryEx(dll_path.value().data(), NULL, |
| 741 LOAD_WITH_ALTERED_SEARCH_PATH); |
| 742 RETURN_ON_FAILURE(decoder_dll, "vpx decoder dll is not loaded", false); |
| 743 } else { |
| 744 RETURN_ON_FAILURE(false, "Unsupported codec.", false); |
| 745 } |
666 | 746 |
667 typedef HRESULT(WINAPI * GetClassObject)( | 747 typedef HRESULT(WINAPI * GetClassObject)( |
668 const CLSID & clsid, const IID & iid, void * *object); | 748 const CLSID & clsid, const IID & iid, void * *object); |
669 | 749 |
670 GetClassObject get_class_object = reinterpret_cast<GetClassObject>( | 750 GetClassObject get_class_object = reinterpret_cast<GetClassObject>( |
671 GetProcAddress(decoder_dll, "DllGetClassObject")); | 751 GetProcAddress(decoder_dll, "DllGetClassObject")); |
672 RETURN_ON_FAILURE( | 752 RETURN_ON_FAILURE( |
673 get_class_object, "Failed to get DllGetClassObject pointer", false); | 753 get_class_object, "Failed to get DllGetClassObject pointer", false); |
674 | 754 |
675 base::win::ScopedComPtr<IClassFactory> factory; | 755 base::win::ScopedComPtr<IClassFactory> factory; |
676 HRESULT hr = get_class_object(__uuidof(CMSH264DecoderMFT), | 756 HRESULT hr; |
677 __uuidof(IClassFactory), | 757 if (codec_ == media::kCodecH264) { |
678 reinterpret_cast<void**>(factory.Receive())); | 758 hr = get_class_object(__uuidof(CMSH264DecoderMFT), |
| 759 __uuidof(IClassFactory), |
| 760 reinterpret_cast<void**>(factory.Receive())); |
| 761 } else if (codec_ == media::kCodecVP8) { |
| 762 hr = get_class_object(CLSID_WebmMfVp8Dec, |
| 763 __uuidof(IClassFactory), |
| 764 reinterpret_cast<void**>(factory.Receive())); |
| 765 } else if (codec_ == media::kCodecVP9) { |
| 766 hr = get_class_object(CLSID_WebmMfVp9Dec, |
| 767 __uuidof(IClassFactory), |
| 768 reinterpret_cast<void**>(factory.Receive())); |
| 769 } else { |
| 770 RETURN_ON_FAILURE(false, "Unsupported codec.", false); |
| 771 } |
679 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false); | 772 RETURN_ON_HR_FAILURE(hr, "DllGetClassObject for decoder failed", false); |
680 | 773 |
681 hr = factory->CreateInstance(NULL, | 774 hr = factory->CreateInstance(NULL, |
682 __uuidof(IMFTransform), | 775 __uuidof(IMFTransform), |
683 reinterpret_cast<void**>(decoder_.Receive())); | 776 reinterpret_cast<void**>(decoder_.Receive())); |
684 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false); | 777 RETURN_ON_HR_FAILURE(hr, "Failed to create decoder instance", false); |
685 | 778 |
686 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(), | 779 RETURN_ON_FAILURE(CheckDecoderDxvaSupport(), |
687 "Failed to check decoder DXVA support", false); | 780 "Failed to check decoder DXVA support", false); |
688 | 781 |
(...skipping 29 matching lines...) Expand all Loading... |
718 | 811 |
719 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { | 812 bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { |
720 base::win::ScopedComPtr<IMFAttributes> attributes; | 813 base::win::ScopedComPtr<IMFAttributes> attributes; |
721 HRESULT hr = decoder_->GetAttributes(attributes.Receive()); | 814 HRESULT hr = decoder_->GetAttributes(attributes.Receive()); |
722 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); | 815 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); |
723 | 816 |
724 UINT32 dxva = 0; | 817 UINT32 dxva = 0; |
725 hr = attributes->GetUINT32(MF_SA_D3D_AWARE, &dxva); | 818 hr = attributes->GetUINT32(MF_SA_D3D_AWARE, &dxva); |
726 RETURN_ON_HR_FAILURE(hr, "Failed to check if decoder supports DXVA", false); | 819 RETURN_ON_HR_FAILURE(hr, "Failed to check if decoder supports DXVA", false); |
727 | 820 |
728 hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); | 821 if (codec_ == media::kCodecH264) { |
729 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); | 822 hr = attributes->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); |
| 823 RETURN_ON_HR_FAILURE(hr, "Failed to enable DXVA H/W decoding", false); |
| 824 } |
| 825 |
730 return true; | 826 return true; |
731 } | 827 } |
732 | 828 |
733 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { | 829 bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { |
734 RETURN_ON_FAILURE(SetDecoderInputMediaType(), | 830 RETURN_ON_FAILURE(SetDecoderInputMediaType(), |
735 "Failed to set decoder input media type", false); | 831 "Failed to set decoder input media type", false); |
736 return SetDecoderOutputMediaType(MFVideoFormat_NV12); | 832 return SetDecoderOutputMediaType(MFVideoFormat_NV12); |
737 } | 833 } |
738 | 834 |
739 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { | 835 bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { |
740 base::win::ScopedComPtr<IMFMediaType> media_type; | 836 base::win::ScopedComPtr<IMFMediaType> media_type; |
741 HRESULT hr = MFCreateMediaType(media_type.Receive()); | 837 HRESULT hr = MFCreateMediaType(media_type.Receive()); |
742 RETURN_ON_HR_FAILURE(hr, "MFCreateMediaType failed", false); | 838 RETURN_ON_HR_FAILURE(hr, "MFCreateMediaType failed", false); |
743 | 839 |
744 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); | 840 hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); |
745 RETURN_ON_HR_FAILURE(hr, "Failed to set major input type", false); | 841 RETURN_ON_HR_FAILURE(hr, "Failed to set major input type", false); |
746 | 842 |
747 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); | 843 if (codec_ == media::kCodecH264) { |
| 844 hr = media_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); |
| 845 } else if (codec_ == media::kCodecVP8) { |
| 846 hr = media_type->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_VP80); |
| 847 } else if (codec_ == media::kCodecVP9) { |
| 848 hr = media_type->SetGUID(MF_MT_SUBTYPE, MEDIASUBTYPE_VP90); |
| 849 } else { |
| 850 NOTREACHED(); |
| 851 RETURN_ON_FAILURE(false, "Unsupported codec on input media type.", false); |
| 852 } |
748 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); | 853 RETURN_ON_HR_FAILURE(hr, "Failed to set subtype", false); |
749 | 854 |
750 // Not sure about this. msdn recommends setting this value on the input | 855 // Not sure about this. msdn recommends setting this value on the input |
751 // media type. | 856 // media type. |
752 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, | 857 hr = media_type->SetUINT32(MF_MT_INTERLACE_MODE, |
753 MFVideoInterlace_MixedInterlaceOrProgressive); | 858 MFVideoInterlace_MixedInterlaceOrProgressive); |
754 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); | 859 RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false); |
755 | 860 |
756 hr = decoder_->SetInputType(0, media_type.get(), 0); // No flags | 861 hr = decoder_->SetInputType(0, media_type.get(), 0); // No flags |
757 RETURN_ON_HR_FAILURE(hr, "Failed to set decoder input type", false); | 862 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. | 896 // sure they're the correct size. We only provide decoding if DXVA is enabled. |
792 bool DXVAVideoDecodeAccelerator::GetStreamsInfoAndBufferReqs() { | 897 bool DXVAVideoDecodeAccelerator::GetStreamsInfoAndBufferReqs() { |
793 HRESULT hr = decoder_->GetInputStreamInfo(0, &input_stream_info_); | 898 HRESULT hr = decoder_->GetInputStreamInfo(0, &input_stream_info_); |
794 RETURN_ON_HR_FAILURE(hr, "Failed to get input stream info", false); | 899 RETURN_ON_HR_FAILURE(hr, "Failed to get input stream info", false); |
795 | 900 |
796 hr = decoder_->GetOutputStreamInfo(0, &output_stream_info_); | 901 hr = decoder_->GetOutputStreamInfo(0, &output_stream_info_); |
797 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder output stream info", false); | 902 RETURN_ON_HR_FAILURE(hr, "Failed to get decoder output stream info", false); |
798 | 903 |
799 DVLOG(1) << "Input stream info: "; | 904 DVLOG(1) << "Input stream info: "; |
800 DVLOG(1) << "Max latency: " << input_stream_info_.hnsMaxLatency; | 905 DVLOG(1) << "Max latency: " << input_stream_info_.hnsMaxLatency; |
801 // There should be three flags, one for requiring a whole frame be in a | 906 if (codec_ == media::kCodecH264) { |
802 // single sample, one for requiring there be one buffer only in a single | 907 // 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) | 908 // single sample, one for requiring there be one buffer only in a single |
804 CHECK_EQ(input_stream_info_.dwFlags, 0x7u); | 909 // sample, and one that specifies a fixed sample size. (as in cbSize) |
| 910 CHECK_EQ(input_stream_info_.dwFlags, 0x7u); |
| 911 } |
805 | 912 |
806 DVLOG(1) << "Min buffer size: " << input_stream_info_.cbSize; | 913 DVLOG(1) << "Min buffer size: " << input_stream_info_.cbSize; |
807 DVLOG(1) << "Max lookahead: " << input_stream_info_.cbMaxLookahead; | 914 DVLOG(1) << "Max lookahead: " << input_stream_info_.cbMaxLookahead; |
808 DVLOG(1) << "Alignment: " << input_stream_info_.cbAlignment; | 915 DVLOG(1) << "Alignment: " << input_stream_info_.cbAlignment; |
809 | 916 |
810 DVLOG(1) << "Output stream info: "; | 917 DVLOG(1) << "Output stream info: "; |
811 // The flags here should be the same and mean the same thing, except when | 918 // 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 | 919 // DXVA is enabled, there is an extra 0x100 flag meaning decoder will |
813 // allocate its own sample. | 920 // allocate its own sample. |
814 DVLOG(1) << "Flags: " | 921 DVLOG(1) << "Flags: " |
815 << std::hex << std::showbase << output_stream_info_.dwFlags; | 922 << std::hex << std::showbase << output_stream_info_.dwFlags; |
816 CHECK_EQ(output_stream_info_.dwFlags, 0x107u); | 923 if (codec_ == media::kCodecH264) { |
| 924 CHECK_EQ(output_stream_info_.dwFlags, 0x107u); |
| 925 } |
817 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize; | 926 DVLOG(1) << "Min buffer size: " << output_stream_info_.cbSize; |
818 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment; | 927 DVLOG(1) << "Alignment: " << output_stream_info_.cbAlignment; |
819 return true; | 928 return true; |
820 } | 929 } |
821 | 930 |
822 void DXVAVideoDecodeAccelerator::DoDecode() { | 931 void DXVAVideoDecodeAccelerator::DoDecode() { |
823 // This function is also called from FlushInternal in a loop which could | 932 // 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. | 933 // result in the state transitioning to kStopped due to no decoded output. |
825 RETURN_AND_NOTIFY_ON_FAILURE( | 934 RETURN_AND_NOTIFY_ON_FAILURE( |
826 (state_ == kNormal || state_ == kFlushing || | 935 (state_ == kNormal || state_ == kFlushing || |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 int32 picture_buffer_id) { | 1360 int32 picture_buffer_id) { |
1252 OutputBuffers::iterator it = stale_output_picture_buffers_.find( | 1361 OutputBuffers::iterator it = stale_output_picture_buffers_.find( |
1253 picture_buffer_id); | 1362 picture_buffer_id); |
1254 DCHECK(it != stale_output_picture_buffers_.end()); | 1363 DCHECK(it != stale_output_picture_buffers_.end()); |
1255 DVLOG(1) << "Dismissing picture id: " << it->second->id(); | 1364 DVLOG(1) << "Dismissing picture id: " << it->second->id(); |
1256 client_->DismissPictureBuffer(it->second->id()); | 1365 client_->DismissPictureBuffer(it->second->id()); |
1257 stale_output_picture_buffers_.erase(it); | 1366 stale_output_picture_buffers_.erase(it); |
1258 } | 1367 } |
1259 | 1368 |
1260 } // namespace content | 1369 } // namespace content |
OLD | NEW |