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::SupportsSetParameters() && | 130 if (!(media::MediaCodecBridge::SupportsSetParameters() && |
131 format == VideoFrame::I420 && | 131 format == VideoFrame::I420 && |
132 output_profile == media::VP8PROFILE_MAIN, | 132 output_profile == media::VP8PROFILE_MAIN)) { |
133 "Unexpected combo: " << format << ", " << output_profile, | 133 DLOG(ERROR) << "Unexpected combo: " << format << ", " << output_profile; |
134 kInvalidArgumentError); | 134 return false; |
| 135 } |
135 | 136 |
136 last_set_bitrate_ = initial_bitrate; | 137 last_set_bitrate_ = initial_bitrate; |
137 | 138 |
138 // Only consider using MediaCodec if it's likely backed by hardware. | 139 // Only consider using MediaCodec if it's likely backed by hardware. |
139 RETURN_ON_FAILURE(!media::VideoCodecBridge::IsKnownUnaccelerated( | 140 if (media::VideoCodecBridge::IsKnownUnaccelerated( |
140 media::kCodecVP8, media::MEDIA_CODEC_ENCODER), | 141 media::kCodecVP8, media::MEDIA_CODEC_ENCODER)) { |
141 "No HW support", | 142 DLOG(ERROR) << "No HW support"; |
142 kPlatformFailureError); | 143 return false; |
| 144 } |
143 | 145 |
144 // TODO(fischman): when there is more HW out there with different color-space | 146 // TODO(fischman): when there is more HW out there with different color-space |
145 // support, this should turn into a negotiation with the codec for supported | 147 // support, this should turn into a negotiation with the codec for supported |
146 // formats. For now we use the only format supported by the only available | 148 // formats. For now we use the only format supported by the only available |
147 // HW. | 149 // HW. |
148 media_codec_.reset( | 150 media_codec_.reset( |
149 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, | 151 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, |
150 input_visible_size, | 152 input_visible_size, |
151 initial_bitrate, | 153 initial_bitrate, |
152 INITIAL_FRAMERATE, | 154 INITIAL_FRAMERATE, |
153 IFRAME_INTERVAL, | 155 IFRAME_INTERVAL, |
154 COLOR_FORMAT_YUV420_SEMIPLANAR)); | 156 COLOR_FORMAT_YUV420_SEMIPLANAR)); |
155 | 157 |
156 RETURN_ON_FAILURE( | 158 if (!media_codec_) { |
157 media_codec_, | 159 DLOG(ERROR) << "Failed to create/start the codec: " |
158 "Failed to create/start the codec: " << input_visible_size.ToString(), | 160 << input_visible_size.ToString(); |
159 kPlatformFailureError); | 161 return false; |
160 | 162 } |
161 base::MessageLoop::current()->PostTask( | |
162 FROM_HERE, | |
163 base::Bind(&VideoEncodeAccelerator::Client::NotifyInitializeDone, | |
164 client_ptr_factory_->GetWeakPtr())); | |
165 | 163 |
166 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); | 164 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); |
167 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); | 165 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); |
168 base::MessageLoop::current()->PostTask( | 166 base::MessageLoop::current()->PostTask( |
169 FROM_HERE, | 167 FROM_HERE, |
170 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, | 168 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, |
171 client_ptr_factory_->GetWeakPtr(), | 169 client_ptr_factory_->GetWeakPtr(), |
172 num_output_buffers_, | 170 num_output_buffers_, |
173 input_visible_size, | 171 input_visible_size, |
174 output_buffers_capacity_)); | 172 output_buffers_capacity_)); |
| 173 return true; |
175 } | 174 } |
176 | 175 |
177 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { | 176 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { |
178 if (!io_timer_.IsRunning() && | 177 if (!io_timer_.IsRunning() && |
179 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { | 178 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { |
180 io_timer_.Start(FROM_HERE, | 179 io_timer_.Start(FROM_HERE, |
181 EncodePollDelay(), | 180 EncodePollDelay(), |
182 this, | 181 this, |
183 &AndroidVideoEncodeAccelerator::DoIOTask); | 182 &AndroidVideoEncodeAccelerator::DoIOTask); |
184 } | 183 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 base::MessageLoop::current()->PostTask( | 404 base::MessageLoop::current()->PostTask( |
406 FROM_HERE, | 405 FROM_HERE, |
407 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, | 406 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, |
408 client_ptr_factory_->GetWeakPtr(), | 407 client_ptr_factory_->GetWeakPtr(), |
409 bitstream_buffer.id(), | 408 bitstream_buffer.id(), |
410 size, | 409 size, |
411 key_frame)); | 410 key_frame)); |
412 } | 411 } |
413 | 412 |
414 } // namespace content | 413 } // namespace content |
OLD | NEW |