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