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

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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 713 }
707 714
708 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 715 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
709 int32_t codec_buffer_index, 716 int32_t codec_buffer_index,
710 int32_t bitstream_id) { 717 int32_t bitstream_id) {
711 DCHECK(thread_checker_.CalledOnValidThread()); 718 DCHECK(thread_checker_.CalledOnValidThread());
712 DCHECK_NE(bitstream_id, -1); 719 DCHECK_NE(bitstream_id, -1);
713 DCHECK(!free_picture_ids_.empty()); 720 DCHECK(!free_picture_ids_.empty());
714 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); 721 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient");
715 722
716 if (!make_context_current_.Run()) { 723 if (!make_context_current_cb_.Run()) {
717 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 724 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
718 return; 725 return;
719 } 726 }
720 727
721 int32_t picture_buffer_id = free_picture_ids_.front(); 728 int32_t picture_buffer_id = free_picture_ids_.front();
722 free_picture_ids_.pop(); 729 free_picture_ids_.pop();
723 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 730 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
724 731
725 const auto& i = output_picture_buffers_.find(picture_buffer_id); 732 const auto& i = output_picture_buffers_.find(picture_buffer_id);
726 if (i == output_picture_buffers_.end()) { 733 if (i == output_picture_buffers_.end()) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 const std::vector<media::PictureBuffer>& buffers) { 802 const std::vector<media::PictureBuffer>& buffers) {
796 DCHECK(thread_checker_.CalledOnValidThread()); 803 DCHECK(thread_checker_.CalledOnValidThread());
797 DCHECK(output_picture_buffers_.empty()); 804 DCHECK(output_picture_buffers_.empty());
798 DCHECK(free_picture_ids_.empty()); 805 DCHECK(free_picture_ids_.empty());
799 806
800 if (buffers.size() < kNumPictureBuffers) { 807 if (buffers.size() < kNumPictureBuffers) {
801 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 808 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
802 return; 809 return;
803 } 810 }
804 811
805 const bool have_context = make_context_current_.Run(); 812 const bool have_context = make_context_current_cb_.Run();
806 LOG_IF(WARNING, !have_context) 813 LOG_IF(WARNING, !have_context)
807 << "Failed to make GL context current for Assign, continuing."; 814 << "Failed to make GL context current for Assign, continuing.";
808 815
809 for (size_t i = 0; i < buffers.size(); ++i) { 816 for (size_t i = 0; i < buffers.size(); ++i) {
810 if (buffers[i].size() != strategy_->GetPictureBufferSize()) { 817 if (buffers[i].size() != strategy_->GetPictureBufferSize()) {
811 POST_ERROR(INVALID_ARGUMENT, 818 POST_ERROR(INVALID_ARGUMENT,
812 "Invalid picture buffer size assigned. Wanted " 819 "Invalid picture buffer size assigned. Wanted "
813 << size_.ToString() << ", but got " 820 << size_.ToString() << ", but got "
814 << buffers[i].size().ToString()); 821 << buffers[i].size().ToString());
815 return; 822 return;
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 ResetCodecState(); 989 ResetCodecState();
983 990
984 base::MessageLoop::current()->PostTask( 991 base::MessageLoop::current()->PostTask(
985 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 992 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
986 weak_this_factory_.GetWeakPtr())); 993 weak_this_factory_.GetWeakPtr()));
987 } 994 }
988 995
989 void AndroidVideoDecodeAccelerator::Destroy() { 996 void AndroidVideoDecodeAccelerator::Destroy() {
990 DCHECK(thread_checker_.CalledOnValidThread()); 997 DCHECK(thread_checker_.CalledOnValidThread());
991 998
992 bool have_context = make_context_current_.Run(); 999 bool have_context = make_context_current_cb_.Run();
993 if (!have_context) 1000 if (!have_context)
994 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1001 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
995 1002
996 strategy_->Cleanup(have_context, output_picture_buffers_); 1003 strategy_->Cleanup(have_context, output_picture_buffers_);
liberato (no reviews please) 2016/03/30 16:18:01 since this is no longer initialized in the constru
Pawel Osciak 2016/04/05 10:01:09 Done.
997 1004
998 // If we have an OnFrameAvailable handler, tell it that we're going away. 1005 // If we have an OnFrameAvailable handler, tell it that we're going away.
999 if (on_frame_available_handler_) { 1006 if (on_frame_available_handler_) {
1000 on_frame_available_handler_->ClearOwner(); 1007 on_frame_available_handler_->ClearOwner();
1001 on_frame_available_handler_ = nullptr; 1008 on_frame_available_handler_ = nullptr;
1002 } 1009 }
1003 1010
1004 weak_this_factory_.InvalidateWeakPtrs(); 1011 weak_this_factory_.InvalidateWeakPtrs();
1005 if (media_codec_) { 1012 if (media_codec_) {
1006 g_avda_timer.Pointer()->StopTimer(this); 1013 g_avda_timer.Pointer()->StopTimer(this);
1007 media_codec_.reset(); 1014 media_codec_.reset();
1008 } 1015 }
1009 delete this; 1016 delete this;
1010 } 1017 }
1011 1018
1012 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { 1019 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread(
1020 const base::WeakPtr<Client>& decode_client,
1021 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) {
1013 return false; 1022 return false;
1014 } 1023 }
1015 1024
1016 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { 1025 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
1017 return size_; 1026 return size_;
1018 } 1027 }
1019 1028
1020 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 1029 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
1021 const { 1030 const {
1022 return thread_checker_; 1031 return thread_checker_;
1023 } 1032 }
1024 1033
1025 base::WeakPtr<gpu::gles2::GLES2Decoder> 1034 base::WeakPtr<gpu::gles2::GLES2Decoder>
1026 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1035 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1027 return gl_decoder_; 1036 return get_gles2_decoder_cb_.Run();
1028 } 1037 }
1029 1038
1030 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( 1039 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
1031 const media::PictureBuffer& picture_buffer) { 1040 const media::PictureBuffer& picture_buffer) {
1032 RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE, 1041 auto gles_decoder = GetGlDecoder();
1033 nullptr); 1042 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder",
1034 RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(), 1043 ILLEGAL_STATE, nullptr);
1035 "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE, 1044 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(),
1045 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE,
1036 nullptr); 1046 nullptr);
1037 gpu::gles2::TextureManager* texture_manager = 1047 gpu::gles2::TextureManager* texture_manager =
1038 gl_decoder_->GetContextGroup()->texture_manager(); 1048 gles_decoder->GetContextGroup()->texture_manager();
1039 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", 1049 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager",
1040 ILLEGAL_STATE, nullptr); 1050 ILLEGAL_STATE, nullptr);
1041 gpu::gles2::TextureRef* texture_ref = 1051 gpu::gles2::TextureRef* texture_ref =
1042 texture_manager->GetTexture(picture_buffer.internal_texture_id()); 1052 texture_manager->GetTexture(picture_buffer.internal_texture_id());
1043 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, 1053 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE,
1044 nullptr); 1054 nullptr);
1045 1055
1046 return texture_ref; 1056 return texture_ref;
1047 } 1057 }
1048 1058
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1222 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1213 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1223 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1214 media::VideoDecodeAccelerator::Capabilities:: 1224 media::VideoDecodeAccelerator::Capabilities::
1215 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1225 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1216 } 1226 }
1217 1227
1218 return capabilities; 1228 return capabilities;
1219 } 1229 }
1220 1230
1221 } // namespace content 1231 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698