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

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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 } 714 }
708 715
709 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 716 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
710 int32_t codec_buffer_index, 717 int32_t codec_buffer_index,
711 int32_t bitstream_id) { 718 int32_t bitstream_id) {
712 DCHECK(thread_checker_.CalledOnValidThread()); 719 DCHECK(thread_checker_.CalledOnValidThread());
713 DCHECK_NE(bitstream_id, -1); 720 DCHECK_NE(bitstream_id, -1);
714 DCHECK(!free_picture_ids_.empty()); 721 DCHECK(!free_picture_ids_.empty());
715 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); 722 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient");
716 723
717 if (!make_context_current_.Run()) { 724 if (!make_context_current_cb_.Run()) {
718 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 725 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
719 return; 726 return;
720 } 727 }
721 728
722 int32_t picture_buffer_id = free_picture_ids_.front(); 729 int32_t picture_buffer_id = free_picture_ids_.front();
723 free_picture_ids_.pop(); 730 free_picture_ids_.pop();
724 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 731 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
725 732
726 const auto& i = output_picture_buffers_.find(picture_buffer_id); 733 const auto& i = output_picture_buffers_.find(picture_buffer_id);
727 if (i == output_picture_buffers_.end()) { 734 if (i == output_picture_buffers_.end()) {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 ResetCodecState(); 992 ResetCodecState();
986 993
987 base::MessageLoop::current()->PostTask( 994 base::MessageLoop::current()->PostTask(
988 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 995 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
989 weak_this_factory_.GetWeakPtr())); 996 weak_this_factory_.GetWeakPtr()));
990 } 997 }
991 998
992 void AndroidVideoDecodeAccelerator::Destroy() { 999 void AndroidVideoDecodeAccelerator::Destroy() {
993 DCHECK(thread_checker_.CalledOnValidThread()); 1000 DCHECK(thread_checker_.CalledOnValidThread());
994 1001
995 bool have_context = make_context_current_.Run(); 1002 bool have_context = make_context_current_cb_.Run();
996 if (!have_context) 1003 if (!have_context)
997 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1004 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
998 1005
999 strategy_->Cleanup(have_context, output_picture_buffers_); 1006 strategy_->Cleanup(have_context, output_picture_buffers_);
1000 1007
1001 // If we have an OnFrameAvailable handler, tell it that we're going away. 1008 // If we have an OnFrameAvailable handler, tell it that we're going away.
1002 if (on_frame_available_handler_) { 1009 if (on_frame_available_handler_) {
1003 on_frame_available_handler_->ClearOwner(); 1010 on_frame_available_handler_->ClearOwner();
1004 on_frame_available_handler_ = nullptr; 1011 on_frame_available_handler_ = nullptr;
1005 } 1012 }
1006 1013
1007 weak_this_factory_.InvalidateWeakPtrs(); 1014 weak_this_factory_.InvalidateWeakPtrs();
1008 if (media_codec_) { 1015 if (media_codec_) {
1009 g_avda_timer.Pointer()->StopTimer(this); 1016 g_avda_timer.Pointer()->StopTimer(this);
1010 media_codec_.reset(); 1017 media_codec_.reset();
1011 } 1018 }
1012 delete this; 1019 delete this;
1013 } 1020 }
1014 1021
1015 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { 1022 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1023 const base::WeakPtr<Client>& decode_client,
1024 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1016 return false; 1025 return false;
1017 } 1026 }
1018 1027
1019 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 1028 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
1020 return size_; 1029 return size_;
1021 } 1030 }
1022 1031
1023 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 1032 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
1024 const { 1033 const {
1025 return thread_checker_; 1034 return thread_checker_;
1026 } 1035 }
1027 1036
1028 base::WeakPtr<gpu::gles2::GLES2Decoder> 1037 base::WeakPtr<gpu::gles2::GLES2Decoder>
1029 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1038 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1030 return gl_decoder_; 1039 return get_gles2_decoder_cb_.Run();
1031 } 1040 }
1032 1041
1033 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( 1042 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
1034 const media::PictureBuffer& picture_buffer) { 1043 const media::PictureBuffer& picture_buffer) {
1035 RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE, 1044 auto gles_decoder = GetGlDecoder();
1036 nullptr); 1045 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder",
1037 RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(), 1046 ILLEGAL_STATE, nullptr);
1038 "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE, 1047 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(),
1048 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE,
1039 nullptr); 1049 nullptr);
1040 gpu::gles2::TextureManager* texture_manager = 1050 gpu::gles2::TextureManager* texture_manager =
1041 gl_decoder_->GetContextGroup()->texture_manager(); 1051 gles_decoder->GetContextGroup()->texture_manager();
1042 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", 1052 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager",
1043 ILLEGAL_STATE, nullptr); 1053 ILLEGAL_STATE, nullptr);
1044 gpu::gles2::TextureRef* texture_ref = 1054 gpu::gles2::TextureRef* texture_ref =
1045 texture_manager->GetTexture(picture_buffer.internal_texture_id()); 1055 texture_manager->GetTexture(picture_buffer.internal_texture_id());
1046 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, 1056 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE,
1047 nullptr); 1057 nullptr);
1048 1058
1049 return texture_ref; 1059 return texture_ref;
1050 } 1060 }
1051 1061
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1223 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1214 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1224 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1215 media::VideoDecodeAccelerator::Capabilities:: 1225 media::VideoDecodeAccelerator::Capabilities::
1216 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1226 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1217 } 1227 }
1218 1228
1219 return capabilities; 1229 return capabilities;
1220 } 1230 }
1221 1231
1222 } // namespace content 1232 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698