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 MakeGLContextCurrentCallback& make_context_current_cb, | 254 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, |
255 const GetGLES2DecoderCallback& get_gles2_decoder_cb) | 255 const base::Callback<bool(void)>& make_context_current) |
256 : client_(NULL), | 256 : client_(NULL), |
257 make_context_current_cb_(make_context_current_cb), | 257 make_context_current_(make_context_current), |
258 get_gles2_decoder_cb_(get_gles2_decoder_cb), | |
259 codec_(media::kCodecH264), | 258 codec_(media::kCodecH264), |
260 is_encrypted_(false), | 259 is_encrypted_(false), |
261 needs_protected_surface_(false), | 260 needs_protected_surface_(false), |
262 state_(NO_ERROR), | 261 state_(NO_ERROR), |
263 picturebuffers_requested_(false), | 262 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 } |
270 | 283 |
271 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 284 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
272 DCHECK(thread_checker_.CalledOnValidThread()); | 285 DCHECK(thread_checker_.CalledOnValidThread()); |
273 g_avda_timer.Pointer()->StopTimer(this); | 286 g_avda_timer.Pointer()->StopTimer(this); |
274 | 287 |
275 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 288 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
276 if (!media_drm_bridge_cdm_context_) | 289 if (!media_drm_bridge_cdm_context_) |
277 return; | 290 return; |
278 | 291 |
279 DCHECK(cdm_registration_id_); | 292 DCHECK(cdm_registration_id_); |
280 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); | 293 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); |
281 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 294 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
282 } | 295 } |
283 | 296 |
284 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, | 297 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
285 Client* client) { | 298 Client* client) { |
286 DCHECK(!media_codec_); | 299 DCHECK(!media_codec_); |
287 DCHECK(thread_checker_.CalledOnValidThread()); | 300 DCHECK(thread_checker_.CalledOnValidThread()); |
288 TRACE_EVENT0("media", "AVDA::Initialize"); | 301 TRACE_EVENT0("media", "AVDA::Initialize"); |
289 | 302 |
290 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); | 303 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); |
291 | 304 |
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 | |
297 DCHECK(client); | 305 DCHECK(client); |
298 client_ = client; | 306 client_ = client; |
299 codec_ = VideoCodecProfileToVideoCodec(config.profile); | 307 codec_ = VideoCodecProfileToVideoCodec(config.profile); |
300 is_encrypted_ = config.is_encrypted; | 308 is_encrypted_ = config.is_encrypted; |
301 | 309 |
302 bool profile_supported = codec_ == media::kCodecVP8 || | 310 bool profile_supported = codec_ == media::kCodecVP8 || |
303 codec_ == media::kCodecVP9 || | 311 codec_ == media::kCodecVP9 || |
304 codec_ == media::kCodecH264; | 312 codec_ == media::kCodecH264; |
305 | 313 |
306 if (!profile_supported) { | 314 if (!profile_supported) { |
307 LOG(ERROR) << "Unsupported profile: " << config.profile; | 315 LOG(ERROR) << "Unsupported profile: " << config.profile; |
308 return false; | 316 return false; |
309 } | 317 } |
310 | 318 |
311 // Only use MediaCodec for VP8/9 if it's likely backed by hardware | 319 // Only use MediaCodec for VP8/9 if it's likely backed by hardware |
312 // or if the stream is encrypted. | 320 // or if the stream is encrypted. |
313 if (codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) { | 321 if (codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) { |
314 DCHECK(is_encrypted_ || | 322 DCHECK(is_encrypted_ || |
315 !media::VideoCodecBridge::IsKnownUnaccelerated( | 323 !media::VideoCodecBridge::IsKnownUnaccelerated( |
316 codec_, media::MEDIA_CODEC_DECODER)); | 324 codec_, media::MEDIA_CODEC_DECODER)); |
317 } | 325 } |
318 | 326 |
319 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 327 if (!make_context_current_.Run()) { |
320 if (!gles_decoder) { | 328 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 329 return false; |
| 330 } |
| 331 |
| 332 if (!gl_decoder_) { |
321 LOG(ERROR) << "Failed to get gles2 decoder instance."; | 333 LOG(ERROR) << "Failed to get gles2 decoder instance."; |
322 return false; | 334 return false; |
323 } | 335 } |
324 | 336 |
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()) { | |
340 LOG(ERROR) << "Failed to make this decoder's GL context current."; | |
341 return false; | |
342 } | |
343 | |
344 surface_ = strategy_->Initialize(config.surface_id); | 337 surface_ = strategy_->Initialize(config.surface_id); |
345 if (surface_.IsEmpty()) { | 338 if (surface_.IsEmpty()) { |
346 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " | 339 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " |
347 "Java surface is empty."; | 340 "Java surface is empty."; |
348 return false; | 341 return false; |
349 } | 342 } |
350 | 343 |
351 // TODO(watk,liberato): move this into the strategy. | 344 // TODO(watk,liberato): move this into the strategy. |
352 scoped_refptr<gfx::SurfaceTexture> surface_texture = | 345 scoped_refptr<gfx::SurfaceTexture> surface_texture = |
353 strategy_->GetSurfaceTexture(); | 346 strategy_->GetSurfaceTexture(); |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 } | 707 } |
715 | 708 |
716 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( | 709 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( |
717 int32_t codec_buffer_index, | 710 int32_t codec_buffer_index, |
718 int32_t bitstream_id) { | 711 int32_t bitstream_id) { |
719 DCHECK(thread_checker_.CalledOnValidThread()); | 712 DCHECK(thread_checker_.CalledOnValidThread()); |
720 DCHECK_NE(bitstream_id, -1); | 713 DCHECK_NE(bitstream_id, -1); |
721 DCHECK(!free_picture_ids_.empty()); | 714 DCHECK(!free_picture_ids_.empty()); |
722 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); | 715 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); |
723 | 716 |
724 if (!make_context_current_cb_.Run()) { | 717 if (!make_context_current_.Run()) { |
725 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); | 718 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); |
726 return; | 719 return; |
727 } | 720 } |
728 | 721 |
729 int32_t picture_buffer_id = free_picture_ids_.front(); | 722 int32_t picture_buffer_id = free_picture_ids_.front(); |
730 free_picture_ids_.pop(); | 723 free_picture_ids_.pop(); |
731 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 724 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
732 | 725 |
733 const auto& i = output_picture_buffers_.find(picture_buffer_id); | 726 const auto& i = output_picture_buffers_.find(picture_buffer_id); |
734 if (i == output_picture_buffers_.end()) { | 727 if (i == output_picture_buffers_.end()) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 ResetCodecState(); | 985 ResetCodecState(); |
993 | 986 |
994 base::MessageLoop::current()->PostTask( | 987 base::MessageLoop::current()->PostTask( |
995 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 988 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
996 weak_this_factory_.GetWeakPtr())); | 989 weak_this_factory_.GetWeakPtr())); |
997 } | 990 } |
998 | 991 |
999 void AndroidVideoDecodeAccelerator::Destroy() { | 992 void AndroidVideoDecodeAccelerator::Destroy() { |
1000 DCHECK(thread_checker_.CalledOnValidThread()); | 993 DCHECK(thread_checker_.CalledOnValidThread()); |
1001 | 994 |
1002 bool have_context = make_context_current_cb_.Run(); | 995 bool have_context = make_context_current_.Run(); |
1003 if (!have_context) | 996 if (!have_context) |
1004 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; | 997 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; |
1005 | 998 |
1006 strategy_->Cleanup(have_context, output_picture_buffers_); | 999 strategy_->Cleanup(have_context, output_picture_buffers_); |
1007 | 1000 |
1008 // If we have an OnFrameAvailable handler, tell it that we're going away. | 1001 // If we have an OnFrameAvailable handler, tell it that we're going away. |
1009 if (on_frame_available_handler_) { | 1002 if (on_frame_available_handler_) { |
1010 on_frame_available_handler_->ClearOwner(); | 1003 on_frame_available_handler_->ClearOwner(); |
1011 on_frame_available_handler_ = nullptr; | 1004 on_frame_available_handler_ = nullptr; |
1012 } | 1005 } |
1013 | 1006 |
1014 weak_this_factory_.InvalidateWeakPtrs(); | 1007 weak_this_factory_.InvalidateWeakPtrs(); |
1015 if (media_codec_) { | 1008 if (media_codec_) { |
1016 g_avda_timer.Pointer()->StopTimer(this); | 1009 g_avda_timer.Pointer()->StopTimer(this); |
1017 media_codec_.reset(); | 1010 media_codec_.reset(); |
1018 } | 1011 } |
1019 delete this; | 1012 delete this; |
1020 } | 1013 } |
1021 | 1014 |
1022 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1015 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { |
1023 const base::WeakPtr<Client>& decode_client, | |
1024 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | |
1025 return false; | 1016 return false; |
1026 } | 1017 } |
1027 | 1018 |
1028 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { | 1019 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { |
1029 return size_; | 1020 return size_; |
1030 } | 1021 } |
1031 | 1022 |
1032 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() | 1023 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() |
1033 const { | 1024 const { |
1034 return thread_checker_; | 1025 return thread_checker_; |
1035 } | 1026 } |
1036 | 1027 |
1037 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1028 base::WeakPtr<gpu::gles2::GLES2Decoder> |
1038 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1029 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
1039 return get_gles2_decoder_cb_.Run(); | 1030 return gl_decoder_; |
1040 } | 1031 } |
1041 | 1032 |
1042 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( | 1033 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( |
1043 const media::PictureBuffer& picture_buffer) { | 1034 const media::PictureBuffer& picture_buffer) { |
1044 auto gles_decoder = GetGlDecoder(); | 1035 RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE, |
1045 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder", | 1036 nullptr); |
1046 ILLEGAL_STATE, nullptr); | 1037 RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(), |
1047 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(), | 1038 "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE, |
1048 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE, | |
1049 nullptr); | 1039 nullptr); |
1050 gpu::gles2::TextureManager* texture_manager = | 1040 gpu::gles2::TextureManager* texture_manager = |
1051 gles_decoder->GetContextGroup()->texture_manager(); | 1041 gl_decoder_->GetContextGroup()->texture_manager(); |
1052 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", | 1042 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", |
1053 ILLEGAL_STATE, nullptr); | 1043 ILLEGAL_STATE, nullptr); |
1054 gpu::gles2::TextureRef* texture_ref = | 1044 gpu::gles2::TextureRef* texture_ref = |
1055 texture_manager->GetTexture(picture_buffer.internal_texture_id()); | 1045 texture_manager->GetTexture(picture_buffer.internal_texture_id()); |
1056 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, | 1046 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, |
1057 nullptr); | 1047 nullptr); |
1058 | 1048 |
1059 return texture_ref; | 1049 return texture_ref; |
1060 } | 1050 } |
1061 | 1051 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 1213 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
1224 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | | 1214 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | |
1225 media::VideoDecodeAccelerator::Capabilities:: | 1215 media::VideoDecodeAccelerator::Capabilities:: |
1226 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1216 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
1227 } | 1217 } |
1228 | 1218 |
1229 return capabilities; | 1219 return capabilities; |
1230 } | 1220 } |
1231 | 1221 |
1232 } // namespace content | 1222 } // namespace content |
OLD | NEW |