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 |