OLD | NEW |
---|---|
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" |
(...skipping 23 matching lines...) Expand all Loading... | |
34 // playback if we lower this. Previously (crbug.com/176036), a deadlock | 34 // playback if we lower this. Previously (crbug.com/176036), a deadlock |
35 // could occur during preroll. More recent tests have shown some | 35 // could occur during preroll. More recent tests have shown some |
36 // instability with kNumPictureBuffers==2 with similar symptoms | 36 // instability with kNumPictureBuffers==2 with similar symptoms |
37 // during playback. crbug.com/531588 . | 37 // during playback. crbug.com/531588 . |
38 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; | 38 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; |
39 | 39 |
40 // Max number of bitstreams notified to the client with | 40 // Max number of bitstreams notified to the client with |
41 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. | 41 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. |
42 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; | 42 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; |
43 | 43 |
44 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | |
45 // MediaCodec is only guaranteed to support baseline, but some devices may | 44 // MediaCodec is only guaranteed to support baseline, but some devices may |
46 // support others. Advertise support for all H264 profiles and let the | 45 // support others. Advertise support for all H264 profiles and let the |
47 // MediaCodec fail when decoding if it's not actually supported. It's assumed | 46 // MediaCodec fail when decoding if it's not actually supported. It's assumed |
48 // that consumers won't have software fallback for H264 on Android anyway. | 47 // that consumers won't have software fallback for H264 on Android anyway. |
49 static const media::VideoCodecProfile kSupportedH264Profiles[] = { | 48 static const media::VideoCodecProfile kSupportedH264Profiles[] = { |
50 media::H264PROFILE_BASELINE, | 49 media::H264PROFILE_BASELINE, |
51 media::H264PROFILE_MAIN, | 50 media::H264PROFILE_MAIN, |
52 media::H264PROFILE_EXTENDED, | 51 media::H264PROFILE_EXTENDED, |
53 media::H264PROFILE_HIGH, | 52 media::H264PROFILE_HIGH, |
54 media::H264PROFILE_HIGH10PROFILE, | 53 media::H264PROFILE_HIGH10PROFILE, |
55 media::H264PROFILE_HIGH422PROFILE, | 54 media::H264PROFILE_HIGH422PROFILE, |
56 media::H264PROFILE_HIGH444PREDICTIVEPROFILE, | 55 media::H264PROFILE_HIGH444PREDICTIVEPROFILE, |
57 media::H264PROFILE_SCALABLEBASELINE, | 56 media::H264PROFILE_SCALABLEBASELINE, |
58 media::H264PROFILE_SCALABLEHIGH, | 57 media::H264PROFILE_SCALABLEHIGH, |
59 media::H264PROFILE_STEREOHIGH, | 58 media::H264PROFILE_STEREOHIGH, |
60 media::H264PROFILE_MULTIVIEWHIGH | 59 media::H264PROFILE_MULTIVIEWHIGH |
61 }; | 60 }; |
62 | 61 |
63 #define BACKING_STRATEGY AndroidDeferredRenderingBackingStrategy | |
64 #else | |
65 #define BACKING_STRATEGY AndroidCopyingBackingStrategy | |
66 #endif | |
67 | |
68 // Because MediaCodec is thread-hostile (must be poked on a single thread) and | 62 // Because MediaCodec is thread-hostile (must be poked on a single thread) and |
69 // has no callback mechanism (b/11990118), we must drive it by polling for | 63 // has no callback mechanism (b/11990118), we must drive it by polling for |
70 // complete frames (and available input buffers, when the codec is fully | 64 // complete frames (and available input buffers, when the codec is fully |
71 // saturated). This function defines the polling delay. The value used is an | 65 // saturated). This function defines the polling delay. The value used is an |
72 // arbitrary choice that trades off CPU utilization (spinning) against latency. | 66 // arbitrary choice that trades off CPU utilization (spinning) against latency. |
73 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay(). | 67 // Mirrors android_video_encode_accelerator.cc:EncodePollDelay(). |
74 static inline const base::TimeDelta DecodePollDelay() { | 68 static inline const base::TimeDelta DecodePollDelay() { |
75 // An alternative to this polling scheme could be to dedicate a new thread | 69 // An alternative to this polling scheme could be to dedicate a new thread |
76 // (instead of using the ChildThread) to run the MediaCodec, and make that | 70 // (instead of using the ChildThread) to run the MediaCodec, and make that |
77 // thread use the timeout-based flavor of MediaCodec's dequeue methods when it | 71 // thread use the timeout-based flavor of MediaCodec's dequeue methods when it |
(...skipping 12 matching lines...) Expand all Loading... | |
90 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 84 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
91 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, | 85 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, |
92 const base::Callback<bool(void)>& make_context_current) | 86 const base::Callback<bool(void)>& make_context_current) |
93 : client_(NULL), | 87 : client_(NULL), |
94 make_context_current_(make_context_current), | 88 make_context_current_(make_context_current), |
95 codec_(media::kCodecH264), | 89 codec_(media::kCodecH264), |
96 is_encrypted_(false), | 90 is_encrypted_(false), |
97 state_(NO_ERROR), | 91 state_(NO_ERROR), |
98 picturebuffers_requested_(false), | 92 picturebuffers_requested_(false), |
99 gl_decoder_(decoder), | 93 gl_decoder_(decoder), |
100 strategy_(new BACKING_STRATEGY()), | 94 // TODO(liberato): This should be based on the command line flags present |
DaleCurtis
2015/12/16 00:06:40
liberato@, approved your CL here: https://coderevi
DaleCurtis
2015/12/17 01:50:48
Rebased on Frank's changes.
| |
95 // until we can make it work for WebRTC as well. | |
96 strategy_(new AndroidCopyingBackingStrategy()), | |
101 weak_this_factory_(this) {} | 97 weak_this_factory_(this) {} |
102 | 98 |
103 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 99 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
104 DCHECK(thread_checker_.CalledOnValidThread()); | 100 DCHECK(thread_checker_.CalledOnValidThread()); |
105 } | 101 } |
106 | 102 |
107 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, | 103 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
108 Client* client) { | 104 Client* client) { |
109 DCHECK(!media_codec_); | 105 DCHECK(!media_codec_); |
110 DCHECK(thread_checker_.CalledOnValidThread()); | 106 DCHECK(thread_checker_.CalledOnValidThread()); |
111 TRACE_EVENT0("media", "AVDA::Initialize"); | 107 TRACE_EVENT0("media", "AVDA::Initialize"); |
112 | 108 |
113 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile | 109 DVLOG(1) << __FUNCTION__ << ": profile:" << config.profile |
114 << " is_encrypted:" << config.is_encrypted; | 110 << " is_encrypted:" << config.is_encrypted; |
115 | 111 |
116 client_ = client; | 112 client_ = client; |
117 codec_ = VideoCodecProfileToVideoCodec(config.profile); | 113 codec_ = VideoCodecProfileToVideoCodec(config.profile); |
118 is_encrypted_ = config.is_encrypted; | 114 is_encrypted_ = config.is_encrypted; |
119 | 115 |
120 bool profile_supported = codec_ == media::kCodecVP8; | 116 bool profile_supported = codec_ == media::kCodecVP8 || |
121 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | 117 codec_ == media::kCodecVP9 || |
122 profile_supported |= | 118 codec_ == media::kCodecH264; |
123 (codec_ == media::kCodecVP9 || codec_ == media::kCodecH264); | |
124 #endif | |
125 | 119 |
126 if (!profile_supported) { | 120 if (!profile_supported) { |
127 LOG(ERROR) << "Unsupported profile: " << config.profile; | 121 LOG(ERROR) << "Unsupported profile: " << config.profile; |
128 return false; | 122 return false; |
129 } | 123 } |
130 | 124 |
131 // Only use MediaCodec for VP8/9 if it's likely backed by hardware. | 125 // Only use MediaCodec for VP8/9 if it's likely backed by hardware. |
132 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && | 126 if ((codec_ == media::kCodecVP8 || codec_ == media::kCodecVP9) && |
133 media::VideoCodecBridge::IsKnownUnaccelerated( | 127 media::VideoCodecBridge::IsKnownUnaccelerated( |
134 codec_, media::MEDIA_CODEC_DECODER)) { | 128 codec_, media::MEDIA_CODEC_DECODER)) { |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
652 | 646 |
653 if (!media::VideoCodecBridge::IsKnownUnaccelerated( | 647 if (!media::VideoCodecBridge::IsKnownUnaccelerated( |
654 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { | 648 media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { |
655 SupportedProfile profile; | 649 SupportedProfile profile; |
656 profile.profile = media::VP8PROFILE_ANY; | 650 profile.profile = media::VP8PROFILE_ANY; |
657 profile.min_resolution.SetSize(0, 0); | 651 profile.min_resolution.SetSize(0, 0); |
658 profile.max_resolution.SetSize(1920, 1088); | 652 profile.max_resolution.SetSize(1920, 1088); |
659 profiles.push_back(profile); | 653 profiles.push_back(profile); |
660 } | 654 } |
661 | 655 |
662 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) | |
663 if (!media::VideoCodecBridge::IsKnownUnaccelerated( | 656 if (!media::VideoCodecBridge::IsKnownUnaccelerated( |
664 media::kCodecVP9, media::MEDIA_CODEC_DECODER)) { | 657 media::kCodecVP9, media::MEDIA_CODEC_DECODER)) { |
665 SupportedProfile profile; | 658 SupportedProfile profile; |
666 profile.profile = media::VP9PROFILE_ANY; | 659 profile.profile = media::VP9PROFILE_ANY; |
667 profile.min_resolution.SetSize(0, 0); | 660 profile.min_resolution.SetSize(0, 0); |
668 profile.max_resolution.SetSize(1920, 1088); | 661 profile.max_resolution.SetSize(1920, 1088); |
669 profiles.push_back(profile); | 662 profiles.push_back(profile); |
670 } | 663 } |
671 | 664 |
672 for (const auto& supported_profile : kSupportedH264Profiles) { | 665 for (const auto& supported_profile : kSupportedH264Profiles) { |
673 SupportedProfile profile; | 666 SupportedProfile profile; |
674 profile.profile = supported_profile; | 667 profile.profile = supported_profile; |
675 profile.min_resolution.SetSize(0, 0); | 668 profile.min_resolution.SetSize(0, 0); |
676 // Advertise support for 4k and let the MediaCodec fail when decoding if it | 669 // Advertise support for 4k and let the MediaCodec fail when decoding if it |
677 // doesn't support the resolution. It's assumed that consumers won't have | 670 // doesn't support the resolution. It's assumed that consumers won't have |
678 // software fallback for H264 on Android anyway. | 671 // software fallback for H264 on Android anyway. |
679 profile.max_resolution.SetSize(3840, 2160); | 672 profile.max_resolution.SetSize(3840, 2160); |
680 profiles.push_back(profile); | 673 profiles.push_back(profile); |
681 } | 674 } |
682 #endif | |
683 | 675 |
684 capabilities.flags = BACKING_STRATEGY::GetCapabilitiesFlags(); | 676 // TODO(liberato): Needs to be based on command line flag... |
677 capabilities.flags = AndroidCopyingBackingStrategy::GetCapabilitiesFlags(); | |
685 | 678 |
686 return capabilities; | 679 return capabilities; |
687 } | 680 } |
688 | 681 |
689 } // namespace content | 682 } // namespace content |
OLD | NEW |