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

Side by Side Diff: media/gpu/android_video_encode_accelerator.cc

Issue 2061823003: media: Drop "media::" in media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: work around clang format by adding an empty line Created 4 years, 6 months 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
« no previous file with comments | « media/gpu/android_video_encode_accelerator.h ('k') | media/gpu/avda_codec_image.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "media/gpu/android_video_encode_accelerator.h" 5 #include "media/gpu/android_video_encode_accelerator.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <set> 8 #include <set>
9 #include <tuple> 9 #include <tuple>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 17 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
18 #include "gpu/ipc/service/gpu_channel.h" 18 #include "gpu/ipc/service/gpu_channel.h"
19 #include "media/base/android/media_codec_util.h" 19 #include "media/base/android/media_codec_util.h"
20 #include "media/base/bitstream_buffer.h" 20 #include "media/base/bitstream_buffer.h"
21 #include "media/base/limits.h" 21 #include "media/base/limits.h"
22 #include "media/gpu/shared_memory_region.h" 22 #include "media/gpu/shared_memory_region.h"
23 #include "media/video/picture.h" 23 #include "media/video/picture.h"
24 #include "third_party/libyuv/include/libyuv/convert_from.h" 24 #include "third_party/libyuv/include/libyuv/convert_from.h"
25 #include "ui/gl/android/scoped_java_surface.h" 25 #include "ui/gl/android/scoped_java_surface.h"
26 #include "ui/gl/gl_bindings.h" 26 #include "ui/gl/gl_bindings.h"
27 27
28 using media::VideoCodecBridge;
29 using media::VideoFrame;
30
31 namespace media { 28 namespace media {
32 29
33 // Limit default max video codec size for Android to avoid 30 // Limit default max video codec size for Android to avoid
34 // HW codec initialization failure for resolution higher than 720p. 31 // HW codec initialization failure for resolution higher than 720p.
35 // Default values are from Libjingle "jsepsessiondescription.cc". 32 // Default values are from Libjingle "jsepsessiondescription.cc".
36 const int kMaxEncodeFrameWidth = 1280; 33 const int kMaxEncodeFrameWidth = 1280;
37 const int kMaxEncodeFrameHeight = 720; 34 const int kMaxEncodeFrameHeight = 720;
38 const int kMaxFramerateNumerator = 30; 35 const int kMaxFramerateNumerator = 30;
39 const int kMaxFramerateDenominator = 1; 36 const int kMaxFramerateDenominator = 1;
40 37
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 75
79 static inline const base::TimeDelta NoWaitTimeOut() { 76 static inline const base::TimeDelta NoWaitTimeOut() {
80 return base::TimeDelta::FromMicroseconds(0); 77 return base::TimeDelta::FromMicroseconds(0);
81 } 78 }
82 79
83 static bool GetSupportedColorFormatForMime(const std::string& mime, 80 static bool GetSupportedColorFormatForMime(const std::string& mime,
84 PixelFormat* pixel_format) { 81 PixelFormat* pixel_format) {
85 if (mime.empty()) 82 if (mime.empty())
86 return false; 83 return false;
87 84
88 std::set<int> formats = media::MediaCodecUtil::GetEncoderColorFormats(mime); 85 std::set<int> formats = MediaCodecUtil::GetEncoderColorFormats(mime);
89 if (formats.count(COLOR_FORMAT_YUV420_SEMIPLANAR) > 0) 86 if (formats.count(COLOR_FORMAT_YUV420_SEMIPLANAR) > 0)
90 *pixel_format = COLOR_FORMAT_YUV420_SEMIPLANAR; 87 *pixel_format = COLOR_FORMAT_YUV420_SEMIPLANAR;
91 else if (formats.count(COLOR_FORMAT_YUV420_PLANAR) > 0) 88 else if (formats.count(COLOR_FORMAT_YUV420_PLANAR) > 0)
92 *pixel_format = COLOR_FORMAT_YUV420_PLANAR; 89 *pixel_format = COLOR_FORMAT_YUV420_PLANAR;
93 else 90 else
94 return false; 91 return false;
95 92
96 return true; 93 return true;
97 } 94 }
98 95
99 AndroidVideoEncodeAccelerator::AndroidVideoEncodeAccelerator() 96 AndroidVideoEncodeAccelerator::AndroidVideoEncodeAccelerator()
100 : num_buffers_at_codec_(0), last_set_bitrate_(0) {} 97 : num_buffers_at_codec_(0), last_set_bitrate_(0) {}
101 98
102 AndroidVideoEncodeAccelerator::~AndroidVideoEncodeAccelerator() { 99 AndroidVideoEncodeAccelerator::~AndroidVideoEncodeAccelerator() {
103 DCHECK(thread_checker_.CalledOnValidThread()); 100 DCHECK(thread_checker_.CalledOnValidThread());
104 } 101 }
105 102
106 media::VideoEncodeAccelerator::SupportedProfiles 103 VideoEncodeAccelerator::SupportedProfiles
107 AndroidVideoEncodeAccelerator::GetSupportedProfiles() { 104 AndroidVideoEncodeAccelerator::GetSupportedProfiles() {
108 SupportedProfiles profiles; 105 SupportedProfiles profiles;
109 106
110 const struct { 107 const struct {
111 const media::VideoCodec codec; 108 const VideoCodec codec;
112 const media::VideoCodecProfile profile; 109 const VideoCodecProfile profile;
113 } kSupportedCodecs[] = {{media::kCodecVP8, media::VP8PROFILE_ANY}, 110 } kSupportedCodecs[] = {{kCodecVP8, VP8PROFILE_ANY},
114 {media::kCodecH264, media::H264PROFILE_BASELINE}, 111 {kCodecH264, H264PROFILE_BASELINE},
115 {media::kCodecH264, media::H264PROFILE_MAIN}}; 112 {kCodecH264, H264PROFILE_MAIN}};
116 113
117 for (const auto& supported_codec : kSupportedCodecs) { 114 for (const auto& supported_codec : kSupportedCodecs) {
118 if (supported_codec.codec == media::kCodecVP8 && 115 if (supported_codec.codec == kCodecVP8 &&
119 !media::MediaCodecUtil::IsVp8EncoderAvailable()) { 116 !MediaCodecUtil::IsVp8EncoderAvailable()) {
120 continue; 117 continue;
121 } 118 }
122 119
123 if (VideoCodecBridge::IsKnownUnaccelerated(supported_codec.codec, 120 if (VideoCodecBridge::IsKnownUnaccelerated(supported_codec.codec,
124 media::MEDIA_CODEC_ENCODER)) { 121 MEDIA_CODEC_ENCODER)) {
125 continue; 122 continue;
126 } 123 }
127 124
128 SupportedProfile profile; 125 SupportedProfile profile;
129 profile.profile = supported_codec.profile; 126 profile.profile = supported_codec.profile;
130 // It would be nice if MediaCodec exposes the maximum capabilities of 127 // It would be nice if MediaCodec exposes the maximum capabilities of
131 // the encoder. Hard-code some reasonable defaults as workaround. 128 // the encoder. Hard-code some reasonable defaults as workaround.
132 profile.max_resolution.SetSize(kMaxEncodeFrameWidth, kMaxEncodeFrameHeight); 129 profile.max_resolution.SetSize(kMaxEncodeFrameWidth, kMaxEncodeFrameHeight);
133 profile.max_framerate_numerator = kMaxFramerateNumerator; 130 profile.max_framerate_numerator = kMaxFramerateNumerator;
134 profile.max_framerate_denominator = kMaxFramerateDenominator; 131 profile.max_framerate_denominator = kMaxFramerateDenominator;
135 profiles.push_back(profile); 132 profiles.push_back(profile);
136 } 133 }
137 return profiles; 134 return profiles;
138 } 135 }
139 136
140 bool AndroidVideoEncodeAccelerator::Initialize( 137 bool AndroidVideoEncodeAccelerator::Initialize(
141 media::VideoPixelFormat format, 138 VideoPixelFormat format,
142 const gfx::Size& input_visible_size, 139 const gfx::Size& input_visible_size,
143 media::VideoCodecProfile output_profile, 140 VideoCodecProfile output_profile,
144 uint32_t initial_bitrate, 141 uint32_t initial_bitrate,
145 Client* client) { 142 Client* client) {
146 DVLOG(3) << __PRETTY_FUNCTION__ << " format: " << format 143 DVLOG(3) << __PRETTY_FUNCTION__ << " format: " << format
147 << ", input_visible_size: " << input_visible_size.ToString() 144 << ", input_visible_size: " << input_visible_size.ToString()
148 << ", output_profile: " << output_profile 145 << ", output_profile: " << output_profile
149 << ", initial_bitrate: " << initial_bitrate; 146 << ", initial_bitrate: " << initial_bitrate;
150 DCHECK(!media_codec_); 147 DCHECK(!media_codec_);
151 DCHECK(thread_checker_.CalledOnValidThread()); 148 DCHECK(thread_checker_.CalledOnValidThread());
152 149
153 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); 150 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
154 151
155 if (!(media::MediaCodecUtil::SupportsSetParameters() && 152 if (!(MediaCodecUtil::SupportsSetParameters() &&
156 format == media::PIXEL_FORMAT_I420)) { 153 format == PIXEL_FORMAT_I420)) {
157 DLOG(ERROR) << "Unexpected combo: " << format << ", " << output_profile; 154 DLOG(ERROR) << "Unexpected combo: " << format << ", " << output_profile;
158 return false; 155 return false;
159 } 156 }
160 157
161 std::string mime_type; 158 std::string mime_type;
162 media::VideoCodec codec; 159 VideoCodec codec;
163 // The client should be prepared to feed at least this many frames into the 160 // The client should be prepared to feed at least this many frames into the
164 // encoder before being returned any output frames, since the encoder may 161 // encoder before being returned any output frames, since the encoder may
165 // need to hold onto some subset of inputs as reference pictures. 162 // need to hold onto some subset of inputs as reference pictures.
166 uint32_t frame_input_count; 163 uint32_t frame_input_count;
167 if (output_profile == media::VP8PROFILE_ANY) { 164 if (output_profile == VP8PROFILE_ANY) {
168 codec = media::kCodecVP8; 165 codec = kCodecVP8;
169 mime_type = "video/x-vnd.on2.vp8"; 166 mime_type = "video/x-vnd.on2.vp8";
170 frame_input_count = 1; 167 frame_input_count = 1;
171 } else if (output_profile == media::H264PROFILE_BASELINE || 168 } else if (output_profile == H264PROFILE_BASELINE ||
172 output_profile == media::H264PROFILE_MAIN) { 169 output_profile == H264PROFILE_MAIN) {
173 codec = media::kCodecH264; 170 codec = kCodecH264;
174 mime_type = "video/avc"; 171 mime_type = "video/avc";
175 frame_input_count = 30; 172 frame_input_count = 30;
176 } else { 173 } else {
177 return false; 174 return false;
178 } 175 }
179 176
180 frame_size_ = input_visible_size; 177 frame_size_ = input_visible_size;
181 last_set_bitrate_ = initial_bitrate; 178 last_set_bitrate_ = initial_bitrate;
182 179
183 // Only consider using MediaCodec if it's likely backed by hardware. 180 // Only consider using MediaCodec if it's likely backed by hardware.
184 if (media::VideoCodecBridge::IsKnownUnaccelerated( 181 if (VideoCodecBridge::IsKnownUnaccelerated(codec, MEDIA_CODEC_ENCODER)) {
185 codec, media::MEDIA_CODEC_ENCODER)) {
186 DLOG(ERROR) << "No HW support"; 182 DLOG(ERROR) << "No HW support";
187 return false; 183 return false;
188 } 184 }
189 185
190 PixelFormat pixel_format = COLOR_FORMAT_YUV420_SEMIPLANAR; 186 PixelFormat pixel_format = COLOR_FORMAT_YUV420_SEMIPLANAR;
191 if (!GetSupportedColorFormatForMime(mime_type, &pixel_format)) { 187 if (!GetSupportedColorFormatForMime(mime_type, &pixel_format)) {
192 DLOG(ERROR) << "No color format support."; 188 DLOG(ERROR) << "No color format support.";
193 return false; 189 return false;
194 } 190 }
195 media_codec_.reset(media::VideoCodecBridge::CreateEncoder( 191 media_codec_.reset(VideoCodecBridge::CreateEncoder(
196 codec, input_visible_size, initial_bitrate, INITIAL_FRAMERATE, 192 codec, input_visible_size, initial_bitrate, INITIAL_FRAMERATE,
197 IFRAME_INTERVAL, pixel_format)); 193 IFRAME_INTERVAL, pixel_format));
198 194
199 if (!media_codec_) { 195 if (!media_codec_) {
200 DLOG(ERROR) << "Failed to create/start the codec: " 196 DLOG(ERROR) << "Failed to create/start the codec: "
201 << input_visible_size.ToString(); 197 << input_visible_size.ToString();
202 return false; 198 return false;
203 } 199 }
204 200
205 // Conservative upper bound for output buffer size: decoded size + 2KB. 201 // Conservative upper bound for output buffer size: decoded size + 2KB.
(...skipping 20 matching lines...) Expand all
226 (num_buffers_at_codec_ == 0 && pending_frames_.empty())) { 222 (num_buffers_at_codec_ == 0 && pending_frames_.empty())) {
227 io_timer_.Stop(); 223 io_timer_.Stop();
228 } 224 }
229 } 225 }
230 226
231 void AndroidVideoEncodeAccelerator::Encode( 227 void AndroidVideoEncodeAccelerator::Encode(
232 const scoped_refptr<VideoFrame>& frame, 228 const scoped_refptr<VideoFrame>& frame,
233 bool force_keyframe) { 229 bool force_keyframe) {
234 DVLOG(3) << __PRETTY_FUNCTION__ << ": " << force_keyframe; 230 DVLOG(3) << __PRETTY_FUNCTION__ << ": " << force_keyframe;
235 DCHECK(thread_checker_.CalledOnValidThread()); 231 DCHECK(thread_checker_.CalledOnValidThread());
236 RETURN_ON_FAILURE(frame->format() == media::PIXEL_FORMAT_I420, 232 RETURN_ON_FAILURE(frame->format() == PIXEL_FORMAT_I420, "Unexpected format",
237 "Unexpected format", kInvalidArgumentError); 233 kInvalidArgumentError);
238 RETURN_ON_FAILURE(frame->visible_rect().size() == frame_size_, 234 RETURN_ON_FAILURE(frame->visible_rect().size() == frame_size_,
239 "Unexpected resolution", kInvalidArgumentError); 235 "Unexpected resolution", kInvalidArgumentError);
240 // MediaCodec doesn't have a way to specify stride for non-Packed formats, so 236 // MediaCodec doesn't have a way to specify stride for non-Packed formats, so
241 // we insist on being called with packed frames and no cropping :( 237 // we insist on being called with packed frames and no cropping :(
242 RETURN_ON_FAILURE(frame->row_bytes(VideoFrame::kYPlane) == 238 RETURN_ON_FAILURE(frame->row_bytes(VideoFrame::kYPlane) ==
243 frame->stride(VideoFrame::kYPlane) && 239 frame->stride(VideoFrame::kYPlane) &&
244 frame->row_bytes(VideoFrame::kUPlane) == 240 frame->row_bytes(VideoFrame::kUPlane) ==
245 frame->stride(VideoFrame::kUPlane) && 241 frame->stride(VideoFrame::kUPlane) &&
246 frame->row_bytes(VideoFrame::kVPlane) == 242 frame->row_bytes(VideoFrame::kVPlane) ==
247 frame->stride(VideoFrame::kVPlane) && 243 frame->stride(VideoFrame::kVPlane) &&
248 frame->coded_size() == frame->visible_rect().size(), 244 frame->coded_size() == frame->visible_rect().size(),
249 "Non-packed frame, or visible_rect != coded_size", 245 "Non-packed frame, or visible_rect != coded_size",
250 kInvalidArgumentError); 246 kInvalidArgumentError);
251 247
252 pending_frames_.push( 248 pending_frames_.push(
253 std::make_tuple(frame, force_keyframe, base::Time::Now())); 249 std::make_tuple(frame, force_keyframe, base::Time::Now()));
254 DoIOTask(); 250 DoIOTask();
255 } 251 }
256 252
257 void AndroidVideoEncodeAccelerator::UseOutputBitstreamBuffer( 253 void AndroidVideoEncodeAccelerator::UseOutputBitstreamBuffer(
258 const media::BitstreamBuffer& buffer) { 254 const BitstreamBuffer& buffer) {
259 DVLOG(3) << __PRETTY_FUNCTION__ << ": bitstream_buffer_id=" << buffer.id(); 255 DVLOG(3) << __PRETTY_FUNCTION__ << ": bitstream_buffer_id=" << buffer.id();
260 DCHECK(thread_checker_.CalledOnValidThread()); 256 DCHECK(thread_checker_.CalledOnValidThread());
261 available_bitstream_buffers_.push_back(buffer); 257 available_bitstream_buffers_.push_back(buffer);
262 DoIOTask(); 258 DoIOTask();
263 } 259 }
264 260
265 void AndroidVideoEncodeAccelerator::RequestEncodingParametersChange( 261 void AndroidVideoEncodeAccelerator::RequestEncodingParametersChange(
266 uint32_t bitrate, 262 uint32_t bitrate,
267 uint32_t framerate) { 263 uint32_t framerate) {
268 DVLOG(3) << __PRETTY_FUNCTION__ << ": bitrate: " << bitrate 264 DVLOG(3) << __PRETTY_FUNCTION__ << ": bitrate: " << bitrate
(...skipping 26 matching lines...) Expand all
295 DequeueOutput(); 291 DequeueOutput();
296 MaybeStartIOTimer(); 292 MaybeStartIOTimer();
297 MaybeStopIOTimer(); 293 MaybeStopIOTimer();
298 } 294 }
299 295
300 void AndroidVideoEncodeAccelerator::QueueInput() { 296 void AndroidVideoEncodeAccelerator::QueueInput() {
301 if (!client_ptr_factory_->GetWeakPtr() || pending_frames_.empty()) 297 if (!client_ptr_factory_->GetWeakPtr() || pending_frames_.empty())
302 return; 298 return;
303 299
304 int input_buf_index = 0; 300 int input_buf_index = 0;
305 media::MediaCodecStatus status = 301 MediaCodecStatus status =
306 media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index); 302 media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index);
307 if (status != media::MEDIA_CODEC_OK) { 303 if (status != MEDIA_CODEC_OK) {
308 DCHECK(status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER || 304 DCHECK(status == MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER ||
309 status == media::MEDIA_CODEC_ERROR); 305 status == MEDIA_CODEC_ERROR);
310 RETURN_ON_FAILURE(status != media::MEDIA_CODEC_ERROR, "MediaCodec error", 306 RETURN_ON_FAILURE(status != MEDIA_CODEC_ERROR, "MediaCodec error",
311 kPlatformFailureError); 307 kPlatformFailureError);
312 return; 308 return;
313 } 309 }
314 310
315 const PendingFrames::value_type& input = pending_frames_.front(); 311 const PendingFrames::value_type& input = pending_frames_.front();
316 bool is_key_frame = std::get<1>(input); 312 bool is_key_frame = std::get<1>(input);
317 if (is_key_frame) { 313 if (is_key_frame) {
318 // Ideally MediaCodec would honor BUFFER_FLAG_SYNC_FRAME so we could 314 // Ideally MediaCodec would honor BUFFER_FLAG_SYNC_FRAME so we could
319 // indicate this in the QueueInputBuffer() call below and guarantee _this_ 315 // indicate this in the QueueInputBuffer() call below and guarantee _this_
320 // frame be encoded as a key frame, but sadly that flag is ignored. 316 // frame be encoded as a key frame, but sadly that flag is ignored.
321 // Instead, we request a key frame "soon". 317 // Instead, we request a key frame "soon".
322 media_codec_->RequestKeyFrameSoon(); 318 media_codec_->RequestKeyFrameSoon();
323 } 319 }
324 scoped_refptr<VideoFrame> frame = std::get<0>(input); 320 scoped_refptr<VideoFrame> frame = std::get<0>(input);
325 321
326 uint8_t* buffer = NULL; 322 uint8_t* buffer = NULL;
327 size_t capacity = 0; 323 size_t capacity = 0;
328 status = media_codec_->GetInputBuffer(input_buf_index, &buffer, &capacity); 324 status = media_codec_->GetInputBuffer(input_buf_index, &buffer, &capacity);
329 RETURN_ON_FAILURE(status == media::MEDIA_CODEC_OK, "GetInputBuffer failed.", 325 RETURN_ON_FAILURE(status == MEDIA_CODEC_OK, "GetInputBuffer failed.",
330 kPlatformFailureError); 326 kPlatformFailureError);
331 327
332 size_t queued_size = 328 size_t queued_size =
333 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, frame->coded_size()); 329 VideoFrame::AllocationSize(PIXEL_FORMAT_I420, frame->coded_size());
334 RETURN_ON_FAILURE(capacity >= queued_size, 330 RETURN_ON_FAILURE(capacity >= queued_size,
335 "Failed to get input buffer: " << input_buf_index, 331 "Failed to get input buffer: " << input_buf_index,
336 kPlatformFailureError); 332 kPlatformFailureError);
337 333
338 uint8_t* dst_y = buffer; 334 uint8_t* dst_y = buffer;
339 int dst_stride_y = frame->stride(VideoFrame::kYPlane); 335 int dst_stride_y = frame->stride(VideoFrame::kYPlane);
340 uint8_t* dst_uv = 336 uint8_t* dst_uv =
341 buffer + 337 buffer +
342 frame->stride(VideoFrame::kYPlane) * frame->rows(VideoFrame::kYPlane); 338 frame->stride(VideoFrame::kYPlane) * frame->rows(VideoFrame::kYPlane);
343 int dst_stride_uv = frame->stride(VideoFrame::kUPlane) * 2; 339 int dst_stride_uv = frame->stride(VideoFrame::kUPlane) * 2;
344 // Why NV12? Because COLOR_FORMAT_YUV420_SEMIPLANAR. See comment at other 340 // Why NV12? Because COLOR_FORMAT_YUV420_SEMIPLANAR. See comment at other
345 // mention of that constant. 341 // mention of that constant.
346 bool converted = !libyuv::I420ToNV12( 342 bool converted = !libyuv::I420ToNV12(
347 frame->data(VideoFrame::kYPlane), frame->stride(VideoFrame::kYPlane), 343 frame->data(VideoFrame::kYPlane), frame->stride(VideoFrame::kYPlane),
348 frame->data(VideoFrame::kUPlane), frame->stride(VideoFrame::kUPlane), 344 frame->data(VideoFrame::kUPlane), frame->stride(VideoFrame::kUPlane),
349 frame->data(VideoFrame::kVPlane), frame->stride(VideoFrame::kVPlane), 345 frame->data(VideoFrame::kVPlane), frame->stride(VideoFrame::kVPlane),
350 dst_y, dst_stride_y, dst_uv, dst_stride_uv, frame->coded_size().width(), 346 dst_y, dst_stride_y, dst_uv, dst_stride_uv, frame->coded_size().width(),
351 frame->coded_size().height()); 347 frame->coded_size().height());
352 RETURN_ON_FAILURE(converted, "Failed to I420ToNV12!", kPlatformFailureError); 348 RETURN_ON_FAILURE(converted, "Failed to I420ToNV12!", kPlatformFailureError);
353 349
354 fake_input_timestamp_ += base::TimeDelta::FromMicroseconds(1); 350 fake_input_timestamp_ += base::TimeDelta::FromMicroseconds(1);
355 status = media_codec_->QueueInputBuffer(input_buf_index, NULL, queued_size, 351 status = media_codec_->QueueInputBuffer(input_buf_index, NULL, queued_size,
356 fake_input_timestamp_); 352 fake_input_timestamp_);
357 UMA_HISTOGRAM_TIMES("Media.AVDA.InputQueueTime", 353 UMA_HISTOGRAM_TIMES("Media.AVDA.InputQueueTime",
358 base::Time::Now() - std::get<2>(input)); 354 base::Time::Now() - std::get<2>(input));
359 RETURN_ON_FAILURE(status == media::MEDIA_CODEC_OK, 355 RETURN_ON_FAILURE(status == MEDIA_CODEC_OK,
360 "Failed to QueueInputBuffer: " << status, 356 "Failed to QueueInputBuffer: " << status,
361 kPlatformFailureError); 357 kPlatformFailureError);
362 ++num_buffers_at_codec_; 358 ++num_buffers_at_codec_;
363 pending_frames_.pop(); 359 pending_frames_.pop();
364 } 360 }
365 361
366 void AndroidVideoEncodeAccelerator::DequeueOutput() { 362 void AndroidVideoEncodeAccelerator::DequeueOutput() {
367 if (!client_ptr_factory_->GetWeakPtr() || 363 if (!client_ptr_factory_->GetWeakPtr() ||
368 available_bitstream_buffers_.empty() || num_buffers_at_codec_ == 0) { 364 available_bitstream_buffers_.empty() || num_buffers_at_codec_ == 0) {
369 return; 365 return;
370 } 366 }
371 367
372 int32_t buf_index = 0; 368 int32_t buf_index = 0;
373 size_t offset = 0; 369 size_t offset = 0;
374 size_t size = 0; 370 size_t size = 0;
375 bool key_frame = false; 371 bool key_frame = false;
376 do { 372 do {
377 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 373 MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
378 NoWaitTimeOut(), &buf_index, &offset, &size, NULL, NULL, &key_frame); 374 NoWaitTimeOut(), &buf_index, &offset, &size, NULL, NULL, &key_frame);
379 switch (status) { 375 switch (status) {
380 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 376 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
381 return; 377 return;
382 378
383 case media::MEDIA_CODEC_ERROR: 379 case MEDIA_CODEC_ERROR:
384 RETURN_ON_FAILURE(false, "Codec error", kPlatformFailureError); 380 RETURN_ON_FAILURE(false, "Codec error", kPlatformFailureError);
385 // Unreachable because of previous statement, but included for clarity. 381 // Unreachable because of previous statement, but included for clarity.
386 return; 382 return;
387 383
388 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: 384 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED:
389 RETURN_ON_FAILURE(false, "Unexpected output format change", 385 RETURN_ON_FAILURE(false, "Unexpected output format change",
390 kPlatformFailureError); 386 kPlatformFailureError);
391 break; 387 break;
392 388
393 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 389 case MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
394 break; 390 break;
395 391
396 case media::MEDIA_CODEC_OK: 392 case MEDIA_CODEC_OK:
397 DCHECK_GE(buf_index, 0); 393 DCHECK_GE(buf_index, 0);
398 break; 394 break;
399 395
400 default: 396 default:
401 NOTREACHED(); 397 NOTREACHED();
402 break; 398 break;
403 } 399 }
404 } while (buf_index < 0); 400 } while (buf_index < 0);
405 401
406 media::BitstreamBuffer bitstream_buffer = available_bitstream_buffers_.back(); 402 BitstreamBuffer bitstream_buffer = available_bitstream_buffers_.back();
407 available_bitstream_buffers_.pop_back(); 403 available_bitstream_buffers_.pop_back();
408 std::unique_ptr<SharedMemoryRegion> shm( 404 std::unique_ptr<SharedMemoryRegion> shm(
409 new SharedMemoryRegion(bitstream_buffer, false)); 405 new SharedMemoryRegion(bitstream_buffer, false));
410 RETURN_ON_FAILURE(shm->Map(), "Failed to map SHM", kPlatformFailureError); 406 RETURN_ON_FAILURE(shm->Map(), "Failed to map SHM", kPlatformFailureError);
411 RETURN_ON_FAILURE(size <= shm->size(), 407 RETURN_ON_FAILURE(size <= shm->size(),
412 "Encoded buffer too large: " << size << ">" << shm->size(), 408 "Encoded buffer too large: " << size << ">" << shm->size(),
413 kPlatformFailureError); 409 kPlatformFailureError);
414 410
415 media::MediaCodecStatus status = media_codec_->CopyFromOutputBuffer( 411 MediaCodecStatus status = media_codec_->CopyFromOutputBuffer(
416 buf_index, offset, shm->memory(), size); 412 buf_index, offset, shm->memory(), size);
417 RETURN_ON_FAILURE(status == media::MEDIA_CODEC_OK, 413 RETURN_ON_FAILURE(status == MEDIA_CODEC_OK, "CopyFromOutputBuffer failed",
418 "CopyFromOutputBuffer failed", kPlatformFailureError); 414 kPlatformFailureError);
419 media_codec_->ReleaseOutputBuffer(buf_index, false); 415 media_codec_->ReleaseOutputBuffer(buf_index, false);
420 --num_buffers_at_codec_; 416 --num_buffers_at_codec_;
421 417
422 base::ThreadTaskRunnerHandle::Get()->PostTask( 418 base::ThreadTaskRunnerHandle::Get()->PostTask(
423 FROM_HERE, 419 FROM_HERE,
424 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, 420 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady,
425 client_ptr_factory_->GetWeakPtr(), bitstream_buffer.id(), size, 421 client_ptr_factory_->GetWeakPtr(), bitstream_buffer.id(), size,
426 key_frame, base::Time::Now() - base::Time())); 422 key_frame, base::Time::Now() - base::Time()));
427 } 423 }
428 424
429 } // namespace media 425 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_encode_accelerator.h ('k') | media/gpu/avda_codec_image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698