OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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_encode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_encode_accelerator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 // encoder? Sure would be. Too bad it doesn't. So we hard-code some | 105 // encoder? Sure would be. Too bad it doesn't. So we hard-code some |
106 // reasonable defaults. | 106 // reasonable defaults. |
107 profile.max_resolution.SetSize(1920, 1088); | 107 profile.max_resolution.SetSize(1920, 1088); |
108 profile.max_framerate.numerator = 30; | 108 profile.max_framerate.numerator = 30; |
109 profile.max_framerate.denominator = 1; | 109 profile.max_framerate.denominator = 1; |
110 profiles.push_back(profile); | 110 profiles.push_back(profile); |
111 } | 111 } |
112 return profiles; | 112 return profiles; |
113 } | 113 } |
114 | 114 |
115 void AndroidVideoEncodeAccelerator::Initialize( | 115 bool AndroidVideoEncodeAccelerator::Initialize( |
116 VideoFrame::Format format, | 116 VideoFrame::Format format, |
117 const gfx::Size& input_visible_size, | 117 const gfx::Size& input_visible_size, |
118 media::VideoCodecProfile output_profile, | 118 media::VideoCodecProfile output_profile, |
119 uint32 initial_bitrate, | 119 uint32 initial_bitrate, |
120 Client* client) { | 120 Client* client) { |
121 DVLOG(3) << __PRETTY_FUNCTION__ << " format: " << format | 121 DVLOG(3) << __PRETTY_FUNCTION__ << " format: " << format |
122 << ", input_visible_size: " << input_visible_size.ToString() | 122 << ", input_visible_size: " << input_visible_size.ToString() |
123 << ", output_profile: " << output_profile | 123 << ", output_profile: " << output_profile |
124 << ", initial_bitrate: " << initial_bitrate; | 124 << ", initial_bitrate: " << initial_bitrate; |
125 DCHECK(!media_codec_); | 125 DCHECK(!media_codec_); |
126 DCHECK(thread_checker_.CalledOnValidThread()); | 126 DCHECK(thread_checker_.CalledOnValidThread()); |
127 | 127 |
128 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); | 128 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); |
129 | 129 |
130 RETURN_ON_FAILURE(media::MediaCodecBridge::IsAvailable() && | 130 if (!(media::MediaCodecBridge::IsAvailable() && |
131 media::MediaCodecBridge::SupportsSetParameters() && | 131 media::MediaCodecBridge::SupportsSetParameters() && |
132 format == VideoFrame::I420 && | 132 format == VideoFrame::I420 && |
133 output_profile == media::VP8PROFILE_MAIN, | 133 output_profile == media::VP8PROFILE_MAIN)) { |
134 "Unexpected combo: " << format << ", " << output_profile, | 134 DLOG(ERROR) << "Unexpected combo: " << format << ", " << output_profile; |
135 kInvalidArgumentError); | 135 return false; |
| 136 } |
136 | 137 |
137 last_set_bitrate_ = initial_bitrate; | 138 last_set_bitrate_ = initial_bitrate; |
138 | 139 |
139 // Only consider using MediaCodec if it's likely backed by hardware. | 140 // Only consider using MediaCodec if it's likely backed by hardware. |
140 RETURN_ON_FAILURE(!media::VideoCodecBridge::IsKnownUnaccelerated( | 141 if (media::VideoCodecBridge::IsKnownUnaccelerated( |
141 media::kCodecVP8, media::MEDIA_CODEC_ENCODER), | 142 media::kCodecVP8, media::MEDIA_CODEC_ENCODER)) { |
142 "No HW support", | 143 DLOG(ERROR) << "No HW support"; |
143 kPlatformFailureError); | 144 return false; |
| 145 } |
144 | 146 |
145 // TODO(fischman): when there is more HW out there with different color-space | 147 // TODO(fischman): when there is more HW out there with different color-space |
146 // support, this should turn into a negotiation with the codec for supported | 148 // support, this should turn into a negotiation with the codec for supported |
147 // formats. For now we use the only format supported by the only available | 149 // formats. For now we use the only format supported by the only available |
148 // HW. | 150 // HW. |
149 media_codec_.reset( | 151 media_codec_.reset( |
150 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, | 152 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, |
151 input_visible_size, | 153 input_visible_size, |
152 initial_bitrate, | 154 initial_bitrate, |
153 INITIAL_FRAMERATE, | 155 INITIAL_FRAMERATE, |
154 IFRAME_INTERVAL, | 156 IFRAME_INTERVAL, |
155 COLOR_FORMAT_YUV420_SEMIPLANAR)); | 157 COLOR_FORMAT_YUV420_SEMIPLANAR)); |
156 | 158 |
157 RETURN_ON_FAILURE( | 159 if (!media_codec_) { |
158 media_codec_, | 160 DLOG(ERROR) << "Failed to create/start the codec: " |
159 "Failed to create/start the codec: " << input_visible_size.ToString(), | 161 << input_visible_size.ToString(); |
160 kPlatformFailureError); | 162 return false; |
161 | 163 } |
162 base::MessageLoop::current()->PostTask( | |
163 FROM_HERE, | |
164 base::Bind(&VideoEncodeAccelerator::Client::NotifyInitializeDone, | |
165 client_ptr_factory_->GetWeakPtr())); | |
166 | 164 |
167 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); | 165 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); |
168 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); | 166 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); |
169 base::MessageLoop::current()->PostTask( | 167 base::MessageLoop::current()->PostTask( |
170 FROM_HERE, | 168 FROM_HERE, |
171 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, | 169 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, |
172 client_ptr_factory_->GetWeakPtr(), | 170 client_ptr_factory_->GetWeakPtr(), |
173 num_output_buffers_, | 171 num_output_buffers_, |
174 input_visible_size, | 172 input_visible_size, |
175 output_buffers_capacity_)); | 173 output_buffers_capacity_)); |
| 174 return true; |
176 } | 175 } |
177 | 176 |
178 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { | 177 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { |
179 if (!io_timer_.IsRunning() && | 178 if (!io_timer_.IsRunning() && |
180 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { | 179 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { |
181 io_timer_.Start(FROM_HERE, | 180 io_timer_.Start(FROM_HERE, |
182 EncodePollDelay(), | 181 EncodePollDelay(), |
183 this, | 182 this, |
184 &AndroidVideoEncodeAccelerator::DoIOTask); | 183 &AndroidVideoEncodeAccelerator::DoIOTask); |
185 } | 184 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 base::MessageLoop::current()->PostTask( | 405 base::MessageLoop::current()->PostTask( |
407 FROM_HERE, | 406 FROM_HERE, |
408 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, | 407 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, |
409 client_ptr_factory_->GetWeakPtr(), | 408 client_ptr_factory_->GetWeakPtr(), |
410 bitstream_buffer.id(), | 409 bitstream_buffer.id(), |
411 size, | 410 size, |
412 key_frame)); | 411 key_frame)); |
413 } | 412 } |
414 | 413 |
415 } // namespace content | 414 } // namespace content |
OLD | NEW |