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 |