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

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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 // Repeating timer responsible for draining pending IO to the codecs. 232 // Repeating timer responsible for draining pending IO to the codecs.
233 base::RepeatingTimer io_timer_; 233 base::RepeatingTimer io_timer_;
234 234
235 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); 235 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager);
236 }; 236 };
237 237
238 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = 238 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer =
239 LAZY_INSTANCE_INITIALIZER; 239 LAZY_INSTANCE_INITIALIZER;
240 240
241 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 241 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
242 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, 242 const gpu_vda_helpers::MakeGLContextCurrentCb& make_context_current_cb,
243 const base::Callback<bool(void)>& make_context_current) 243 const gpu_vda_helpers::GetGLES2DecoderCb& get_gles2_decoder_cb)
244 : client_(NULL), 244 : client_(NULL),
245 make_context_current_(make_context_current), 245 make_context_current_cb_(make_context_current_cb),
246 get_gles2_decoder_cb_(get_gles2_decoder_cb),
246 codec_(media::kCodecH264), 247 codec_(media::kCodecH264),
247 is_encrypted_(false), 248 is_encrypted_(false),
248 needs_protected_surface_(false), 249 needs_protected_surface_(false),
249 state_(NO_ERROR), 250 state_(NO_ERROR),
250 picturebuffers_requested_(false), 251 picturebuffers_requested_(false),
251 gl_decoder_(decoder),
252 cdm_registration_id_(0), 252 cdm_registration_id_(0),
253 pending_input_buf_index_(-1), 253 pending_input_buf_index_(-1),
254 error_sequence_token_(0), 254 error_sequence_token_(0),
255 defer_errors_(false), 255 defer_errors_(false),
256 weak_this_factory_(this) { 256 weak_this_factory_(this) {}
257 if (UseDeferredRenderingStrategy()) {
258 // TODO(liberato, watk): Figure out what we want to do about zero copy for
259 // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
260 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync());
261 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
262 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
263 } else {
264 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
265 strategy_.reset(new AndroidCopyingBackingStrategy(this));
266 }
267 }
268 257
269 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 258 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
270 DCHECK(thread_checker_.CalledOnValidThread()); 259 DCHECK(thread_checker_.CalledOnValidThread());
271 g_avda_timer.Pointer()->StopTimer(this); 260 g_avda_timer.Pointer()->StopTimer(this);
272 261
273 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 262 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
274 if (cdm_) { 263 if (cdm_) {
275 DCHECK(cdm_registration_id_); 264 DCHECK(cdm_registration_id_);
276 static_cast<media::MediaDrmBridge*>(cdm_.get()) 265 static_cast<media::MediaDrmBridge*>(cdm_.get())
277 ->UnregisterPlayer(cdm_registration_id_); 266 ->UnregisterPlayer(cdm_registration_id_);
278 } 267 }
279 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 268 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
280 } 269 }
281 270
282 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, 271 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config,
283 Client* client) { 272 Client* client) {
284 DCHECK(!media_codec_); 273 DCHECK(!media_codec_);
285 DCHECK(thread_checker_.CalledOnValidThread()); 274 DCHECK(thread_checker_.CalledOnValidThread());
286 TRACE_EVENT0("media", "AVDA::Initialize"); 275 TRACE_EVENT0("media", "AVDA::Initialize");
287 276
288 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); 277 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString();
289 278
279 if (make_context_current_cb_.is_null() || get_gles2_decoder_cb_.is_null()) {
280 NOTREACHED() << "GL callbacks are required for this VDA";
281 return false;
282 }
283
290 DCHECK(client); 284 DCHECK(client);
291 client_ = client; 285 client_ = client;
292 codec_ = VideoCodecProfileToVideoCodec(config.profile); 286 codec_ = VideoCodecProfileToVideoCodec(config.profile);
293 is_encrypted_ = config.is_encrypted; 287 is_encrypted_ = config.is_encrypted;
294 288
295 bool profile_supported = codec_ == media::kCodecVP8 || 289 bool profile_supported = codec_ == media::kCodecVP8 ||
296 codec_ == media::kCodecVP9 || 290 codec_ == media::kCodecVP9 ||
297 codec_ == media::kCodecH264; 291 codec_ == media::kCodecH264;
298 292
299 if (!profile_supported) { 293 if (!profile_supported) {
300 LOG(ERROR) << "Unsupported profile: " << config.profile; 294 LOG(ERROR) << "Unsupported profile: " << config.profile;
301 return false; 295 return false;
302 } 296 }
303 297
304 // Only use MediaCodec for VP8/9 if it's likely backed by hardware 298 // Only use MediaCodec for VP8/9 if it's likely backed by hardware
305 // or if the stream is encrypted. 299 // or if the stream is encrypted.
306 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && 300 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) &&
307 !is_encrypted_) { 301 !is_encrypted_) {
308 if (media::VideoCodecBridge::IsKnownUnaccelerated( 302 if (media::VideoCodecBridge::IsKnownUnaccelerated(
309 codec_, media::MEDIA_CODEC_DECODER)) { 303 codec_, media::MEDIA_CODEC_DECODER)) {
310 DVLOG(1) << "Initialization failed: " 304 DVLOG(1) << "Initialization failed: "
311 << (codec_ == media::kCodecVP8 ? "vp8" : "vp9") 305 << (codec_ == media::kCodecVP8 ? "vp8" : "vp9")
312 << " is not hardware accelerated"; 306 << " is not hardware accelerated";
313 return false; 307 return false;
314 } 308 }
315 } 309 }
316 310
317 if (!make_context_current_.Run()) { 311 if (UseDeferredRenderingStrategy()) {
312 // TODO(liberato, watk): Figure out what we want to do about zero copy for
313 // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
314 auto gles_decoder = get_gles2_decoder_cb_.Run();
315 if (!gles_decoder) {
316 LOG(ERROR) << "Failed to get gles2 decoder instance.";
317 return false;
318 }
319 DCHECK(!gles_decoder->GetContextGroup()->mailbox_manager()->UsesSync());
320 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
321 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
322 } else {
323 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
324 strategy_.reset(new AndroidCopyingBackingStrategy(this));
325 }
326
327 if (!make_context_current_cb_.Run()) {
318 LOG(ERROR) << "Failed to make this decoder's GL context current."; 328 LOG(ERROR) << "Failed to make this decoder's GL context current.";
319 return false; 329 return false;
320 } 330 }
321 331
322 if (!gl_decoder_) {
323 LOG(ERROR) << "Failed to get gles2 decoder instance.";
324 return false;
325 }
326
327 surface_ = strategy_->Initialize(config.surface_id); 332 surface_ = strategy_->Initialize(config.surface_id);
328 if (surface_.IsEmpty()) { 333 if (surface_.IsEmpty()) {
329 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " 334 LOG(ERROR) << "Failed to initialize the backing strategy. The returned "
330 "Java surface is empty."; 335 "Java surface is empty.";
331 return false; 336 return false;
332 } 337 }
333 338
334 // TODO(watk,liberato): move this into the strategy. 339 // TODO(watk,liberato): move this into the strategy.
335 scoped_refptr<gfx::SurfaceTexture> surface_texture = 340 scoped_refptr<gfx::SurfaceTexture> surface_texture =
336 strategy_->GetSurfaceTexture(); 341 strategy_->GetSurfaceTexture();
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 } 695 }
691 696
692 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 697 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
693 int32_t codec_buffer_index, 698 int32_t codec_buffer_index,
694 int32_t bitstream_id) { 699 int32_t bitstream_id) {
695 DCHECK(thread_checker_.CalledOnValidThread()); 700 DCHECK(thread_checker_.CalledOnValidThread());
696 DCHECK_NE(bitstream_id, -1); 701 DCHECK_NE(bitstream_id, -1);
697 DCHECK(!free_picture_ids_.empty()); 702 DCHECK(!free_picture_ids_.empty());
698 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); 703 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient");
699 704
700 if (!make_context_current_.Run()) { 705 if (!make_context_current_cb_.Run()) {
701 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 706 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
702 return; 707 return;
703 } 708 }
704 709
705 int32_t picture_buffer_id = free_picture_ids_.front(); 710 int32_t picture_buffer_id = free_picture_ids_.front();
706 free_picture_ids_.pop(); 711 free_picture_ids_.pop();
707 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 712 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
708 713
709 OutputBufferMap::const_iterator i = 714 OutputBufferMap::const_iterator i =
710 output_picture_buffers_.find(picture_buffer_id); 715 output_picture_buffers_.find(picture_buffer_id);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 ResetCodecState(); 958 ResetCodecState();
954 959
955 base::MessageLoop::current()->PostTask( 960 base::MessageLoop::current()->PostTask(
956 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 961 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
957 weak_this_factory_.GetWeakPtr())); 962 weak_this_factory_.GetWeakPtr()));
958 } 963 }
959 964
960 void AndroidVideoDecodeAccelerator::Destroy() { 965 void AndroidVideoDecodeAccelerator::Destroy() {
961 DCHECK(thread_checker_.CalledOnValidThread()); 966 DCHECK(thread_checker_.CalledOnValidThread());
962 967
963 bool have_context = make_context_current_.Run(); 968 bool have_context = make_context_current_cb_.Run();
964 if (!have_context) 969 if (!have_context)
965 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 970 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
966 971
967 strategy_->Cleanup(have_context, output_picture_buffers_); 972 strategy_->Cleanup(have_context, output_picture_buffers_);
968 973
969 // If we have an OnFrameAvailable handler, tell it that we're going away. 974 // If we have an OnFrameAvailable handler, tell it that we're going away.
970 if (on_frame_available_handler_) { 975 if (on_frame_available_handler_) {
971 on_frame_available_handler_->ClearOwner(); 976 on_frame_available_handler_->ClearOwner();
972 on_frame_available_handler_ = nullptr; 977 on_frame_available_handler_ = nullptr;
973 } 978 }
974 979
975 weak_this_factory_.InvalidateWeakPtrs(); 980 weak_this_factory_.InvalidateWeakPtrs();
976 if (media_codec_) { 981 if (media_codec_) {
977 g_avda_timer.Pointer()->StopTimer(this); 982 g_avda_timer.Pointer()->StopTimer(this);
978 media_codec_.reset(); 983 media_codec_.reset();
979 } 984 }
980 delete this; 985 delete this;
981 } 986 }
982 987
983 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { 988 bool AndroidVideoDecodeAccelerator::TryInitializeDecodeOnSeparateThread(
989 const base::WeakPtr<Client>& decode_client,
990 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
984 return false; 991 return false;
985 } 992 }
986 993
987 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 994 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
988 return size_; 995 return size_;
989 } 996 }
990 997
991 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 998 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
992 const { 999 const {
993 return thread_checker_; 1000 return thread_checker_;
994 } 1001 }
995 1002
996 base::WeakPtr<gpu::gles2::GLES2Decoder> 1003 base::WeakPtr<gpu::gles2::GLES2Decoder>
997 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1004 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
998 return gl_decoder_; 1005 return get_gles2_decoder_cb_.Run();
999 } 1006 }
1000 1007
1001 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { 1008 void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
1002 // Remember: this may be on any thread. 1009 // Remember: this may be on any thread.
1003 DCHECK(strategy_); 1010 DCHECK(strategy_);
1004 strategy_->OnFrameAvailable(); 1011 strategy_->OnFrameAvailable();
1005 } 1012 }
1006 1013
1007 void AndroidVideoDecodeAccelerator::PostError( 1014 void AndroidVideoDecodeAccelerator::PostError(
1008 const ::tracked_objects::Location& from_here, 1015 const ::tracked_objects::Location& from_here,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1152 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1146 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1153 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1147 media::VideoDecodeAccelerator::Capabilities:: 1154 media::VideoDecodeAccelerator::Capabilities::
1148 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1155 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1149 } 1156 }
1150 1157
1151 return capabilities; 1158 return capabilities;
1152 } 1159 }
1153 1160
1154 } // namespace content 1161 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698