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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 VideoCodecProfile profile) { | 101 const gfx::Size& min_resolution, |
102 #if defined(OS_WIN) | 102 const gfx::Size& max_resolution) { |
103 // Windows Media Foundation H.264 decoding does not support decoding videos | 103 return (coded_size.width() <= max_resolution.width() && |
104 // with any dimension smaller than 48 pixels: | 104 coded_size.height() <= max_resolution.height() && |
105 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 | 105 coded_size.width() >= min_resolution.width() && |
106 if (coded_size.width() < 48 || coded_size.height() < 48) | 106 coded_size.height() >= min_resolution.height()); |
107 return false; | |
108 #endif | |
109 | |
110 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. | |
111 // We test against 1088 to account for 16x16 macroblocks. | |
112 if (coded_size.width() <= 1920 && coded_size.height() <= 1088) | |
113 return true; | |
114 | |
115 // NOTE: additional autodetection logic may require updating input buffer size | |
116 // selection in platform-specific implementations, such as | |
117 // V4L2VideoDecodeAccelerator. | |
118 base::CPU cpu; | |
119 bool hw_large_video_support = | |
120 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
121 switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode) || | |
122 ((cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 55 && | |
123 // TODO(posciak, henryhsu): Remove this once we can query in runtime. | |
124 profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX); | |
125 bool os_large_video_support = true; | |
126 #if defined(OS_WIN) | |
127 os_large_video_support = false; | |
128 #endif | |
129 return os_large_video_support && hw_large_video_support; | |
130 } | 107 } |
131 | 108 |
132 // Report |status| to UMA and run |cb| with it. This is super-specific to the | 109 // Report |status| to UMA and run |cb| with it. This is super-specific to the |
133 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a | 110 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a |
134 // callsite to always be called with the same stat name (can't parameterize it). | 111 // callsite to always be called with the same stat name (can't parameterize it). |
135 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( | 112 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( |
136 const PipelineStatusCB& cb, | 113 const PipelineStatusCB& cb, |
137 PipelineStatus status) { | 114 PipelineStatus status) { |
138 UMA_HISTOGRAM_ENUMERATION( | 115 UMA_HISTOGRAM_ENUMERATION( |
139 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); | 116 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); |
(...skipping 22 matching lines...) Expand all Loading... |
162 << config.AsHumanReadableString(); | 139 << config.AsHumanReadableString(); |
163 | 140 |
164 // TODO(posciak): destroy and create a new VDA on codec/profile change | 141 // TODO(posciak): destroy and create a new VDA on codec/profile change |
165 // (http://crbug.com/260224). | 142 // (http://crbug.com/260224). |
166 if (previously_initialized && (config_.profile() != config.profile())) { | 143 if (previously_initialized && (config_.profile() != config.profile())) { |
167 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; | 144 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; |
168 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 145 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
169 return; | 146 return; |
170 } | 147 } |
171 | 148 |
172 if (!IsCodedSizeSupported(config.coded_size(), config.profile())) { | 149 if (!IsProfileSupported(config.profile(), config.coded_size())) { |
173 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 150 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
174 return; | 151 return; |
175 } | 152 } |
176 | 153 |
177 config_ = config; | 154 config_ = config; |
178 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 155 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
179 output_cb_ = BindToCurrentLoop(output_cb); | 156 output_cb_ = BindToCurrentLoop(output_cb); |
180 | 157 |
181 if (previously_initialized) { | 158 if (previously_initialized) { |
182 // Reinitialization with a different config (but same codec and profile). | 159 // Reinitialization with a different config (but same codec and profile). |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 563 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
587 if (!vda_) | 564 if (!vda_) |
588 return; | 565 return; |
589 | 566 |
590 state_ = kError; | 567 state_ = kError; |
591 | 568 |
592 DLOG(ERROR) << "VDA Error: " << error; | 569 DLOG(ERROR) << "VDA Error: " << error; |
593 DestroyVDA(); | 570 DestroyVDA(); |
594 } | 571 } |
595 | 572 |
| 573 bool GpuVideoDecoder::IsProfileSupported(VideoCodecProfile profile, |
| 574 const gfx::Size& coded_size) { |
| 575 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
| 576 VideoDecodeAccelerator::SupportedProfiles supported_profiles = |
| 577 factories_->GetVideoDecodeAcceleratorSupportedProfiles(); |
| 578 for (const auto& supported_profile : supported_profiles) { |
| 579 if (profile == supported_profile.profile) { |
| 580 return IsCodedSizeSupported(coded_size, |
| 581 supported_profile.min_resolution, |
| 582 supported_profile.max_resolution); |
| 583 } |
| 584 } |
| 585 return false; |
| 586 } |
| 587 |
596 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 588 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
597 const { | 589 const { |
598 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 590 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
599 } | 591 } |
600 | 592 |
601 } // namespace media | 593 } // namespace media |
OLD | NEW |