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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/cpu.h" | 9 #include "base/cpu.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 if (vda_) | 210 if (vda_) |
211 DestroyVDA(); | 211 DestroyVDA(); |
212 if (!pending_read_cb_.is_null()) | 212 if (!pending_read_cb_.is_null()) |
213 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 213 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
214 if (!pending_reset_cb_.is_null()) | 214 if (!pending_reset_cb_.is_null()) |
215 base::ResetAndReturn(&pending_reset_cb_).Run(); | 215 base::ResetAndReturn(&pending_reset_cb_).Run(); |
216 demuxer_stream_ = NULL; | 216 demuxer_stream_ = NULL; |
217 BindToCurrentLoop(closure).Run(); | 217 BindToCurrentLoop(closure).Run(); |
218 } | 218 } |
219 | 219 |
| 220 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { |
| 221 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. |
| 222 // We test against 1088 to account for 16x16 macroblocks. |
| 223 if (coded_size.width() <= 1920 && coded_size.height() <= 1088) |
| 224 return true; |
| 225 |
| 226 base::CPU cpu; |
| 227 bool hw_large_video_support = |
| 228 (cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 58; |
| 229 bool os_large_video_support = true; |
| 230 #if defined(OS_WIN) |
| 231 os_large_video_support = false; |
| 232 #endif |
| 233 return os_large_video_support && hw_large_video_support; |
| 234 } |
| 235 |
220 void GpuVideoDecoder::Initialize(DemuxerStream* stream, | 236 void GpuVideoDecoder::Initialize(DemuxerStream* stream, |
221 const PipelineStatusCB& orig_status_cb, | 237 const PipelineStatusCB& orig_status_cb, |
222 const StatisticsCB& statistics_cb) { | 238 const StatisticsCB& statistics_cb) { |
223 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 239 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 240 DCHECK(stream); |
| 241 |
224 weak_this_ = weak_factory_.GetWeakPtr(); | 242 weak_this_ = weak_factory_.GetWeakPtr(); |
225 | 243 |
226 PipelineStatusCB status_cb = CreateUMAReportingPipelineCB( | 244 PipelineStatusCB status_cb = CreateUMAReportingPipelineCB( |
227 "Media.GpuVideoDecoderInitializeStatus", | 245 "Media.GpuVideoDecoderInitializeStatus", |
228 BindToCurrentLoop(orig_status_cb)); | 246 BindToCurrentLoop(orig_status_cb)); |
229 DCHECK(!demuxer_stream_); | |
230 | 247 |
231 if (!stream) { | 248 if (demuxer_stream_) { |
232 status_cb.Run(PIPELINE_ERROR_DECODE); | 249 // TODO(xhwang): Make GpuVideoDecoder reinitializable. |
| 250 // See http://crbug.com/233608 |
| 251 DVLOG(1) << "GpuVideoDecoder reinitialization not supported."; |
| 252 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
233 return; | 253 return; |
234 } | 254 } |
235 | 255 |
236 // TODO(scherkus): this check should go in Pipeline prior to creating | |
237 // decoder objects. | |
238 const VideoDecoderConfig& config = stream->video_decoder_config(); | 256 const VideoDecoderConfig& config = stream->video_decoder_config(); |
239 if (!config.IsValidConfig() || config.is_encrypted()) { | 257 DCHECK(config.IsValidConfig()); |
240 DLOG(ERROR) << "Unsupported video stream - " | 258 DCHECK(!config.is_encrypted()); |
241 << config.AsHumanReadableString(); | 259 |
242 status_cb.Run(PIPELINE_ERROR_DECODE); | 260 if (!IsCodedSizeSupported(config.coded_size())) { |
| 261 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
243 return; | 262 return; |
244 } | 263 } |
245 | 264 |
246 // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. | |
247 // We test against 1088 to account for 16x16 macroblocks. | |
248 if (config.coded_size().width() > 1920 || | |
249 config.coded_size().height() > 1088) { | |
250 base::CPU cpu; | |
251 bool hw_large_video_support = | |
252 cpu.vendor_name() == "GenuineIntel" && cpu.model() >= 58; | |
253 bool os_large_video_support = true; | |
254 #if defined(OS_WIN) | |
255 os_large_video_support = false; | |
256 #endif | |
257 if (!(os_large_video_support && hw_large_video_support)) { | |
258 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | |
259 return; | |
260 } | |
261 } | |
262 | |
263 client_proxy_ = new VDAClientProxy(this); | 265 client_proxy_ = new VDAClientProxy(this); |
264 VideoDecodeAccelerator* vda = | 266 VideoDecodeAccelerator* vda = |
265 factories_->CreateVideoDecodeAccelerator(config.profile(), client_proxy_); | 267 factories_->CreateVideoDecodeAccelerator(config.profile(), client_proxy_); |
266 if (!vda) { | 268 if (!vda) { |
267 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 269 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
268 return; | 270 return; |
269 } | 271 } |
270 | 272 |
271 if (config.codec() == kCodecH264) | 273 if (config.codec() == kCodecH264) |
272 stream->EnableBitstreamConverter(); | 274 stream->EnableBitstreamConverter(); |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 | 711 |
710 state_ = kError; | 712 state_ = kError; |
711 | 713 |
712 if (!pending_read_cb_.is_null()) { | 714 if (!pending_read_cb_.is_null()) { |
713 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 715 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
714 return; | 716 return; |
715 } | 717 } |
716 } | 718 } |
717 | 719 |
718 } // namespace media | 720 } // namespace media |
OLD | NEW |