| 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); | 320 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); |
| 320 | 321 |
| 321 if (CanMoreDecodeWorkBeDone()) | 322 if (CanMoreDecodeWorkBeDone()) |
| 322 EnsureDemuxOrDecode(); | 323 EnsureDemuxOrDecode(); |
| 323 } | 324 } |
| 324 | 325 |
| 325 void GpuVideoDecoder::RecordBufferData( | 326 void GpuVideoDecoder::RecordBufferData( |
| 326 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { | 327 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { |
| 327 input_buffer_data_.push_front(BufferData( | 328 input_buffer_data_.push_front(BufferData( |
| 328 bitstream_buffer.id(), buffer.GetTimestamp(), | 329 bitstream_buffer.id(), buffer.GetTimestamp(), |
| 330 demuxer_stream_->video_decoder_config().visible_rect(), |
| 329 demuxer_stream_->video_decoder_config().natural_size())); | 331 demuxer_stream_->video_decoder_config().natural_size())); |
| 330 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but | 332 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but |
| 331 // that's too small for some pathological B-frame test videos. The cost of | 333 // that's too small for some pathological B-frame test videos. The cost of |
| 332 // using too-high a value is low (192 bits per extra slot). | 334 // using too-high a value is low (192 bits per extra slot). |
| 333 static const size_t kMaxInputBufferDataSize = 128; | 335 static const size_t kMaxInputBufferDataSize = 128; |
| 334 // Pop from the back of the list, because that's the oldest and least likely | 336 // Pop from the back of the list, because that's the oldest and least likely |
| 335 // to be useful in the future data. | 337 // to be useful in the future data. |
| 336 if (input_buffer_data_.size() > kMaxInputBufferDataSize) | 338 if (input_buffer_data_.size() > kMaxInputBufferDataSize) |
| 337 input_buffer_data_.pop_back(); | 339 input_buffer_data_.pop_back(); |
| 338 } | 340 } |
| 339 | 341 |
| 340 void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp, | 342 void GpuVideoDecoder::GetBufferData(int32 id, base::TimeDelta* timestamp, |
| 343 gfx::Rect* visible_rect, |
| 341 gfx::Size* natural_size) { | 344 gfx::Size* natural_size) { |
| 342 for (std::list<BufferData>::const_iterator it = | 345 for (std::list<BufferData>::const_iterator it = |
| 343 input_buffer_data_.begin(); it != input_buffer_data_.end(); | 346 input_buffer_data_.begin(); it != input_buffer_data_.end(); |
| 344 ++it) { | 347 ++it) { |
| 345 if (it->bitstream_buffer_id != id) | 348 if (it->bitstream_buffer_id != id) |
| 346 continue; | 349 continue; |
| 347 *timestamp = it->timestamp; | 350 *timestamp = it->timestamp; |
| 351 *visible_rect = it->visible_rect; |
| 348 *natural_size = it->natural_size; | 352 *natural_size = it->natural_size; |
| 349 return; | 353 return; |
| 350 } | 354 } |
| 351 NOTREACHED() << "Missing bitstreambuffer id: " << id; | 355 NOTREACHED() << "Missing bitstreambuffer id: " << id; |
| 352 } | 356 } |
| 353 | 357 |
| 354 bool GpuVideoDecoder::HasAlpha() const { | 358 bool GpuVideoDecoder::HasAlpha() const { |
| 355 return true; | 359 return true; |
| 356 } | 360 } |
| 357 | 361 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); | 423 picture_buffers_in_decoder_.find(picture.picture_buffer_id()); |
| 420 if (it == picture_buffers_in_decoder_.end()) { | 424 if (it == picture_buffers_in_decoder_.end()) { |
| 421 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); | 425 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); |
| 422 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 426 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
| 423 return; | 427 return; |
| 424 } | 428 } |
| 425 const PictureBuffer& pb = it->second; | 429 const PictureBuffer& pb = it->second; |
| 426 | 430 |
| 427 // Update frame's timestamp. | 431 // Update frame's timestamp. |
| 428 base::TimeDelta timestamp; | 432 base::TimeDelta timestamp; |
| 433 gfx::Rect visible_rect; |
| 429 gfx::Size natural_size; | 434 gfx::Size natural_size; |
| 430 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &natural_size); | 435 GetBufferData(picture.bitstream_buffer_id(), ×tamp, &visible_rect, |
| 436 &natural_size); |
| 431 DCHECK(decoder_texture_target_); | 437 DCHECK(decoder_texture_target_); |
| 432 scoped_refptr<VideoFrame> frame(VideoFrame::WrapNativeTexture( | 438 scoped_refptr<VideoFrame> frame( |
| 433 pb.texture_id(), decoder_texture_target_, pb.size(), natural_size, | 439 VideoFrame::WrapNativeTexture( |
| 434 timestamp, | 440 pb.texture_id(), decoder_texture_target_, pb.size(), visible_rect, |
| 435 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), | 441 natural_size, timestamp, |
| 436 decoder_texture_target_, pb.size()), | 442 base::Bind(&Factories::ReadPixels, factories_, pb.texture_id(), |
| 437 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, | 443 decoder_texture_target_, pb.size()), |
| 438 picture.picture_buffer_id()))); | 444 base::Bind(&GpuVideoDecoder::ReusePictureBuffer, this, |
| 445 picture.picture_buffer_id()))); |
| 439 | 446 |
| 440 EnqueueFrameAndTriggerFrameDelivery(frame); | 447 EnqueueFrameAndTriggerFrameDelivery(frame); |
| 441 } | 448 } |
| 442 | 449 |
| 443 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 450 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( |
| 444 const scoped_refptr<VideoFrame>& frame) { | 451 const scoped_refptr<VideoFrame>& frame) { |
| 445 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 452 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 446 | 453 |
| 447 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the | 454 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the |
| 448 // floor and return. | 455 // floor and return. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 | 608 |
| 602 error_occured_ = true; | 609 error_occured_ = true; |
| 603 | 610 |
| 604 if (!pending_read_cb_.is_null()) { | 611 if (!pending_read_cb_.is_null()) { |
| 605 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 612 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 606 return; | 613 return; |
| 607 } | 614 } |
| 608 } | 615 } |
| 609 | 616 |
| 610 } // namespace media | 617 } // namespace media |
| OLD | NEW |