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

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: ...because trybots have feelings too. 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 state_(NO_ERROR), 96 state_(NO_ERROR),
85 picturebuffers_requested_(false), 97 picturebuffers_requested_(false),
86 gl_decoder_(decoder), 98 gl_decoder_(decoder),
87 strategy_(strategy.Pass()), 99 strategy_(new BACKING_STRATEGY()),
88 weak_this_factory_(this) {} 100 weak_this_factory_(this) {}
89 101
90 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 102 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
91 DCHECK(thread_checker_.CalledOnValidThread()); 103 DCHECK(thread_checker_.CalledOnValidThread());
92 } 104 }
93 105
94 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 106 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
95 Client* client) { 107 Client* client) {
96 DCHECK(!media_codec_); 108 DCHECK(!media_codec_);
97 DCHECK(thread_checker_.CalledOnValidThread()); 109 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 434
423 pending_bitstream_buffers_.push( 435 pending_bitstream_buffers_.push(
424 std::make_pair(bitstream_buffer, base::Time::Now())); 436 std::make_pair(bitstream_buffer, base::Time::Now()));
425 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 437 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
426 pending_bitstream_buffers_.size()); 438 pending_bitstream_buffers_.size());
427 439
428 DoIOTask(); 440 DoIOTask();
429 } 441 }
430 442
431 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 443 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
432 client_->ProvidePictureBuffers(strategy_->GetNumPictureBuffers(), size_, 444 client_->ProvidePictureBuffers(kNumPictureBuffers, size_,
433 strategy_->GetTextureTarget()); 445 strategy_->GetTextureTarget());
434 } 446 }
435 447
436 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 448 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
437 const std::vector<media::PictureBuffer>& buffers) { 449 const std::vector<media::PictureBuffer>& buffers) {
438 DCHECK(thread_checker_.CalledOnValidThread()); 450 DCHECK(thread_checker_.CalledOnValidThread());
439 DCHECK(output_picture_buffers_.empty()); 451 DCHECK(output_picture_buffers_.empty());
440 DCHECK(free_picture_ids_.empty()); 452 DCHECK(free_picture_ids_.empty());
441 453
442 for (size_t i = 0; i < buffers.size(); ++i) { 454 for (size_t i = 0; i < buffers.size(); ++i) {
443 RETURN_ON_FAILURE(this, buffers[i].size() == size_, 455 RETURN_ON_FAILURE(this, buffers[i].size() == size_,
444 "Invalid picture buffer size was passed.", 456 "Invalid picture buffer size was passed.",
445 INVALID_ARGUMENT); 457 INVALID_ARGUMENT);
446 int32 id = buffers[i].id(); 458 int32 id = buffers[i].id();
447 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); 459 output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
448 free_picture_ids_.push(id); 460 free_picture_ids_.push(id);
449 // Since the client might be re-using |picture_buffer_id| values, forget 461 // Since the client might be re-using |picture_buffer_id| values, forget
450 // about previously-dismissed IDs now. See ReusePictureBuffer() comment 462 // about previously-dismissed IDs now. See ReusePictureBuffer() comment
451 // about "zombies" for why we maintain this set in the first place. 463 // about "zombies" for why we maintain this set in the first place.
452 dismissed_picture_ids_.erase(id); 464 dismissed_picture_ids_.erase(id);
453 465
454 strategy_->AssignOnePictureBuffer(buffers[i]); 466 strategy_->AssignOnePictureBuffer(buffers[i]);
455 } 467 }
456 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 468 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
457 469
458 RETURN_ON_FAILURE( 470 RETURN_ON_FAILURE(this, output_picture_buffers_.size() >= kNumPictureBuffers,
459 this, output_picture_buffers_.size() >= strategy_->GetNumPictureBuffers(), 471 "Invalid picture buffers were passed.", INVALID_ARGUMENT);
460 "Invalid picture buffers were passed.", INVALID_ARGUMENT);
461 472
462 DoIOTask(); 473 DoIOTask();
463 } 474 }
464 475
465 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( 476 void AndroidVideoDecodeAccelerator::ReusePictureBuffer(
466 int32 picture_buffer_id) { 477 int32 picture_buffer_id) {
467 DCHECK(thread_checker_.CalledOnValidThread()); 478 DCHECK(thread_checker_.CalledOnValidThread());
468 479
469 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in 480 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in
470 // IPC, or in a PostTask either at the sender or receiver) when we sent a 481 // 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
622 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 633 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
623 client_->NotifyResetDone(); 634 client_->NotifyResetDone();
624 } 635 }
625 636
626 void AndroidVideoDecodeAccelerator::NotifyError( 637 void AndroidVideoDecodeAccelerator::NotifyError(
627 media::VideoDecodeAccelerator::Error error) { 638 media::VideoDecodeAccelerator::Error error) {
628 client_->NotifyError(error); 639 client_->NotifyError(error);
629 } 640 }
630 641
631 // static 642 // static
632 media::VideoDecodeAccelerator::SupportedProfiles 643 media::VideoDecodeAccelerator::Capabilities
633 AndroidVideoDecodeAccelerator::GetSupportedProfiles() { 644 AndroidVideoDecodeAccelerator::GetCapabilities() {
634 SupportedProfiles profiles; 645 Capabilities capabilities;
646 SupportedProfiles& profiles = capabilities.supported_profiles;
635 647
636 if (!media::VideoCodecBridge::IsKnownUnaccelerated( 648 if (!media::VideoCodecBridge::IsKnownUnaccelerated(
637 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { 649 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) {
638 SupportedProfile profile; 650 SupportedProfile profile;
639 profile.profile = media::VP8PROFILE_ANY; 651 profile.profile = media::VP8PROFILE_ANY;
640 profile.min_resolution.SetSize(0, 0); 652 profile.min_resolution.SetSize(0, 0);
641 profile.max_resolution.SetSize(1920, 1088); 653 profile.max_resolution.SetSize(1920, 1088);
642 profiles.push_back(profile); 654 profiles.push_back(profile);
643 } 655 }
644 656
(...skipping 12 matching lines...) Expand all
657 profile.profile = supported_profile; 669 profile.profile = supported_profile;
658 profile.min_resolution.SetSize(0, 0); 670 profile.min_resolution.SetSize(0, 0);
659 // Advertise support for 4k and let the MediaCodec fail when decoding if it 671 // Advertise support for 4k and let the MediaCodec fail when decoding if it
660 // doesn't support the resolution. It's assumed that consumers won't have 672 // doesn't support the resolution. It's assumed that consumers won't have
661 // software fallback for H264 on Android anyway. 673 // software fallback for H264 on Android anyway.
662 profile.max_resolution.SetSize(3840, 2160); 674 profile.max_resolution.SetSize(3840, 2160);
663 profiles.push_back(profile); 675 profiles.push_back(profile);
664 } 676 }
665 #endif 677 #endif
666 678
667 return profiles; 679 capabilities.flags = BACKING_STRATEGY::GetCapabilitiesFlags();
680
681 return capabilities;
668 } 682 }
669 683
670 } // namespace content 684 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698