| 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 |