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

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

Powered by Google App Engine
This is Rietveld 408576698