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

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

Issue 1490333005: Don't require VDAs to return all PictureBuffers at once. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cl feedback. Created 5 years 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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/trace_event/trace_event.h" 11 #include "base/trace_event/trace_event.h"
12 #include "content/common/gpu/gpu_channel.h" 12 #include "content/common/gpu/gpu_channel.h"
13 #include "content/common/gpu/media/android_copying_backing_strategy.h"
14 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h "
13 #include "content/common/gpu/media/avda_return_on_failure.h" 15 #include "content/common/gpu/media/avda_return_on_failure.h"
14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 16 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
15 #include "media/base/bitstream_buffer.h" 17 #include "media/base/bitstream_buffer.h"
16 #include "media/base/limits.h" 18 #include "media/base/limits.h"
17 #include "media/base/timestamp_constants.h" 19 #include "media/base/timestamp_constants.h"
18 #include "media/base/video_decoder_config.h" 20 #include "media/base/video_decoder_config.h"
19 #include "media/video/picture.h" 21 #include "media/video/picture.h"
20 #include "ui/gl/android/scoped_java_surface.h" 22 #include "ui/gl/android/scoped_java_surface.h"
21 #include "ui/gl/android/surface_texture.h" 23 #include "ui/gl/android/surface_texture.h"
22 #include "ui/gl/gl_bindings.h" 24 #include "ui/gl/gl_bindings.h"
23 25
24 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 26 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
25 #include "media/base/media_keys.h" 27 #include "media/base/media_keys.h"
26 #include "media/mojo/services/mojo_cdm_service.h" 28 #include "media/mojo/services/mojo_cdm_service.h"
27 #endif 29 #endif
28 30
29 namespace content { 31 namespace content {
30 32
33 // TODO(liberato): It is unclear if we have an issue with deadlock during
34 // playback if we lower this. Previously (crbug.com/176036), a deadlock
35 // could occur during preroll. More recent tests have shown some
36 // instability with kNumPictureBuffers==2 with similar symptoms
37 // during playback. crbug.com/531588 .
38 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 };
39
31 // Max number of bitstreams notified to the client with 40 // Max number of bitstreams notified to the client with
32 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. 41 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
33 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; 42 enum { kMaxBitstreamsNotifiedInAdvance = 32 };
34 43
35 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) 44 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID)
36 // MediaCodec is only guaranteed to support baseline, but some devices may 45 // MediaCodec is only guaranteed to support baseline, but some devices may
37 // support others. Advertise support for all H264 profiles and let the 46 // support others. Advertise support for all H264 profiles and let the
38 // MediaCodec fail when decoding if it's not actually supported. It's assumed 47 // MediaCodec fail when decoding if it's not actually supported. It's assumed
39 // that consumers won't have software fallback for H264 on Android anyway. 48 // that consumers won't have software fallback for H264 on Android anyway.
40 static const media::VideoCodecProfile kSupportedH264Profiles[] = { 49 static const media::VideoCodecProfile kSupportedH264Profiles[] = {
41 media::H264PROFILE_BASELINE, 50 media::H264PROFILE_BASELINE,
42 media::H264PROFILE_MAIN, 51 media::H264PROFILE_MAIN,
43 media::H264PROFILE_EXTENDED, 52 media::H264PROFILE_EXTENDED,
44 media::H264PROFILE_HIGH, 53 media::H264PROFILE_HIGH,
45 media::H264PROFILE_HIGH10PROFILE, 54 media::H264PROFILE_HIGH10PROFILE,
46 media::H264PROFILE_HIGH422PROFILE, 55 media::H264PROFILE_HIGH422PROFILE,
47 media::H264PROFILE_HIGH444PREDICTIVEPROFILE, 56 media::H264PROFILE_HIGH444PREDICTIVEPROFILE,
48 media::H264PROFILE_SCALABLEBASELINE, 57 media::H264PROFILE_SCALABLEBASELINE,
49 media::H264PROFILE_SCALABLEHIGH, 58 media::H264PROFILE_SCALABLEHIGH,
50 media::H264PROFILE_STEREOHIGH, 59 media::H264PROFILE_STEREOHIGH,
51 media::H264PROFILE_MULTIVIEWHIGH 60 media::H264PROFILE_MULTIVIEWHIGH
52 }; 61 };
62
63 #define BACKING_STRATEGY AndroidDeferredRenderingBackingStrategy
64 #else
65 #define BACKING_STRATEGY AndroidCopyingBackingStrategy
53 #endif 66 #endif
54 67
55 // Because MediaCodec is thread-hostile (must be poked on a single thread) and 68 // Because MediaCodec is thread-hostile (must be poked on a single thread) and
56 // has no callback mechanism (b/11990118), we must drive it by polling for 69 // has no callback mechanism (b/11990118), we must drive it by polling for
57 // complete frames (and available input buffers, when the codec is fully 70 // complete frames (and available input buffers, when the codec is fully
58 // saturated). This function defines the polling delay. The value used is an 71 // saturated). This function defines the polling delay. The value used is an
59 // arbitrary choice that trades off CPU utilization (spinning) against latency. 72 // arbitrary choice that trades off CPU utilization (spinning) against latency.
60 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay(). 73 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay().
61 static inline const base::TimeDelta DecodePollDelay() { 74 static inline const base::TimeDelta DecodePollDelay() {
62 // An alternative to this polling scheme could be to dedicate a new thread 75 // An alternative to this polling scheme could be to dedicate a new thread
63 // (instead of using the ChildThread) to run the MediaCodec, and make that 76 // (instead of using the ChildThread) to run the MediaCodec, and make that
64 // thread use the timeout-based flavor of MediaCodec's dequeue methods when it 77 // thread use the timeout-based flavor of MediaCodec's dequeue methods when it
65 // believes the codec should complete "soon" (e.g. waiting for an input 78 // believes the codec should complete "soon" (e.g. waiting for an input
66 // buffer, or waiting for a picture when it knows enough complete input 79 // buffer, or waiting for a picture when it knows enough complete input
67 // pictures have been fed to saturate any internal buffering). This is 80 // pictures have been fed to saturate any internal buffering). This is
68 // speculative and it's unclear that this would be a win (nor that there's a 81 // speculative and it's unclear that this would be a win (nor that there's a
69 // reasonably device-agnostic way to fill in the "believes" above). 82 // reasonably device-agnostic way to fill in the "believes" above).
70 return base::TimeDelta::FromMilliseconds(10); 83 return base::TimeDelta::FromMilliseconds(10);
71 } 84 }
72 85
73 static inline const base::TimeDelta NoWaitTimeOut() { 86 static inline const base::TimeDelta NoWaitTimeOut() {
74 return base::TimeDelta::FromMicroseconds(0); 87 return base::TimeDelta::FromMicroseconds(0);
75 } 88 }
76 89
77 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 90 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
78 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, 91 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder,
79 const base::Callback<bool(void)>& make_context_current, 92 const base::Callback<bool(void)>& make_context_current)
80 scoped_ptr<BackingStrategy> strategy)
81 : client_(NULL), 93 : client_(NULL),
82 make_context_current_(make_context_current), 94 make_context_current_(make_context_current),
83 codec_(media::kCodecH264), 95 codec_(media::kCodecH264),
84 is_encrypted_(false), 96 is_encrypted_(false),
85 state_(NO_ERROR), 97 state_(NO_ERROR),
86 picturebuffers_requested_(false), 98 picturebuffers_requested_(false),
87 gl_decoder_(decoder), 99 gl_decoder_(decoder),
88 strategy_(strategy.Pass()), 100 strategy_(new BACKING_STRATEGY()),
89 weak_this_factory_(this) {} 101 weak_this_factory_(this) {}
90 102
91 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 103 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
92 DCHECK(thread_checker_.CalledOnValidThread()); 104 DCHECK(thread_checker_.CalledOnValidThread());
93 } 105 }
94 106
95 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, 107 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config,
96 Client* client) { 108 Client* client) {
97 DCHECK(!media_codec_); 109 DCHECK(!media_codec_);
98 DCHECK(thread_checker_.CalledOnValidThread()); 110 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 439
428 pending_bitstream_buffers_.push( 440 pending_bitstream_buffers_.push(
429 std::make_pair(bitstream_buffer, base::Time::Now())); 441 std::make_pair(bitstream_buffer, base::Time::Now()));
430 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 442 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
431 pending_bitstream_buffers_.size()); 443 pending_bitstream_buffers_.size());
432 444
433 DoIOTask(); 445 DoIOTask();
434 } 446 }
435 447
436 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 448 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
437 client_->ProvidePictureBuffers(strategy_->GetNumPictureBuffers(), size_, 449 client_->ProvidePictureBuffers(kNumPictureBuffers, size_,
438 strategy_->GetTextureTarget()); 450 strategy_->GetTextureTarget());
439 } 451 }
440 452
441 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 453 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
442 const std::vector<media::PictureBuffer>& buffers) { 454 const std::vector<media::PictureBuffer>& buffers) {
443 DCHECK(thread_checker_.CalledOnValidThread()); 455 DCHECK(thread_checker_.CalledOnValidThread());
444 DCHECK(output_picture_buffers_.empty()); 456 DCHECK(output_picture_buffers_.empty());
445 DCHECK(free_picture_ids_.empty()); 457 DCHECK(free_picture_ids_.empty());
446 458
447 for (size_t i = 0; i < buffers.size(); ++i) { 459 for (size_t i = 0; i < buffers.size(); ++i) {
448 RETURN_ON_FAILURE(this, buffers[i].size() == size_, 460 RETURN_ON_FAILURE(this, buffers[i].size() == size_,
449 "Invalid picture buffer size was passed.", 461 "Invalid picture buffer size was passed.",
450 INVALID_ARGUMENT); 462 INVALID_ARGUMENT);
451 int32 id = buffers[i].id(); 463 int32 id = buffers[i].id();
452 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); 464 output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
453 free_picture_ids_.push(id); 465 free_picture_ids_.push(id);
454 // Since the client might be re-using |picture_buffer_id| values, forget 466 // Since the client might be re-using |picture_buffer_id| values, forget
455 // about previously-dismissed IDs now. See ReusePictureBuffer() comment 467 // about previously-dismissed IDs now. See ReusePictureBuffer() comment
456 // about "zombies" for why we maintain this set in the first place. 468 // about "zombies" for why we maintain this set in the first place.
457 dismissed_picture_ids_.erase(id); 469 dismissed_picture_ids_.erase(id);
458 470
459 strategy_->AssignOnePictureBuffer(buffers[i]); 471 strategy_->AssignOnePictureBuffer(buffers[i]);
460 } 472 }
461 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 473 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
462 474
463 RETURN_ON_FAILURE( 475 RETURN_ON_FAILURE(this, output_picture_buffers_.size() >= kNumPictureBuffers,
464 this, output_picture_buffers_.size() >= strategy_->GetNumPictureBuffers(), 476 "Invalid picture buffers were passed.", INVALID_ARGUMENT);
465 "Invalid picture buffers were passed.", INVALID_ARGUMENT);
466 477
467 DoIOTask(); 478 DoIOTask();
468 } 479 }
469 480
470 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( 481 void AndroidVideoDecodeAccelerator::ReusePictureBuffer(
471 int32 picture_buffer_id) { 482 int32 picture_buffer_id) {
472 DCHECK(thread_checker_.CalledOnValidThread()); 483 DCHECK(thread_checker_.CalledOnValidThread());
473 484
474 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in 485 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in
475 // IPC, or in a PostTask either at the sender or receiver) when we sent a 486 // IPC, or in a PostTask either at the sender or receiver) when we sent a
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 638 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
628 client_->NotifyResetDone(); 639 client_->NotifyResetDone();
629 } 640 }
630 641
631 void AndroidVideoDecodeAccelerator::NotifyError( 642 void AndroidVideoDecodeAccelerator::NotifyError(
632 media::VideoDecodeAccelerator::Error error) { 643 media::VideoDecodeAccelerator::Error error) {
633 client_->NotifyError(error); 644 client_->NotifyError(error);
634 } 645 }
635 646
636 // static 647 // static
637 media::VideoDecodeAccelerator::SupportedProfiles 648 media::VideoDecodeAccelerator::Capabilities
638 AndroidVideoDecodeAccelerator::GetSupportedProfiles() { 649 AndroidVideoDecodeAccelerator::GetCapabilities() {
639 SupportedProfiles profiles; 650 Capabilities capabilities;
651 SupportedProfiles& profiles = capabilities.supported_profiles;
640 652
641 if (!media::VideoCodecBridge::IsKnownUnaccelerated( 653 if (!media::VideoCodecBridge::IsKnownUnaccelerated(
642 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { 654 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) {
643 SupportedProfile profile; 655 SupportedProfile profile;
644 profile.profile = media::VP8PROFILE_ANY; 656 profile.profile = media::VP8PROFILE_ANY;
645 profile.min_resolution.SetSize(0, 0); 657 profile.min_resolution.SetSize(0, 0);
646 profile.max_resolution.SetSize(1920, 1088); 658 profile.max_resolution.SetSize(1920, 1088);
647 profiles.push_back(profile); 659 profiles.push_back(profile);
648 } 660 }
649 661
(...skipping 12 matching lines...) Expand all
662 profile.profile = supported_profile; 674 profile.profile = supported_profile;
663 profile.min_resolution.SetSize(0, 0); 675 profile.min_resolution.SetSize(0, 0);
664 // Advertise support for 4k and let the MediaCodec fail when decoding if it 676 // Advertise support for 4k and let the MediaCodec fail when decoding if it
665 // doesn't support the resolution. It's assumed that consumers won't have 677 // doesn't support the resolution. It's assumed that consumers won't have
666 // software fallback for H264 on Android anyway. 678 // software fallback for H264 on Android anyway.
667 profile.max_resolution.SetSize(3840, 2160); 679 profile.max_resolution.SetSize(3840, 2160);
668 profiles.push_back(profile); 680 profiles.push_back(profile);
669 } 681 }
670 #endif 682 #endif
671 683
672 return profiles; 684 capabilities.flags = BACKING_STRATEGY::GetCapabilitiesFlags();
685
686 return capabilities;
673 } 687 }
674 688
675 } // namespace content 689 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698