| 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 |