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 25 matching lines...) Expand all Loading... |
36 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} | 36 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} |
37 | 37 |
38 GpuVideoDecoder::BufferPair::BufferPair( | 38 GpuVideoDecoder::BufferPair::BufferPair( |
39 SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b) | 39 SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b) |
40 : shm_buffer(s), buffer(b) { | 40 : shm_buffer(s), buffer(b) { |
41 } | 41 } |
42 | 42 |
43 GpuVideoDecoder::BufferPair::~BufferPair() {} | 43 GpuVideoDecoder::BufferPair::~BufferPair() {} |
44 | 44 |
45 GpuVideoDecoder::BufferData::BufferData( | 45 GpuVideoDecoder::BufferData::BufferData( |
46 int32 bbid, base::TimeDelta ts, const gfx::Size& ns) | 46 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) |
47 : bitstream_buffer_id(bbid), timestamp(ts), natural_size(ns) { | 47 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), |
| 48 natural_size(ns) { |
48 } | 49 } |
49 | 50 |
50 GpuVideoDecoder::BufferData::~BufferData() {} | 51 GpuVideoDecoder::BufferData::~BufferData() {} |
51 | 52 |
52 GpuVideoDecoder::GpuVideoDecoder( | 53 GpuVideoDecoder::GpuVideoDecoder( |
53 const MessageLoopFactoryCB& message_loop_factory_cb, | 54 const MessageLoopFactoryCB& message_loop_factory_cb, |
54 const scoped_refptr<base::MessageLoopProxy>& vda_loop_proxy, | 55 const scoped_refptr<base::MessageLoopProxy>& vda_loop_proxy, |
55 const scoped_refptr<Factories>& factories) | 56 const scoped_refptr<Factories>& factories) |
56 : message_loop_factory_cb_(message_loop_factory_cb), | 57 : message_loop_factory_cb_(message_loop_factory_cb), |
57 gvd_loop_proxy_(NULL), | 58 gvd_loop_proxy_(NULL), |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); | 323 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); |
323 | 324 |
324 if (CanMoreDecodeWorkBeDone()) | 325 if (CanMoreDecodeWorkBeDone()) |
325 EnsureDemuxOrDecode(); | 326 EnsureDemuxOrDecode(); |
326 } | 327 } |
327 | 328 |
328 void GpuVideoDecoder::RecordBufferData( | 329 void GpuVideoDecoder::RecordBufferData( |
329 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { | 330 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { |
330 input_buffer_data_.push_front(BufferData( | 331 input_buffer_data_.push_front(BufferData( |
331 bitstream_buffer.id(), buffer.GetTimestamp(), | 332 bitstream_buffer.id(), buffer.GetTimestamp(), |
| 333 demuxer_stream_->video_decoder_config().visible_rect(), |
332 demuxer_stream_->video_decoder_config().natural_size())); | 334 demuxer_stream_->video_decoder_config().natural_size())); |
333 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but | 335 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but |
334 // that's too small for some pathological B-frame test videos. The cost of | 336 // that's too small for some pathological B-frame test videos. The cost of |
335 // using too-high a value is low (192 bits per extra slot). | 337 // using too-high a value is low (192 bits per extra slot). |
336 static const size_t kMaxInputBufferDataSize = 128; | 338 static const size_t kMaxInputBufferDataSize = 128; |
337 // Pop from the back of the list, because that's the oldest and least likely | 339 // Pop from the back of the list, because that's the oldest and least likely |
338 // to be useful in the future data. | 340 // to be useful in the future data. |
339 if (input_buffer_data_.size() > kMaxInputBufferDataSize) | 341 if (input_buffer_data_.size() > kMaxInputBufferDataSize) |
340 input_buffer_data_.pop_back(); | 342 input_buffer_data_.pop_back(); |
341 } | 343 } |
342 | 344 |
343 void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp, | 345 void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp, |
| 346 gfx::Rect* visible_rect, |
344 gfx::Size* natural_size) { | 347 gfx::Size* natural_size) { |
345 for (std::list<BufferData>::const_iterator it = | 348 for (std::list<BufferData>::const_iterator it = |
346 input_buffer_data_.begin(); it != input_buffer_data_.end(); | 349 input_buffer_data_.begin(); it != input_buffer_data_.end(); |
347 ++it) { | 350 ++it) { |
348 if (it->bitstream_buffer_id != id) | 351 if (it->bitstream_buffer_id != id) |
349 continue; | 352 continue; |
350 *timestamp = it->timestamp; | 353 *timestamp = it->timestamp; |
| 354 *visible_rect = it->visible_rect; |
351 *natural_size = it->natural_size; | 355 *natural_size = it->natural_size; |
352 return; | 356 return; |
353 } | 357 } |
354 NOTREACHED() << "Missing bitstreambuffer id: " << id; | 358 NOTREACHED() << "Missing bitstreambuffer id: " << id; |
355 } | 359 } |
356 | 360 |
357 bool GpuVideoDecoder::HasAlpha() const { | 361 bool GpuVideoDecoder::HasAlpha() const { |
358 return true; | 362 return true; |
359 } | 363 } |
360 | 364 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); | 426 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); |
423 if (it == picture_buffers_in_decoder_.end()) { | 427 if (it == picture_buffers_in_decoder_.end()) { |
424 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); | 428 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); |
425 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 429 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
426 return; | 430 return; |
427 } | 431 } |
428 const PictureBuffer& pb = it->second; | 432 const PictureBuffer& pb = it->second; |
429 | 433 |
430 // Update frame's timestamp. | 434 // Update frame's timestamp. |
431 base::TimeDelta timestamp; | 435 base::TimeDelta timestamp; |
| 436 gfx::Rect visible_rect; |
432 gfx::Size natural_size; | 437 gfx::Size natural_size; |
433 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &natural_size); | 438 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, |
| 439 &natural_size); |
434 DCHECK(decoder_texture_target_); | 440 DCHECK(decoder_texture_target_); |
435 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( | 441 scoped_refptr<VideoFrame> frame( |
436 pb.texture_id(), decoder_texture_target_, pb.size(), natural_size, | 442 VideoFrame::WrapNativeTexture( |
437 timestamp, | 443 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, |
438 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), | 444 natural_size, timestamp, |
439 decoder_texture_target_, pb.size()), | 445 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), |
440 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, | 446 decoder_texture_target_, pb.size()), |
441 picture.picture_buffer_id()))); | 447 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, |
| 448 picture.picture_buffer_id()))); |
442 | 449 |
443 EnqueueFrameAndTriggerFrameDelivery(frame); | 450 EnqueueFrameAndTriggerFrameDelivery(frame); |
444 } | 451 } |
445 | 452 |
446 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 453 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( |
447 const scoped_refptr<VideoFrame>& frame) { | 454 const scoped_refptr<VideoFrame>& frame) { |
448 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 455 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
449 | 456 |
450 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the | 457 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the |
451 // floor and return. | 458 // floor and return. |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 | 614 |
608 error_occured_ = true; | 615 error_occured_ = true; |
609 | 616 |
610 if (!pending_read_cb_.is_null()) { | 617 if (!pending_read_cb_.is_null()) { |
611 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 618 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
612 return; | 619 return; |
613 } | 620 } |
614 } | 621 } |
615 | 622 |
616 } // namespace media | 623 } // namespace media |
OLD | NEW |