Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 1745903002: Introduce GpuVideoDecodeAcceleratorFactory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Instantiate GVDAFactoryImpl instead of GVDAFactory from content/common Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 // Repeating timer responsible for draining pending IO to the codecs. 246 // Repeating timer responsible for draining pending IO to the codecs.
247 base::RepeatingTimer io_timer_; 247 base::RepeatingTimer io_timer_;
248 248
249 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); 249 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager);
250 }; 250 };
251 251
252 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = 252 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer =
253 LAZY_INSTANCE_INITIALIZER; 253 LAZY_INSTANCE_INITIALIZER;
254 254
255 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 255 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
256 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, 256 const MakeGLContextCurrentCallback& make_context_current_cb,
257 const base::Callback<bool(void)>& make_context_current) 257 const GetGLES2DecoderCallback& get_gles2_decoder_cb)
258 : client_(NULL), 258 : client_(NULL),
259 make_context_current_(make_context_current), 259 make_context_current_cb_(make_context_current_cb),
260 get_gles2_decoder_cb_(get_gles2_decoder_cb),
260 codec_(media::kCodecH264), 261 codec_(media::kCodecH264),
261 is_encrypted_(false), 262 is_encrypted_(false),
262 needs_protected_surface_(false), 263 needs_protected_surface_(false),
263 state_(NO_ERROR), 264 state_(NO_ERROR),
264 picturebuffers_requested_(false), 265 picturebuffers_requested_(false),
265 gl_decoder_(decoder),
266 cdm_registration_id_(0), 266 cdm_registration_id_(0),
267 pending_input_buf_index_(-1), 267 pending_input_buf_index_(-1),
268 error_sequence_token_(0), 268 error_sequence_token_(0),
269 defer_errors_(false), 269 defer_errors_(false),
270 weak_this_factory_(this) { 270 weak_this_factory_(this) {}
271 if (UseDeferredRenderingStrategy()) {
272 // TODO(liberato, watk): Figure out what we want to do about zero copy for
273 // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
274 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync());
275 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
276 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
277 } else {
278 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
279 strategy_.reset(new AndroidCopyingBackingStrategy(this));
280 }
281 }
282 271
283 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 272 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
284 DCHECK(thread_checker_.CalledOnValidThread()); 273 DCHECK(thread_checker_.CalledOnValidThread());
285 g_avda_timer.Pointer()->StopTimer(this); 274 g_avda_timer.Pointer()->StopTimer(this);
286 275
287 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 276 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
288 if (cdm_) { 277 if (cdm_) {
289 DCHECK(cdm_registration_id_); 278 DCHECK(cdm_registration_id_);
290 static_cast<media::MediaDrmBridge*>(cdm_.get()) 279 static_cast<media::MediaDrmBridge*>(cdm_.get())
291 ->UnregisterPlayer(cdm_registration_id_); 280 ->UnregisterPlayer(cdm_registration_id_);
292 } 281 }
293 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 282 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
294 } 283 }
295 284
296 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, 285 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config,
297 Client* client) { 286 Client* client) {
298 DCHECK(!media_codec_); 287 DCHECK(!media_codec_);
299 DCHECK(thread_checker_.CalledOnValidThread()); 288 DCHECK(thread_checker_.CalledOnValidThread());
300 TRACE_EVENT0("media", "AVDA::Initialize"); 289 TRACE_EVENT0("media", "AVDA::Initialize");
301 290
302 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); 291 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString();
303 292
293 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) {
294 NOTREACHED() << "GL callbacks are required for this VDA";
295 return false;
296 }
297
304 DCHECK(client); 298 DCHECK(client);
305 client_ = client; 299 client_ = client;
306 codec_ = VideoCodecProfileToVideoCodec(config.profile); 300 codec_ = VideoCodecProfileToVideoCodec(config.profile);
307 is_encrypted_ = config.is_encrypted; 301 is_encrypted_ = config.is_encrypted;
308 302
309 bool profile_supported = codec_ == media::kCodecVP8 || 303 bool profile_supported = codec_ == media::kCodecVP8 ||
310 codec_ == media::kCodecVP9 || 304 codec_ == media::kCodecVP9 ||
311 codec_ == media::kCodecH264; 305 codec_ == media::kCodecH264;
312 306
313 if (!profile_supported) { 307 if (!profile_supported) {
314 LOG(ERROR) << "Unsupported profile: " << config.profile; 308 LOG(ERROR) << "Unsupported profile: " << config.profile;
315 return false; 309 return false;
316 } 310 }
317 311
318 // Only use MediaCodec for VP8/9 if it's likely backed by hardware 312 // Only use MediaCodec for VP8/9 if it's likely backed by hardware
319 // or if the stream is encrypted. 313 // or if the stream is encrypted.
320 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && 314 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) &&
321 !is_encrypted_) { 315 !is_encrypted_) {
322 if (media::VideoCodecBridge::IsKnownUnaccelerated( 316 if (media::VideoCodecBridge::IsKnownUnaccelerated(
323 codec_, media::MEDIA_CODEC_DECODER)) { 317 codec_, media::MEDIA_CODEC_DECODER)) {
324 DVLOG(1) << "Initialization failed: " 318 DVLOG(1) << "Initialization failed: "
325 << (codec_ == media::kCodecVP8 ? "vp8" : "vp9") 319 << (codec_ == media::kCodecVP8 ? "vp8" : "vp9")
326 << " is not hardware accelerated"; 320 << " is not hardware accelerated";
327 return false; 321 return false;
328 } 322 }
329 } 323 }
330 324
331 if (!make_context_current_.Run()) { 325 if (UseDeferredRenderingStrategy()) {
326 // TODO(liberato, watk): Figure out what we want to do about zero copy for
327 // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
328 auto gles_decoder = get_gles2_decoder_cb_.Run();
329 if (!gles_decoder) {
330 LOG(ERROR) << "Failed to get gles2 decoder instance.";
331 return false;
332 }
333 DCHECK(!gles_decoder->GetContextGroup()->mailbox_manager()->UsesSync());
334 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
335 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
336 } else {
337 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
338 strategy_.reset(new AndroidCopyingBackingStrategy(this));
339 }
340
341 if (!make_context_current_cb_.Run()) {
332 LOG(ERROR) << "Failed to make this decoder's GL context current."; 342 LOG(ERROR) << "Failed to make this decoder's GL context current.";
333 return false; 343 return false;
334 } 344 }
335 345
336 if (!gl_decoder_) {
337 LOG(ERROR) << "Failed to get gles2 decoder instance.";
338 return false;
339 }
340
341 surface_ = strategy_->Initialize(config.surface_id); 346 surface_ = strategy_->Initialize(config.surface_id);
342 if (surface_.IsEmpty()) { 347 if (surface_.IsEmpty()) {
343 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " 348 LOG(ERROR) << "Failed to initialize the backing strategy. The returned "
344 "Java surface is empty."; 349 "Java surface is empty.";
345 return false; 350 return false;
346 } 351 }
347 352
348 // TODO(watk,liberato): move this into the strategy. 353 // TODO(watk,liberato): move this into the strategy.
349 scoped_refptr<gfx::SurfaceTexture> surface_texture = 354 scoped_refptr<gfx::SurfaceTexture> surface_texture =
350 strategy_->GetSurfaceTexture(); 355 strategy_->GetSurfaceTexture();
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 } 716 }
712 717
713 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 718 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
714 int32_t codec_buffer_index, 719 int32_t codec_buffer_index,
715 int32_t bitstream_id) { 720 int32_t bitstream_id) {
716 DCHECK(thread_checker_.CalledOnValidThread()); 721 DCHECK(thread_checker_.CalledOnValidThread());
717 DCHECK_NE(bitstream_id, -1); 722 DCHECK_NE(bitstream_id, -1);
718 DCHECK(!free_picture_ids_.empty()); 723 DCHECK(!free_picture_ids_.empty());
719 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); 724 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient");
720 725
721 if (!make_context_current_.Run()) { 726 if (!make_context_current_cb_.Run()) {
722 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 727 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
723 return; 728 return;
724 } 729 }
725 730
726 int32_t picture_buffer_id = free_picture_ids_.front(); 731 int32_t picture_buffer_id = free_picture_ids_.front();
727 free_picture_ids_.pop(); 732 free_picture_ids_.pop();
728 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 733 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
729 734
730 const auto& i = output_picture_buffers_.find(picture_buffer_id); 735 const auto& i = output_picture_buffers_.find(picture_buffer_id);
731 if (i == output_picture_buffers_.end()) { 736 if (i == output_picture_buffers_.end()) {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 ResetCodecState(); 994 ResetCodecState();
990 995
991 base::MessageLoop::current()->PostTask( 996 base::MessageLoop::current()->PostTask(
992 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 997 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
993 weak_this_factory_.GetWeakPtr())); 998 weak_this_factory_.GetWeakPtr()));
994 } 999 }
995 1000
996 void AndroidVideoDecodeAccelerator::Destroy() { 1001 void AndroidVideoDecodeAccelerator::Destroy() {
997 DCHECK(thread_checker_.CalledOnValidThread()); 1002 DCHECK(thread_checker_.CalledOnValidThread());
998 1003
999 bool have_context = make_context_current_.Run(); 1004 bool have_context = make_context_current_cb_.Run();
1000 if (!have_context) 1005 if (!have_context)
1001 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1006 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
1002 1007
1003 strategy_->Cleanup(have_context, output_picture_buffers_); 1008 strategy_->Cleanup(have_context, output_picture_buffers_);
1004 1009
1005 // If we have an OnFrameAvailable handler, tell it that we're going away. 1010 // If we have an OnFrameAvailable handler, tell it that we're going away.
1006 if (on_frame_available_handler_) { 1011 if (on_frame_available_handler_) {
1007 on_frame_available_handler_->ClearOwner(); 1012 on_frame_available_handler_->ClearOwner();
1008 on_frame_available_handler_ = nullptr; 1013 on_frame_available_handler_ = nullptr;
1009 } 1014 }
1010 1015
1011 weak_this_factory_.InvalidateWeakPtrs(); 1016 weak_this_factory_.InvalidateWeakPtrs();
1012 if (media_codec_) { 1017 if (media_codec_) {
1013 g_avda_timer.Pointer()->StopTimer(this); 1018 g_avda_timer.Pointer()->StopTimer(this);
1014 media_codec_.reset(); 1019 media_codec_.reset();
1015 } 1020 }
1016 delete this; 1021 delete this;
1017 } 1022 }
1018 1023
1019 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { 1024 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1025 const base::WeakPtr<Client>& decode_client,
1026 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1020 return false; 1027 return false;
1021 } 1028 }
1022 1029
1023 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 1030 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
1024 return size_; 1031 return size_;
1025 } 1032 }
1026 1033
1027 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 1034 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
1028 const { 1035 const {
1029 return thread_checker_; 1036 return thread_checker_;
1030 } 1037 }
1031 1038
1032 base::WeakPtr<gpu::gles2::GLES2Decoder> 1039 base::WeakPtr<gpu::gles2::GLES2Decoder>
1033 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1040 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1034 return gl_decoder_; 1041 return get_gles2_decoder_cb_.Run();
1035 } 1042 }
1036 1043
1037 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( 1044 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
1038 const media::PictureBuffer& picture_buffer) { 1045 const media::PictureBuffer& picture_buffer) {
1039 RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE, 1046 auto gles_decoder = GetGlDecoder();
1040 nullptr); 1047 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder",
1041 RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(), 1048 ILLEGAL_STATE, nullptr);
1042 "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE, 1049 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(),
1050 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE,
1043 nullptr); 1051 nullptr);
1044 gpu::gles2::TextureManager* texture_manager = 1052 gpu::gles2::TextureManager* texture_manager =
1045 gl_decoder_->GetContextGroup()->texture_manager(); 1053 gles_decoder->GetContextGroup()->texture_manager();
1046 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", 1054 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager",
1047 ILLEGAL_STATE, nullptr); 1055 ILLEGAL_STATE, nullptr);
1048 gpu::gles2::TextureRef* texture_ref = 1056 gpu::gles2::TextureRef* texture_ref =
1049 texture_manager->GetTexture(picture_buffer.internal_texture_id()); 1057 texture_manager->GetTexture(picture_buffer.internal_texture_id());
1050 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, 1058 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE,
1051 nullptr); 1059 nullptr);
1052 1060
1053 return texture_ref; 1061 return texture_ref;
1054 } 1062 }
1055 1063
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1208 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1201 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1209 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1202 media::VideoDecodeAccelerator::Capabilities:: 1210 media::VideoDecodeAccelerator::Capabilities::
1203 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1211 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1204 } 1212 }
1205 1213
1206 return capabilities; 1214 return capabilities;
1207 } 1215 }
1208 1216
1209 } // namespace content 1217 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698