| 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/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 case kNormal: | 213 case kNormal: |
| 214 EnsureDemuxOrDecode(); | 214 EnsureDemuxOrDecode(); |
| 215 break; | 215 break; |
| 216 case kDrainingDecoder: | 216 case kDrainingDecoder: |
| 217 // Do nothing. Will be satisfied either by a PictureReady or | 217 // Do nothing. Will be satisfied either by a PictureReady or |
| 218 // NotifyFlushDone below. | 218 // NotifyFlushDone below. |
| 219 break; | 219 break; |
| 220 } | 220 } |
| 221 } | 221 } |
| 222 | 222 |
| 223 bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() { |
| 224 #if defined(OS_WIN) |
| 225 // TODO(ananta): the DXVA decoder stymies our attempt to pipeline Decode()s by |
| 226 // claiming to be done with previous work way too quickly. Until this is |
| 227 // resolved we don't pipeline work. http://crbug.com/150925 |
| 228 return bitstream_buffers_in_decoder_.empty() && !pending_read_cb_.is_null(); |
| 229 #else |
| 230 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes; |
| 231 #endif |
| 232 } |
| 233 |
| 223 void GpuVideoDecoder::RequestBufferDecode( | 234 void GpuVideoDecoder::RequestBufferDecode( |
| 224 DemuxerStream::Status status, | 235 DemuxerStream::Status status, |
| 225 const scoped_refptr<DecoderBuffer>& buffer) { | 236 const scoped_refptr<DecoderBuffer>& buffer) { |
| 226 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status; | 237 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status; |
| 227 | 238 |
| 228 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { | 239 if (!gvd_loop_proxy_->BelongsToCurrentThread()) { |
| 229 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 240 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 230 &GpuVideoDecoder::RequestBufferDecode, this, status, buffer)); | 241 &GpuVideoDecoder::RequestBufferDecode, this, status, buffer)); |
| 231 return; | 242 return; |
| 232 } | 243 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 BitstreamBuffer bitstream_buffer( | 280 BitstreamBuffer bitstream_buffer( |
| 270 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size); | 281 next_bitstream_buffer_id_++, shm_buffer->shm->handle(), size); |
| 271 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( | 282 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( |
| 272 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; | 283 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; |
| 273 DCHECK(inserted); | 284 DCHECK(inserted); |
| 274 RecordBufferData(bitstream_buffer, *buffer); | 285 RecordBufferData(bitstream_buffer, *buffer); |
| 275 | 286 |
| 276 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 287 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 277 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); | 288 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); |
| 278 | 289 |
| 279 if (bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes) | 290 if (CanMoreDecodeWorkBeDone()) |
| 280 EnsureDemuxOrDecode(); | 291 EnsureDemuxOrDecode(); |
| 281 } | 292 } |
| 282 | 293 |
| 283 void GpuVideoDecoder::RecordBufferData( | 294 void GpuVideoDecoder::RecordBufferData( |
| 284 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { | 295 const BitstreamBuffer& bitstream_buffer, const Buffer& buffer) { |
| 285 input_buffer_data_.push_front(BufferData( | 296 input_buffer_data_.push_front(BufferData( |
| 286 bitstream_buffer.id(), buffer.GetTimestamp(), | 297 bitstream_buffer.id(), buffer.GetTimestamp(), |
| 287 demuxer_stream_->video_decoder_config().natural_size())); | 298 demuxer_stream_->video_decoder_config().natural_size())); |
| 288 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but | 299 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but |
| 289 // that's too small for some pathological B-frame test videos. The cost of | 300 // that's too small for some pathological B-frame test videos. The cost of |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 PutSHM(it->second.shm_buffer); | 480 PutSHM(it->second.shm_buffer); |
| 470 const scoped_refptr<DecoderBuffer>& buffer = it->second.buffer; | 481 const scoped_refptr<DecoderBuffer>& buffer = it->second.buffer; |
| 471 if (buffer->GetDataSize()) { | 482 if (buffer->GetDataSize()) { |
| 472 PipelineStatistics statistics; | 483 PipelineStatistics statistics; |
| 473 statistics.video_bytes_decoded = buffer->GetDataSize(); | 484 statistics.video_bytes_decoded = buffer->GetDataSize(); |
| 474 statistics_cb_.Run(statistics); | 485 statistics_cb_.Run(statistics); |
| 475 } | 486 } |
| 476 bitstream_buffers_in_decoder_.erase(it); | 487 bitstream_buffers_in_decoder_.erase(it); |
| 477 | 488 |
| 478 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder && | 489 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder && |
| 479 bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes) { | 490 CanMoreDecodeWorkBeDone()) { |
| 480 EnsureDemuxOrDecode(); | 491 EnsureDemuxOrDecode(); |
| 481 } | 492 } |
| 482 } | 493 } |
| 483 | 494 |
| 484 GpuVideoDecoder::~GpuVideoDecoder() { | 495 GpuVideoDecoder::~GpuVideoDecoder() { |
| 485 DCHECK(!vda_.get()); // Stop should have been already called. | 496 DCHECK(!vda_.get()); // Stop should have been already called. |
| 486 DCHECK(pending_read_cb_.is_null()); | 497 DCHECK(pending_read_cb_.is_null()); |
| 487 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { | 498 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { |
| 488 available_shm_segments_[i]->shm->Close(); | 499 available_shm_segments_[i]->shm->Close(); |
| 489 delete available_shm_segments_[i]; | 500 delete available_shm_segments_[i]; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 | 566 |
| 556 error_occured_ = true; | 567 error_occured_ = true; |
| 557 | 568 |
| 558 if (!pending_read_cb_.is_null()) { | 569 if (!pending_read_cb_.is_null()) { |
| 559 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 570 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 560 return; | 571 return; |
| 561 } | 572 } |
| 562 } | 573 } |
| 563 | 574 |
| 564 } // namespace media | 575 } // namespace media |
| OLD | NEW |