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 "media/filters/gpu_video_decoder.h" | 5 #include "media/filters/gpu_video_decoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | 90 base::MessageLoop::current()->PostTask(FROM_HERE, closure); |
91 return; | 91 return; |
92 } | 92 } |
93 | 93 |
94 DCHECK(pending_reset_cb_.is_null()); | 94 DCHECK(pending_reset_cb_.is_null()); |
95 pending_reset_cb_ = BindToCurrentLoop(closure); | 95 pending_reset_cb_ = BindToCurrentLoop(closure); |
96 | 96 |
97 vda_->Reset(); | 97 vda_->Reset(); |
98 } | 98 } |
99 | 99 |
100 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { | 100 static bool IsCodedSizeSupported(const gfx::Size& coded_size, |
101 #if defined(OS_WIN) | 101 const gfx::Size& min_resolution, |
102 // Windows Media Foundation H.264 decoding does not support decoding videos | 102 const gfx::Size& max_resolution) { |
103 // with any dimension smaller than 48 pixels: | 103 if (coded_size.width() <= max_resolution.width() && |
104 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 | 104 coded_size.height() <= max_resolution.height() && |
105 if (coded_size.width() < 48 || coded_size.height() < 48) | 105 coded_size.width() >= min_resolution.width() && |
106 return false; | 106 coded_size.height() >= min_resolution.height()) { |
107 #endif | |
108 | |
109 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. | |
110 // We test against 1088 to account for 16x16 macroblocks. | |
111 if (coded_size.width() <= 1920 && coded_size.height() <= 1088) | |
112 return true; | 107 return true; |
113 | 108 } |
114 // NOTE: additional autodetection logic may require updating input buffer size | 109 return false; |
115 // selection in platform-specific implementations, such as | |
116 // V4L2VideoDecodeAccelerator. | |
117 base::CPU cpu; | |
118 bool hw_large_video_support = | |
119 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
120 switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode) || | |
121 ((cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 55); | |
122 bool os_large_video_support = true; | |
123 #if defined(OS_WIN) | |
124 os_large_video_support = false; | |
125 #endif | |
126 return os_large_video_support && hw_large_video_support; | |
127 } | 110 } |
128 | 111 |
129 // Report |status| to UMA and run |cb| with it. This is super-specific to the | 112 // Report |status| to UMA and run |cb| with it. This is super-specific to the |
130 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a | 113 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a |
131 // callsite to always be called with the same stat name (can't parameterize it). | 114 // callsite to always be called with the same stat name (can't parameterize it). |
132 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( | 115 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( |
133 const PipelineStatusCB& cb, | 116 const PipelineStatusCB& cb, |
134 PipelineStatus status) { | 117 PipelineStatus status) { |
135 UMA_HISTOGRAM_ENUMERATION( | 118 UMA_HISTOGRAM_ENUMERATION( |
136 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); | 119 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); |
(...skipping 22 matching lines...) Expand all Loading... | |
159 << config.AsHumanReadableString(); | 142 << config.AsHumanReadableString(); |
160 | 143 |
161 // TODO(posciak): destroy and create a new VDA on codec/profile change | 144 // TODO(posciak): destroy and create a new VDA on codec/profile change |
162 // (http://crbug.com/260224). | 145 // (http://crbug.com/260224). |
163 if (previously_initialized && (config_.profile() != config.profile())) { | 146 if (previously_initialized && (config_.profile() != config.profile())) { |
164 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; | 147 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; |
165 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 148 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
166 return; | 149 return; |
167 } | 150 } |
168 | 151 |
169 if (!IsCodedSizeSupported(config.coded_size())) { | 152 if (!IsProfileSupported(config.profile(), config.coded_size())) { |
170 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 153 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
171 return; | 154 return; |
172 } | 155 } |
173 | 156 |
174 config_ = config; | 157 config_ = config; |
175 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 158 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
176 output_cb_ = BindToCurrentLoop(output_cb); | 159 output_cb_ = BindToCurrentLoop(output_cb); |
177 | 160 |
178 if (previously_initialized) { | 161 if (previously_initialized) { |
179 // Reinitialization with a different config (but same codec and profile). | 162 // Reinitialization with a different config (but same codec and profile). |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
583 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 566 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
584 if (!vda_) | 567 if (!vda_) |
585 return; | 568 return; |
586 | 569 |
587 state_ = kError; | 570 state_ = kError; |
588 | 571 |
589 DLOG(ERROR) << "VDA Error: " << error; | 572 DLOG(ERROR) << "VDA Error: " << error; |
590 DestroyVDA(); | 573 DestroyVDA(); |
591 } | 574 } |
592 | 575 |
576 bool GpuVideoDecoder::IsProfileSupported(const VideoCodecProfile& profile, | |
577 const gfx::Size& coded_size) { | |
578 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | |
579 bool support_query_profile = false; | |
580 std::vector<VideoDecodeAccelerator::SupportedProfile> supported_profiles = | |
581 factories_->GetVideoDecodeAcceleratorSupportedProfiles( | |
582 &support_query_profile); | |
583 if (support_query_profile) { | |
584 for (const auto& supported_profile : supported_profiles) { | |
585 if (profile == supported_profile.profile && | |
586 IsCodedSizeSupported(coded_size, | |
587 supported_profile.min_resolution, | |
588 supported_profile.max_resolution)) { | |
wuchengli
2015/03/18 08:02:38
Can you check with Pawel if max_resolution indicat
| |
589 return true; | |
590 } | |
591 } | |
592 } else { | |
593 #if defined(OS_WIN) | |
594 // Windows Media Foundation H.264 decoding does not support decoding videos | |
595 // with any dimension smaller than 48 pixels: | |
596 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 | |
597 // Use 1088 to account for 16x16 macroblocks. | |
598 return IsCodedSizeSupported( | |
599 coded_size, gfx::Size(48, 48), gfx::Size(1920, 1088)); | |
600 #else | |
601 return IsCodedSizeSupported( | |
602 coded_size, gfx::Size(16, 16), gfx::Size(1920, 1088)); | |
603 #endif | |
604 } | |
605 return false; | |
606 } | |
607 | |
593 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 608 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
594 const { | 609 const { |
595 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 610 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
596 } | 611 } |
597 | 612 |
598 } // namespace media | 613 } // namespace media |
OLD | NEW |