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 <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 222 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
223 requires_texture_copy_ = | 223 requires_texture_copy_ = |
224 !!(capabilities.flags & | 224 !!(capabilities.flags & |
225 VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY); | 225 VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY); |
226 supports_deferred_initialization_ = !!( | 226 supports_deferred_initialization_ = !!( |
227 capabilities.flags & | 227 capabilities.flags & |
228 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION); | 228 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION); |
229 output_cb_ = output_cb; | 229 output_cb_ = output_cb; |
230 | 230 |
231 if (config.is_encrypted() && !supports_deferred_initialization_) { | 231 if (config.is_encrypted() && !supports_deferred_initialization_) { |
232 DVLOG(1) << __FUNCTION__ | 232 DVLOG(1) << __func__ |
233 << " Encrypted stream requires deferred initialialization."; | 233 << " Encrypted stream requires deferred initialialization."; |
234 bound_init_cb.Run(false); | 234 bound_init_cb.Run(false); |
235 return; | 235 return; |
236 } | 236 } |
237 | 237 |
238 if (previously_initialized) { | 238 if (previously_initialized) { |
239 DVLOG(3) << __FUNCTION__ | 239 DVLOG(3) << __func__ |
240 << " Expecting initialized VDA to detect in-stream config change."; | 240 << " Expecting initialized VDA to detect in-stream config change."; |
241 // Reinitialization with a different config (but same codec and profile). | 241 // Reinitialization with a different config (but same codec and profile). |
242 // VDA should handle it by detecting this in-stream by itself, | 242 // VDA should handle it by detecting this in-stream by itself, |
243 // no need to notify it. | 243 // no need to notify it. |
244 bound_init_cb.Run(true); | 244 bound_init_cb.Run(true); |
245 return; | 245 return; |
246 } | 246 } |
247 | 247 |
248 vda_ = factories_->CreateVideoDecodeAccelerator(); | 248 vda_ = factories_->CreateVideoDecodeAccelerator(); |
249 if (!vda_) { | 249 if (!vda_) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 } | 307 } |
308 | 308 |
309 // If deferred initialization is not supported, initialization is complete. | 309 // If deferred initialization is not supported, initialization is complete. |
310 // Otherwise, a call to NotifyInitializationComplete will follow with the | 310 // Otherwise, a call to NotifyInitializationComplete will follow with the |
311 // result of deferred initialization. | 311 // result of deferred initialization. |
312 if (!supports_deferred_initialization_) | 312 if (!supports_deferred_initialization_) |
313 base::ResetAndReturn(&init_cb_).Run(true); | 313 base::ResetAndReturn(&init_cb_).Run(true); |
314 } | 314 } |
315 | 315 |
316 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { | 316 void GpuVideoDecoder::NotifyInitializationComplete(bool success) { |
317 DVLOG_IF(1, !success) << __FUNCTION__ << " Deferred initialization failed."; | 317 DVLOG_IF(1, !success) << __func__ << " Deferred initialization failed."; |
318 DCHECK(!init_cb_.is_null()); | 318 DCHECK(!init_cb_.is_null()); |
319 | 319 |
320 base::ResetAndReturn(&init_cb_).Run(success); | 320 base::ResetAndReturn(&init_cb_).Run(success); |
321 } | 321 } |
322 | 322 |
323 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { | 323 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { |
324 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 324 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
325 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); | 325 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); |
326 ++it) { | 326 ++it) { |
327 for (uint32_t id : it->second.texture_ids()) | 327 for (uint32_t id : it->second.texture_ids()) |
(...skipping 17 matching lines...) Expand all Loading... |
345 assigned_picture_buffers_.erase(it->first); | 345 assigned_picture_buffers_.erase(it->first); |
346 } | 346 } |
347 DestroyPictureBuffers(&assigned_picture_buffers_); | 347 DestroyPictureBuffers(&assigned_picture_buffers_); |
348 } | 348 } |
349 | 349 |
350 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 350 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
351 const DecodeCB& decode_cb) { | 351 const DecodeCB& decode_cb) { |
352 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 352 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
353 DCHECK(pending_reset_cb_.is_null()); | 353 DCHECK(pending_reset_cb_.is_null()); |
354 | 354 |
355 DVLOG(3) << __FUNCTION__ << " " << buffer->AsHumanReadableString(); | 355 DVLOG(3) << __func__ << " " << buffer->AsHumanReadableString(); |
356 | 356 |
357 DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb); | 357 DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb); |
358 | 358 |
359 if (state_ == kError || !vda_) { | 359 if (state_ == kError || !vda_) { |
360 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR); | 360 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR); |
361 return; | 361 return; |
362 } | 362 } |
363 | 363 |
364 switch (state_) { | 364 switch (state_) { |
365 case kDecoderDrained: | 365 case kDecoderDrained: |
366 state_ = kNormal; | 366 state_ = kNormal; |
367 // Fall-through. | 367 // Fall-through. |
368 case kNormal: | 368 case kNormal: |
369 break; | 369 break; |
370 case kDrainingDecoder: | 370 case kDrainingDecoder: |
371 case kError: | 371 case kError: |
372 NOTREACHED(); | 372 NOTREACHED(); |
373 return; | 373 return; |
374 } | 374 } |
375 | 375 |
376 DCHECK_EQ(state_, kNormal); | 376 DCHECK_EQ(state_, kNormal); |
377 | 377 |
378 if (buffer->end_of_stream()) { | 378 if (buffer->end_of_stream()) { |
379 DVLOG(3) << __FUNCTION__ << " Initiating Flush for EOS."; | 379 DVLOG(3) << __func__ << " Initiating Flush for EOS."; |
380 state_ = kDrainingDecoder; | 380 state_ = kDrainingDecoder; |
381 eos_decode_cb_ = bound_decode_cb; | 381 eos_decode_cb_ = bound_decode_cb; |
382 vda_->Flush(); | 382 vda_->Flush(); |
383 return; | 383 return; |
384 } | 384 } |
385 | 385 |
386 size_t size = buffer->data_size(); | 386 size_t size = buffer->data_size(); |
387 std::unique_ptr<SHMBuffer> shm_buffer = GetSHM(size); | 387 std::unique_ptr<SHMBuffer> shm_buffer = GetSHM(size); |
388 if (!shm_buffer) { | 388 if (!shm_buffer) { |
389 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR); | 389 bound_decode_cb.Run(DecodeStatus::DECODE_ERROR); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); | 559 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); |
560 return; | 560 return; |
561 } | 561 } |
562 PictureBuffer& pb = it->second; | 562 PictureBuffer& pb = it->second; |
563 if (picture.size_changed()) { | 563 if (picture.size_changed()) { |
564 // Update the PictureBuffer size to match that of the Picture. Some VDA's | 564 // Update the PictureBuffer size to match that of the Picture. Some VDA's |
565 // (e.g. Android) will handle resolution changes internally without | 565 // (e.g. Android) will handle resolution changes internally without |
566 // requesting new PictureBuffers. Sending a Picture of unmatched size is | 566 // requesting new PictureBuffers. Sending a Picture of unmatched size is |
567 // the signal that we should update the size of our PictureBuffer. | 567 // the signal that we should update the size of our PictureBuffer. |
568 DCHECK(pb.size() != picture.visible_rect().size()); | 568 DCHECK(pb.size() != picture.visible_rect().size()); |
569 DVLOG(3) << __FUNCTION__ << " Updating size of PictureBuffer[" << pb.id() | 569 DVLOG(3) << __func__ << " Updating size of PictureBuffer[" << pb.id() |
570 << "] from:" << pb.size().ToString() | 570 << "] from:" << pb.size().ToString() |
571 << " to:" << picture.visible_rect().size().ToString(); | 571 << " to:" << picture.visible_rect().size().ToString(); |
572 pb.set_size(picture.visible_rect().size()); | 572 pb.set_size(picture.visible_rect().size()); |
573 } | 573 } |
574 | 574 |
575 // Update frame's timestamp. | 575 // Update frame's timestamp. |
576 base::TimeDelta timestamp; | 576 base::TimeDelta timestamp; |
577 // Some of the VDAs like DXVA, and VTVDA don't support and thus don't provide | 577 // Some of the VDAs like DXVA, and VTVDA don't support and thus don't provide |
578 // us with visible size in picture.size, passing (0, 0) instead, so for those | 578 // us with visible size in picture.size, passing (0, 0) instead, so for those |
579 // cases drop it and use config information instead. | 579 // cases drop it and use config information instead. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 return; | 724 return; |
725 } | 725 } |
726 | 726 |
727 PutSHM(base::WrapUnique(it->second.shm_buffer)); | 727 PutSHM(base::WrapUnique(it->second.shm_buffer)); |
728 it->second.done_cb.Run(state_ == kError ? DecodeStatus::DECODE_ERROR | 728 it->second.done_cb.Run(state_ == kError ? DecodeStatus::DECODE_ERROR |
729 : DecodeStatus::OK); | 729 : DecodeStatus::OK); |
730 bitstream_buffers_in_decoder_.erase(it); | 730 bitstream_buffers_in_decoder_.erase(it); |
731 } | 731 } |
732 | 732 |
733 GpuVideoDecoder::~GpuVideoDecoder() { | 733 GpuVideoDecoder::~GpuVideoDecoder() { |
734 DVLOG(3) << __FUNCTION__; | 734 DVLOG(3) << __func__; |
735 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 735 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
736 | 736 |
737 if (vda_) | 737 if (vda_) |
738 DestroyVDA(); | 738 DestroyVDA(); |
739 DCHECK(assigned_picture_buffers_.empty()); | 739 DCHECK(assigned_picture_buffers_.empty()); |
740 | 740 |
741 if (!init_cb_.is_null()) | 741 if (!init_cb_.is_null()) |
742 base::ResetAndReturn(&init_cb_).Run(false); | 742 base::ResetAndReturn(&init_cb_).Run(false); |
743 if (!request_surface_cb_.is_null()) | 743 if (!request_surface_cb_.is_null()) |
744 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB()); | 744 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB()); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 } | 823 } |
824 return false; | 824 return false; |
825 } | 825 } |
826 | 826 |
827 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 827 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
828 const { | 828 const { |
829 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 829 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
830 } | 830 } |
831 | 831 |
832 } // namespace media | 832 } // namespace media |
OLD | NEW |