| 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 gvd_loop_proxy_(message_loop), | 165 gvd_loop_proxy_(message_loop), |
| 166 weak_factory_(this), | 166 weak_factory_(this), |
| 167 vda_loop_proxy_(factories->GetMessageLoop()), | 167 vda_loop_proxy_(factories->GetMessageLoop()), |
| 168 factories_(factories), | 168 factories_(factories), |
| 169 state_(kNormal), | 169 state_(kNormal), |
| 170 demuxer_read_in_progress_(false), | 170 demuxer_read_in_progress_(false), |
| 171 decoder_texture_target_(0), | 171 decoder_texture_target_(0), |
| 172 next_picture_buffer_id_(0), | 172 next_picture_buffer_id_(0), |
| 173 next_bitstream_buffer_id_(0), | 173 next_bitstream_buffer_id_(0), |
| 174 available_pictures_(-1) { | 174 available_pictures_(-1) { |
| 175 DCHECK(factories_); | 175 DCHECK(factories_.get()); |
| 176 } | 176 } |
| 177 | 177 |
| 178 void GpuVideoDecoder::Reset(const base::Closure& closure) { | 178 void GpuVideoDecoder::Reset(const base::Closure& closure) { |
| 179 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 179 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 180 | 180 |
| 181 if (state_ == kDrainingDecoder && !factories_->IsAborted()) { | 181 if (state_ == kDrainingDecoder && !factories_->IsAborted()) { |
| 182 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 182 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 183 &GpuVideoDecoder::Reset, weak_this_, closure)); | 183 &GpuVideoDecoder::Reset, weak_this_, closure)); |
| 184 // NOTE: if we're deferring Reset() until a Flush() completes, return | 184 // NOTE: if we're deferring Reset() until a Flush() completes, return |
| 185 // queued pictures to the VDA so they can be used to finish that Flush(). | 185 // queued pictures to the VDA so they can be used to finish that Flush(). |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 const VideoDecoderConfig& config = stream->video_decoder_config(); | 257 const VideoDecoderConfig& config = stream->video_decoder_config(); |
| 258 DCHECK(config.IsValidConfig()); | 258 DCHECK(config.IsValidConfig()); |
| 259 DCHECK(!config.is_encrypted()); | 259 DCHECK(!config.is_encrypted()); |
| 260 | 260 |
| 261 if (!IsCodedSizeSupported(config.coded_size())) { | 261 if (!IsCodedSizeSupported(config.coded_size())) { |
| 262 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 262 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 263 return; | 263 return; |
| 264 } | 264 } |
| 265 | 265 |
| 266 client_proxy_ = new VDAClientProxy(this); | 266 client_proxy_ = new VDAClientProxy(this); |
| 267 VideoDecodeAccelerator* vda = | 267 VideoDecodeAccelerator* vda = factories_->CreateVideoDecodeAccelerator( |
| 268 factories_->CreateVideoDecodeAccelerator(config.profile(), client_proxy_); | 268 config.profile(), client_proxy_.get()); |
| 269 if (!vda) { | 269 if (!vda) { |
| 270 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 270 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 271 return; | 271 return; |
| 272 } | 272 } |
| 273 | 273 |
| 274 demuxer_stream_ = stream; | 274 demuxer_stream_ = stream; |
| 275 statistics_cb_ = statistics_cb; | 275 statistics_cb_ = statistics_cb; |
| 276 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 276 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
| 277 | 277 |
| 278 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; | 278 DVLOG(1) << "GpuVideoDecoder::Initialize() succeeded."; |
| 279 PostTaskAndReplyWithResult( | 279 PostTaskAndReplyWithResult( |
| 280 vda_loop_proxy_, FROM_HERE, | 280 vda_loop_proxy_.get(), |
| 281 FROM_HERE, |
| 281 base::Bind(&VideoDecodeAccelerator::AsWeakPtr, base::Unretained(vda)), | 282 base::Bind(&VideoDecodeAccelerator::AsWeakPtr, base::Unretained(vda)), |
| 282 base::Bind(&GpuVideoDecoder::SetVDA, weak_this_, status_cb, vda)); | 283 base::Bind(&GpuVideoDecoder::SetVDA, weak_this_, status_cb, vda)); |
| 283 } | 284 } |
| 284 | 285 |
| 285 void GpuVideoDecoder::SetVDA( | 286 void GpuVideoDecoder::SetVDA( |
| 286 const PipelineStatusCB& status_cb, | 287 const PipelineStatusCB& status_cb, |
| 287 VideoDecodeAccelerator* vda, | 288 VideoDecodeAccelerator* vda, |
| 288 base::WeakPtr<VideoDecodeAccelerator> weak_vda) { | 289 base::WeakPtr<VideoDecodeAccelerator> weak_vda) { |
| 289 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 290 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 290 DCHECK(!vda_.get()); | 291 DCHECK(!vda_.get()); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 } | 368 } |
| 368 | 369 |
| 369 bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() { | 370 bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() { |
| 370 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes; | 371 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes; |
| 371 } | 372 } |
| 372 | 373 |
| 373 void GpuVideoDecoder::RequestBufferDecode( | 374 void GpuVideoDecoder::RequestBufferDecode( |
| 374 DemuxerStream::Status status, | 375 DemuxerStream::Status status, |
| 375 const scoped_refptr<DecoderBuffer>& buffer) { | 376 const scoped_refptr<DecoderBuffer>& buffer) { |
| 376 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 377 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 377 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status; | 378 DCHECK_EQ(status != DemuxerStream::kOk, !buffer.get()) << status; |
| 378 | 379 |
| 379 demuxer_read_in_progress_ = false; | 380 demuxer_read_in_progress_ = false; |
| 380 | 381 |
| 381 if (status == DemuxerStream::kAborted) { | 382 if (status == DemuxerStream::kAborted) { |
| 382 if (pending_read_cb_.is_null()) | 383 if (pending_read_cb_.is_null()) |
| 383 return; | 384 return; |
| 384 base::ResetAndReturn(&pending_read_cb_).Run(kOk, NULL); | 385 base::ResetAndReturn(&pending_read_cb_).Run(kOk, NULL); |
| 385 return; | 386 return; |
| 386 } | 387 } |
| 387 | 388 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 411 return; | 412 return; |
| 412 | 413 |
| 413 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); | 414 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); |
| 414 BitstreamBuffer bitstream_buffer( | 415 BitstreamBuffer bitstream_buffer( |
| 415 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); | 416 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); |
| 416 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. | 417 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. |
| 417 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; | 418 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; |
| 418 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( | 419 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( |
| 419 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; | 420 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; |
| 420 DCHECK(inserted); | 421 DCHECK(inserted); |
| 421 RecordBufferData(bitstream_buffer, *buffer); | 422 RecordBufferData(bitstream_buffer, *buffer.get()); |
| 422 | 423 |
| 423 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 424 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 424 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); | 425 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); |
| 425 | 426 |
| 426 if (CanMoreDecodeWorkBeDone()) { | 427 if (CanMoreDecodeWorkBeDone()) { |
| 427 // Force post here to prevent reentrancy into DemuxerStream. | 428 // Force post here to prevent reentrancy into DemuxerStream. |
| 428 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 429 gvd_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 429 &GpuVideoDecoder::EnsureDemuxOrDecode, weak_this_)); | 430 &GpuVideoDecoder::EnsureDemuxOrDecode, weak_this_)); |
| 430 } | 431 } |
| 431 } | 432 } |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 | 564 |
| 564 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( | 565 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( |
| 565 const scoped_refptr<VideoFrame>& frame) { | 566 const scoped_refptr<VideoFrame>& frame) { |
| 566 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 567 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 567 | 568 |
| 568 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the | 569 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the |
| 569 // floor and return. | 570 // floor and return. |
| 570 if (!pending_reset_cb_.is_null()) | 571 if (!pending_reset_cb_.is_null()) |
| 571 return; | 572 return; |
| 572 | 573 |
| 573 if (frame) | 574 if (frame.get()) |
| 574 ready_video_frames_.push_back(frame); | 575 ready_video_frames_.push_back(frame); |
| 575 else | 576 else |
| 576 DCHECK(!ready_video_frames_.empty()); | 577 DCHECK(!ready_video_frames_.empty()); |
| 577 | 578 |
| 578 if (pending_read_cb_.is_null()) | 579 if (pending_read_cb_.is_null()) |
| 579 return; | 580 return; |
| 580 | 581 |
| 581 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); | 582 base::ResetAndReturn(&pending_read_cb_).Run(kOk, ready_video_frames_.front()); |
| 582 ready_video_frames_.pop_front(); | 583 ready_video_frames_.pop_front(); |
| 583 } | 584 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 | 707 |
| 707 state_ = kError; | 708 state_ = kError; |
| 708 | 709 |
| 709 if (!pending_read_cb_.is_null()) { | 710 if (!pending_read_cb_.is_null()) { |
| 710 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 711 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 711 return; | 712 return; |
| 712 } | 713 } |
| 713 } | 714 } |
| 714 | 715 |
| 715 } // namespace media | 716 } // namespace media |
| OLD | NEW |