Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 // Repeating timer responsible for draining pending IO to the codecs. | 244 // Repeating timer responsible for draining pending IO to the codecs. |
| 245 base::RepeatingTimer io_timer_; | 245 base::RepeatingTimer io_timer_; |
| 246 | 246 |
| 247 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); | 247 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); |
| 248 }; | 248 }; |
| 249 | 249 |
| 250 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = | 250 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = |
| 251 LAZY_INSTANCE_INITIALIZER; | 251 LAZY_INSTANCE_INITIALIZER; |
| 252 | 252 |
| 253 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 253 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
| 254 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, | 254 const MakeGLContextCurrentCallback& make_context_current_cb, |
| 255 const base::Callback<bool(void)>& make_context_current) | 255 const GetGLES2DecoderCallback& get_gles2_decoder_cb) |
| 256 : client_(NULL), | 256 : client_(NULL), |
| 257 make_context_current_(make_context_current), | 257 make_context_current_cb_(make_context_current_cb), |
| 258 get_gles2_decoder_cb_(get_gles2_decoder_cb), | |
| 258 codec_(media::kCodecH264), | 259 codec_(media::kCodecH264), |
| 259 is_encrypted_(false), | 260 is_encrypted_(false), |
| 260 needs_protected_surface_(false), | 261 needs_protected_surface_(false), |
| 261 state_(NO_ERROR), | 262 state_(NO_ERROR), |
| 262 picturebuffers_requested_(false), | 263 picturebuffers_requested_(false), |
| 263 gl_decoder_(decoder), | |
| 264 media_drm_bridge_cdm_context_(nullptr), | 264 media_drm_bridge_cdm_context_(nullptr), |
| 265 cdm_registration_id_(0), | 265 cdm_registration_id_(0), |
| 266 pending_input_buf_index_(-1), | 266 pending_input_buf_index_(-1), |
| 267 error_sequence_token_(0), | 267 error_sequence_token_(0), |
| 268 defer_errors_(false), | 268 defer_errors_(false), |
| 269 weak_this_factory_(this) { | 269 weak_this_factory_(this) {} |
| 270 const gpu::GpuPreferences& gpu_preferences = | |
| 271 gl_decoder_->GetContextGroup()->gpu_preferences(); | |
| 272 if (UseDeferredRenderingStrategy(gpu_preferences)) { | |
| 273 // TODO(liberato, watk): Figure out what we want to do about zero copy for | |
| 274 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. | |
| 275 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync()); | |
| 276 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; | |
| 277 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); | |
| 278 } else { | |
| 279 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; | |
| 280 strategy_.reset(new AndroidCopyingBackingStrategy(this)); | |
| 281 } | |
| 282 } | |
| 283 | 270 |
| 284 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 271 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 285 DCHECK(thread_checker_.CalledOnValidThread()); | 272 DCHECK(thread_checker_.CalledOnValidThread()); |
| 286 g_avda_timer.Pointer()->StopTimer(this); | 273 g_avda_timer.Pointer()->StopTimer(this); |
| 287 | 274 |
| 288 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 275 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 289 if (!media_drm_bridge_cdm_context_) | 276 if (!media_drm_bridge_cdm_context_) |
| 290 return; | 277 return; |
| 291 | 278 |
| 292 DCHECK(cdm_registration_id_); | 279 DCHECK(cdm_registration_id_); |
| 293 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); | 280 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); |
| 294 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 281 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 295 } | 282 } |
| 296 | 283 |
| 297 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, | 284 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
| 298 Client* client) { | 285 Client* client) { |
| 299 DCHECK(!media_codec_); | 286 DCHECK(!media_codec_); |
| 300 DCHECK(thread_checker_.CalledOnValidThread()); | 287 DCHECK(thread_checker_.CalledOnValidThread()); |
| 301 TRACE_EVENT0("media", "AVDA::Initialize"); | 288 TRACE_EVENT0("media", "AVDA::Initialize"); |
| 302 | 289 |
| 303 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); | 290 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); |
| 304 | 291 |
| 292 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) { | |
| 293 NOTREACHED() << "GL callbacks are required for this VDA"; | |
| 294 return false; | |
| 295 } | |
| 296 | |
| 305 DCHECK(client); | 297 DCHECK(client); |
| 306 client_ = client; | 298 client_ = client; |
| 307 codec_ = VideoCodecProfileToVideoCodec(config.profile); | 299 codec_ = VideoCodecProfileToVideoCodec(config.profile); |
| 308 is_encrypted_ = config.is_encrypted; | 300 is_encrypted_ = config.is_encrypted; |
| 309 | 301 |
| 310 bool profile_supported = codec_ == media::kCodecVP8 || | 302 bool profile_supported = codec_ == media::kCodecVP8 || |
| 311 codec_ == media::kCodecVP9 || | 303 codec_ == media::kCodecVP9 || |
| 312 codec_ == media::kCodecH264; | 304 codec_ == media::kCodecH264; |
| 313 | 305 |
| 314 if (!profile_supported) { | 306 if (!profile_supported) { |
| 315 LOG(ERROR) << "Unsupported profile: " << config.profile; | 307 LOG(ERROR) << "Unsupported profile: " << config.profile; |
| 316 return false; | 308 return false; |
| 317 } | 309 } |
| 318 | 310 |
| 319 // Only use MediaCodec for VP8/9 if it's likely backed by hardware | 311 // Only use MediaCodec for VP8/9 if it's likely backed by hardware |
| 320 // or if the stream is encrypted. | 312 // or if the stream is encrypted. |
| 321 if (codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) { | 313 if (codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) { |
| 322 DCHECK(is_encrypted_ || | 314 DCHECK(is_encrypted_ || |
| 323 !media::VideoCodecBridge::IsKnownUnaccelerated( | 315 !media::VideoCodecBridge::IsKnownUnaccelerated( |
| 324 codec_, media::MEDIA_CODEC_DECODER)); | 316 codec_, media::MEDIA_CODEC_DECODER)); |
| 325 } | 317 } |
| 326 | 318 |
| 327 if (!make_context_current_.Run()) { | 319 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| 320 if (!gles_decoder) { | |
| 321 LOG(ERROR) << "Failed to get gles2 decoder instance."; | |
| 322 return false; | |
| 323 } | |
| 324 | |
| 325 const gpu::GpuPreferences& gpu_preferences = | |
| 326 gles_decoder->GetContextGroup()->gpu_preferences(); | |
| 327 | |
| 328 if (UseDeferredRenderingStrategy(gpu_preferences)) { | |
| 329 // TODO(liberato, watk): Figure out what we want to do about zero copy for | |
| 330 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. | |
| 331 DCHECK(!gles_decoder->GetContextGroup()->mailbox_manager()->UsesSync()); | |
| 332 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; | |
| 333 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); | |
| 334 } else { | |
| 335 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; | |
| 336 strategy_.reset(new AndroidCopyingBackingStrategy(this)); | |
| 337 } | |
| 338 | |
| 339 if (!make_context_current_cb_.Run()) { | |
| 328 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 340 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 329 return false; | 341 return false; |
| 330 } | 342 } |
| 331 | 343 |
| 332 if (!gl_decoder_) { | |
| 333 LOG(ERROR) << "Failed to get gles2 decoder instance."; | |
| 334 return false; | |
| 335 } | |
| 336 | |
| 337 surface_ = strategy_->Initialize(config.surface_id); | 344 surface_ = strategy_->Initialize(config.surface_id); |
| 338 if (surface_.IsEmpty()) { | 345 if (surface_.IsEmpty()) { |
| 339 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " | 346 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " |
| 340 "Java surface is empty."; | 347 "Java surface is empty."; |
| 341 return false; | 348 return false; |
| 342 } | 349 } |
| 343 | 350 |
| 344 // TODO(watk,liberato): move this into the strategy. | 351 // TODO(watk,liberato): move this into the strategy. |
| 345 scoped_refptr<gfx::SurfaceTexture> surface_texture = | 352 scoped_refptr<gfx::SurfaceTexture> surface_texture = |
| 346 strategy_->GetSurfaceTexture(); | 353 strategy_->GetSurfaceTexture(); |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 706 } | 713 } |
| 707 | 714 |
| 708 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( | 715 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( |
| 709 int32_t codec_buffer_index, | 716 int32_t codec_buffer_index, |
| 710 int32_t bitstream_id) { | 717 int32_t bitstream_id) { |
| 711 DCHECK(thread_checker_.CalledOnValidThread()); | 718 DCHECK(thread_checker_.CalledOnValidThread()); |
| 712 DCHECK_NE(bitstream_id, -1); | 719 DCHECK_NE(bitstream_id, -1); |
| 713 DCHECK(!free_picture_ids_.empty()); | 720 DCHECK(!free_picture_ids_.empty()); |
| 714 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); | 721 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); |
| 715 | 722 |
| 716 if (!make_context_current_.Run()) { | 723 if (!make_context_current_cb_.Run()) { |
| 717 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); | 724 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); |
| 718 return; | 725 return; |
| 719 } | 726 } |
| 720 | 727 |
| 721 int32_t picture_buffer_id = free_picture_ids_.front(); | 728 int32_t picture_buffer_id = free_picture_ids_.front(); |
| 722 free_picture_ids_.pop(); | 729 free_picture_ids_.pop(); |
| 723 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 730 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| 724 | 731 |
| 725 const auto& i = output_picture_buffers_.find(picture_buffer_id); | 732 const auto& i = output_picture_buffers_.find(picture_buffer_id); |
| 726 if (i == output_picture_buffers_.end()) { | 733 if (i == output_picture_buffers_.end()) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 795 const std::vector<media::PictureBuffer>& buffers) { | 802 const std::vector<media::PictureBuffer>& buffers) { |
| 796 DCHECK(thread_checker_.CalledOnValidThread()); | 803 DCHECK(thread_checker_.CalledOnValidThread()); |
| 797 DCHECK(output_picture_buffers_.empty()); | 804 DCHECK(output_picture_buffers_.empty()); |
| 798 DCHECK(free_picture_ids_.empty()); | 805 DCHECK(free_picture_ids_.empty()); |
| 799 | 806 |
| 800 if (buffers.size() < kNumPictureBuffers) { | 807 if (buffers.size() < kNumPictureBuffers) { |
| 801 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); | 808 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); |
| 802 return; | 809 return; |
| 803 } | 810 } |
| 804 | 811 |
| 805 const bool have_context = make_context_current_.Run(); | 812 const bool have_context = make_context_current_cb_.Run(); |
| 806 LOG_IF(WARNING, !have_context) | 813 LOG_IF(WARNING, !have_context) |
| 807 << "Failed to make GL context current for Assign, continuing."; | 814 << "Failed to make GL context current for Assign, continuing."; |
| 808 | 815 |
| 809 for (size_t i = 0; i < buffers.size(); ++i) { | 816 for (size_t i = 0; i < buffers.size(); ++i) { |
| 810 if (buffers[i].size() != strategy_->GetPictureBufferSize()) { | 817 if (buffers[i].size() != strategy_->GetPictureBufferSize()) { |
| 811 POST_ERROR(INVALID_ARGUMENT, | 818 POST_ERROR(INVALID_ARGUMENT, |
| 812 "Invalid picture buffer size assigned. Wanted " | 819 "Invalid picture buffer size assigned. Wanted " |
| 813 << size_.ToString() << ", but got " | 820 << size_.ToString() << ", but got " |
| 814 << buffers[i].size().ToString()); | 821 << buffers[i].size().ToString()); |
| 815 return; | 822 return; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 ResetCodecState(); | 989 ResetCodecState(); |
| 983 | 990 |
| 984 base::MessageLoop::current()->PostTask( | 991 base::MessageLoop::current()->PostTask( |
| 985 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 992 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 986 weak_this_factory_.GetWeakPtr())); | 993 weak_this_factory_.GetWeakPtr())); |
| 987 } | 994 } |
| 988 | 995 |
| 989 void AndroidVideoDecodeAccelerator::Destroy() { | 996 void AndroidVideoDecodeAccelerator::Destroy() { |
| 990 DCHECK(thread_checker_.CalledOnValidThread()); | 997 DCHECK(thread_checker_.CalledOnValidThread()); |
| 991 | 998 |
| 992 bool have_context = make_context_current_.Run(); | 999 bool have_context = make_context_current_cb_.Run(); |
| 993 if (!have_context) | 1000 if (!have_context) |
| 994 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; | 1001 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; |
| 995 | 1002 |
| 996 strategy_->Cleanup(have_context, output_picture_buffers_); | 1003 strategy_->Cleanup(have_context, output_picture_buffers_); |
|
liberato (no reviews please)
2016/03/30 16:18:01
since this is no longer initialized in the constru
Pawel Osciak
2016/04/05 10:01:09
Done.
| |
| 997 | 1004 |
| 998 // If we have an OnFrameAvailable handler, tell it that we're going away. | 1005 // If we have an OnFrameAvailable handler, tell it that we're going away. |
| 999 if (on_frame_available_handler_) { | 1006 if (on_frame_available_handler_) { |
| 1000 on_frame_available_handler_->ClearOwner(); | 1007 on_frame_available_handler_->ClearOwner(); |
| 1001 on_frame_available_handler_ = nullptr; | 1008 on_frame_available_handler_ = nullptr; |
| 1002 } | 1009 } |
| 1003 | 1010 |
| 1004 weak_this_factory_.InvalidateWeakPtrs(); | 1011 weak_this_factory_.InvalidateWeakPtrs(); |
| 1005 if (media_codec_) { | 1012 if (media_codec_) { |
| 1006 g_avda_timer.Pointer()->StopTimer(this); | 1013 g_avda_timer.Pointer()->StopTimer(this); |
| 1007 media_codec_.reset(); | 1014 media_codec_.reset(); |
| 1008 } | 1015 } |
| 1009 delete this; | 1016 delete this; |
| 1010 } | 1017 } |
| 1011 | 1018 |
| 1012 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { | 1019 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 1020 const base::WeakPtr<Client>& decode_client, | |
| 1021 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | |
| 1013 return false; | 1022 return false; |
| 1014 } | 1023 } |
| 1015 | 1024 |
| 1016 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { | 1025 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { |
| 1017 return size_; | 1026 return size_; |
| 1018 } | 1027 } |
| 1019 | 1028 |
| 1020 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() | 1029 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() |
| 1021 const { | 1030 const { |
| 1022 return thread_checker_; | 1031 return thread_checker_; |
| 1023 } | 1032 } |
| 1024 | 1033 |
| 1025 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1034 base::WeakPtr<gpu::gles2::GLES2Decoder> |
| 1026 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1035 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
| 1027 return gl_decoder_; | 1036 return get_gles2_decoder_cb_.Run(); |
| 1028 } | 1037 } |
| 1029 | 1038 |
| 1030 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( | 1039 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( |
| 1031 const media::PictureBuffer& picture_buffer) { | 1040 const media::PictureBuffer& picture_buffer) { |
| 1032 RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE, | 1041 auto gles_decoder = GetGlDecoder(); |
| 1033 nullptr); | 1042 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder", |
| 1034 RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(), | 1043 ILLEGAL_STATE, nullptr); |
| 1035 "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE, | 1044 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(), |
| 1045 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE, | |
| 1036 nullptr); | 1046 nullptr); |
| 1037 gpu::gles2::TextureManager* texture_manager = | 1047 gpu::gles2::TextureManager* texture_manager = |
| 1038 gl_decoder_->GetContextGroup()->texture_manager(); | 1048 gles_decoder->GetContextGroup()->texture_manager(); |
| 1039 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", | 1049 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", |
| 1040 ILLEGAL_STATE, nullptr); | 1050 ILLEGAL_STATE, nullptr); |
| 1041 gpu::gles2::TextureRef* texture_ref = | 1051 gpu::gles2::TextureRef* texture_ref = |
| 1042 texture_manager->GetTexture(picture_buffer.internal_texture_id()); | 1052 texture_manager->GetTexture(picture_buffer.internal_texture_id()); |
| 1043 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, | 1053 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, |
| 1044 nullptr); | 1054 nullptr); |
| 1045 | 1055 |
| 1046 return texture_ref; | 1056 return texture_ref; |
| 1047 } | 1057 } |
| 1048 | 1058 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1212 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 1222 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
| 1213 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | | 1223 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | |
| 1214 media::VideoDecodeAccelerator::Capabilities:: | 1224 media::VideoDecodeAccelerator::Capabilities:: |
| 1215 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1225 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1216 } | 1226 } |
| 1217 | 1227 |
| 1218 return capabilities; | 1228 return capabilities; |
| 1219 } | 1229 } |
| 1220 | 1230 |
| 1221 } // namespace content | 1231 } // namespace content |
| OLD | NEW |