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

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

Issue 1839193003: Reland: Introduce GpuVideoDecodeAcceleratorFactory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 } 709 }
703 710
704 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 711 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
705 int32_t codec_buffer_index, 712 int32_t codec_buffer_index,
706 int32_t bitstream_id) { 713 int32_t bitstream_id) {
707 DCHECK(thread_checker_.CalledOnValidThread()); 714 DCHECK(thread_checker_.CalledOnValidThread());
708 DCHECK_NE(bitstream_id, -1); 715 DCHECK_NE(bitstream_id, -1);
709 DCHECK(!free_picture_ids_.empty()); 716 DCHECK(!free_picture_ids_.empty());
710 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); 717 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient");
711 718
712 if (!make_context_current_.Run()) { 719 if (!make_context_current_cb_.Run()) {
713 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 720 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
714 return; 721 return;
715 } 722 }
716 723
717 int32_t picture_buffer_id = free_picture_ids_.front(); 724 int32_t picture_buffer_id = free_picture_ids_.front();
718 free_picture_ids_.pop(); 725 free_picture_ids_.pop();
719 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 726 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
720 727
721 const auto& i = output_picture_buffers_.find(picture_buffer_id); 728 const auto& i = output_picture_buffers_.find(picture_buffer_id);
722 if (i == output_picture_buffers_.end()) { 729 if (i == output_picture_buffers_.end()) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 const std::vector<media::PictureBuffer>& buffers) { 797 const std::vector<media::PictureBuffer>& buffers) {
791 DCHECK(thread_checker_.CalledOnValidThread()); 798 DCHECK(thread_checker_.CalledOnValidThread());
792 DCHECK(output_picture_buffers_.empty()); 799 DCHECK(output_picture_buffers_.empty());
793 DCHECK(free_picture_ids_.empty()); 800 DCHECK(free_picture_ids_.empty());
794 801
795 if (buffers.size() < kNumPictureBuffers) { 802 if (buffers.size() < kNumPictureBuffers) {
796 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 803 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
797 return; 804 return;
798 } 805 }
799 806
800 const bool have_context = make_context_current_.Run(); 807 const bool have_context = make_context_current_cb_.Run();
801 LOG_IF(WARNING, !have_context) 808 LOG_IF(WARNING, !have_context)
802 << "Failed to make GL context current for Assign, continuing."; 809 << "Failed to make GL context current for Assign, continuing.";
803 810
804 for (size_t i = 0; i < buffers.size(); ++i) { 811 for (size_t i = 0; i < buffers.size(); ++i) {
805 if (buffers[i].size() != strategy_->GetPictureBufferSize()) { 812 if (buffers[i].size() != strategy_->GetPictureBufferSize()) {
806 POST_ERROR(INVALID_ARGUMENT, 813 POST_ERROR(INVALID_ARGUMENT,
807 "Invalid picture buffer size assigned. Wanted " 814 "Invalid picture buffer size assigned. Wanted "
808 << size_.ToString() << ", but got " 815 << size_.ToString() << ", but got "
809 << buffers[i].size().ToString()); 816 << buffers[i].size().ToString());
810 return; 817 return;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 ResetCodecState(); 952 ResetCodecState();
946 953
947 base::MessageLoop::current()->PostTask( 954 base::MessageLoop::current()->PostTask(
948 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 955 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
949 weak_this_factory_.GetWeakPtr())); 956 weak_this_factory_.GetWeakPtr()));
950 } 957 }
951 958
952 void AndroidVideoDecodeAccelerator::Destroy() { 959 void AndroidVideoDecodeAccelerator::Destroy() {
953 DCHECK(thread_checker_.CalledOnValidThread()); 960 DCHECK(thread_checker_.CalledOnValidThread());
954 961
955 bool have_context = make_context_current_.Run(); 962 bool have_context = make_context_current_cb_.Run();
956 if (!have_context) 963 if (!have_context)
957 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 964 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
958 965
959 strategy_->Cleanup(have_context, output_picture_buffers_); 966 if (strategy_)
967 strategy_->Cleanup(have_context, output_picture_buffers_);
960 968
961 // If we have an OnFrameAvailable handler, tell it that we're going away. 969 // If we have an OnFrameAvailable handler, tell it that we're going away.
962 if (on_frame_available_handler_) { 970 if (on_frame_available_handler_) {
963 on_frame_available_handler_->ClearOwner(); 971 on_frame_available_handler_->ClearOwner();
964 on_frame_available_handler_ = nullptr; 972 on_frame_available_handler_ = nullptr;
965 } 973 }
966 974
967 weak_this_factory_.InvalidateWeakPtrs(); 975 weak_this_factory_.InvalidateWeakPtrs();
968 if (media_codec_) { 976 if (media_codec_) {
969 g_avda_timer.Pointer()->StopTimer(this); 977 g_avda_timer.Pointer()->StopTimer(this);
970 media_codec_.reset(); 978 media_codec_.reset();
971 } 979 }
972 delete this; 980 delete this;
973 } 981 }
974 982
975 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { 983 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
984 const base::WeakPtr<Client>& decode_client,
985 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
976 return false; 986 return false;
977 } 987 }
978 988
979 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 989 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
980 return size_; 990 return size_;
981 } 991 }
982 992
983 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 993 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
984 const { 994 const {
985 return thread_checker_; 995 return thread_checker_;
986 } 996 }
987 997
988 base::WeakPtr<gpu::gles2::GLES2Decoder> 998 base::WeakPtr<gpu::gles2::GLES2Decoder>
989 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 999 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
990 return gl_decoder_; 1000 return get_gles2_decoder_cb_.Run();
991 } 1001 }
992 1002
993 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( 1003 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
994 const media::PictureBuffer& picture_buffer) { 1004 const media::PictureBuffer& picture_buffer) {
995 RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE, 1005 auto gles_decoder = GetGlDecoder();
996 nullptr); 1006 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder",
997 RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(), 1007 ILLEGAL_STATE, nullptr);
998 "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE, 1008 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(),
1009 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE,
999 nullptr); 1010 nullptr);
1000 gpu::gles2::TextureManager* texture_manager = 1011 gpu::gles2::TextureManager* texture_manager =
1001 gl_decoder_->GetContextGroup()->texture_manager(); 1012 gles_decoder->GetContextGroup()->texture_manager();
1002 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", 1013 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager",
1003 ILLEGAL_STATE, nullptr); 1014 ILLEGAL_STATE, nullptr);
1004 1015
1005 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size()); 1016 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size());
1006 gpu::gles2::TextureRef* texture_ref = 1017 gpu::gles2::TextureRef* texture_ref =
1007 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]); 1018 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]);
1008 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, 1019 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE,
1009 nullptr); 1020 nullptr);
1010 1021
1011 return texture_ref; 1022 return texture_ref;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1194 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1184 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1195 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1185 media::VideoDecodeAccelerator::Capabilities:: 1196 media::VideoDecodeAccelerator::Capabilities::
1186 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1197 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1187 } 1198 }
1188 1199
1189 return capabilities; 1200 return capabilities;
1190 } 1201 }
1191 1202
1192 } // namespace content 1203 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698