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

Side by Side Diff: media/capture/video/chromeos/camera_device_delegate.cc

Issue 2837273004: media: add video capture device for ARC++ camera HAL v3 (Closed)
Patch Set: Created 3 years, 7 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
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/capture/video/chromeos/camera_device_delegate.h"
6
7 #include <libdrm/drm_fourcc.h>
8
9 #include "media/capture/video/chromeos/camera_metadata_utils.h"
10 #include "mojo/edk/embedder/embedder.h"
11 #include "mojo/edk/embedder/scoped_platform_handle.h"
12 #include "third_party/libsync/include/sync/sync.h"
13
14 namespace media {
15
16 using namespace arc::mojom;
17
18 namespace {
19
20 struct SupportedFormat {
21 VideoPixelFormat chromium_format;
22 HalPixelFormat hal_format;
23 uint32_t drm_format;
24 } const kSupportedFormats[] = {
25 {PIXEL_FORMAT_I420, HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888,
26 DRM_FORMAT_YUV420},
27 {PIXEL_FORMAT_RGB32,
28 HalPixelFormat::HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
29 DRM_FORMAT_XBGR8888},
30 };
31
32 } // namespace
33
34 CameraDeviceDelegate::CameraDeviceDelegate(
35 VideoCaptureDeviceDescriptor device_descriptor,
36 arc::mojom::CameraMetadataPtr static_metadata,
37 mojo::InterfacePtrInfo<Camera3DeviceOps> device_ops_info,
38 const scoped_refptr<base::SingleThreadTaskRunner> device_task_runner)
39 : device_descriptor_(device_descriptor),
40 static_metadata_(std::move(static_metadata)),
41 state_(kStopped),
42 rotation_(0),
43 device_ops_info_(std::move(device_ops_info)),
44 callback_ops_(this),
45 device_task_runner_(device_task_runner),
46 frame_number_(0),
47 partial_result_count_(1),
48 first_frame_shutter_time_(base::TimeTicks::Now()) {}
49
50 // static
51 VideoPixelFormat CameraDeviceDelegate::PixFormatHalToChromium(
52 HalPixelFormat from) {
53 auto it =
54 std::find_if(std::begin(kSupportedFormats), std::end(kSupportedFormats),
55 [from](SupportedFormat f) { return f.hal_format == from; });
56 if (it == std::end(kSupportedFormats)) {
57 return PIXEL_FORMAT_UNKNOWN;
58 }
59 return it->chromium_format;
60 }
61
62 // static
63 uint32_t CameraDeviceDelegate::PixFormatChromiumToDrm(VideoPixelFormat from) {
64 auto it = std::find_if(
65 std::begin(kSupportedFormats), std::end(kSupportedFormats),
66 [from](SupportedFormat f) { return f.chromium_format == from; });
67 if (it == std::end(kSupportedFormats)) {
68 return 0;
69 }
70 return it->drm_format;
71 }
72
73 void CameraDeviceDelegate::AllocateAndStart(
74 const VideoCaptureParams& params,
75 std::unique_ptr<VideoCaptureDevice::Client> client) {
76 DCHECK(device_task_runner_->BelongsToCurrentThread());
77 DCHECK(!client_);
78 DCHECK(state_ = kStopped);
79 const CameraMetadataEntryPtr* partial_count =
80 GetMetadataEntry(static_metadata_,
81 CameraMetadataTag::ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
82 // The partial result count metadata is optional. It defaults to 1 in case it
83 // is not set in the static metadata.
84 if (partial_count) {
85 partial_result_count_ =
86 *reinterpret_cast<int32_t*>((*partial_count)->data.data());
87 }
88
89 client_ = std::move(client);
90 device_ops_.Bind(std::move(device_ops_info_), device_task_runner_);
91 device_ops_.set_connection_error_handler(
92 base::Bind(&CameraDeviceDelegate::OnMojoConnectionError, this));
93 frame_number_ = 0;
94 streams_.clear();
95 partial_results_.clear();
96
97 // Set up context for preview stream.
98 Camera3StreamPtr preview_stream = Camera3Stream::New();
99 preview_stream->id =
100 static_cast<uint64_t>(Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW);
101 preview_stream->stream_type = Camera3StreamType::CAMERA3_STREAM_OUTPUT;
102 preview_stream->width = params.requested_format.frame_size.width();
103 preview_stream->height = params.requested_format.frame_size.height();
104 // preview_stream->format = HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888;
105 // TODO(jcliang): We should not use implementation defined format here.
106 preview_stream->format =
107 HalPixelFormat::HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
108 preview_stream->data_space = 0;
109 preview_stream->rotation = Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
110 streams_[Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW] = {
111 .params = params, .stream = std::move(preview_stream),
112 };
113 // TODO(jcliang): Set up context for still capture stream.
114
115 SetState(kStarting);
116 Initialize();
117 }
118
119 void CameraDeviceDelegate::StopAndDeAllocate(base::WaitableEvent* closed) {
120 DCHECK(device_task_runner_->BelongsToCurrentThread());
121 // StopAndDeAllocate may be called at any state.
122
123 if (!device_ops_.is_bound() || state_ == kStopping) {
124 // In case of Mojo connection error |device_ops_| and |callback_ops_| are
125 // unbound.
126 return;
127 }
128 SetState(kStopping);
129 device_ops_->Close(base::Bind(&CameraDeviceDelegate::OnClosed, this,
130 base::Unretained(closed)));
131 }
132
133 void CameraDeviceDelegate::TakePhoto(
134 VideoCaptureDevice::TakePhotoCallback callback) {
135 DCHECK(device_task_runner_->BelongsToCurrentThread());
136 }
137
138 void CameraDeviceDelegate::GetPhotoCapabilities(
139 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
140 DCHECK(device_task_runner_->BelongsToCurrentThread());
141 }
142
143 void CameraDeviceDelegate::SetPhotoOptions(
144 mojom::PhotoSettingsPtr settings,
145 VideoCaptureDevice::SetPhotoOptionsCallback callback) {
146 DCHECK(device_task_runner_->BelongsToCurrentThread());
147 }
148
149 void CameraDeviceDelegate::SetRotation(int rotation) {
150 DCHECK(device_task_runner_->BelongsToCurrentThread());
151 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0);
152 rotation_ = rotation;
153 }
154
155 void CameraDeviceDelegate::SetState(State state) {
156 state_ = state;
157 }
158
159 void CameraDeviceDelegate::SetErrorState(
160 const tracked_objects::Location& from_here,
161 const std::string& reason) {
162 state_ = kError;
163 client_->OnError(from_here, reason);
164 }
165
166 void CameraDeviceDelegate::ResetMojoInterface() {
167 DCHECK(device_task_runner_->BelongsToCurrentThread());
168 device_ops_.reset();
169 if (callback_ops_.is_bound()) {
170 callback_ops_.Unbind();
171 }
172 }
173
174 void CameraDeviceDelegate::OnMojoConnectionError() {
175 DCHECK(device_task_runner_->BelongsToCurrentThread());
176 ResetMojoInterface();
177 SetErrorState(FROM_HERE, "Mojo connection error");
178 }
179
180 void CameraDeviceDelegate::OnClosed(base::WaitableEvent* closed,
181 int32_t result) {
182 DCHECK(device_task_runner_->BelongsToCurrentThread());
183 ResetMojoInterface();
184 client_.reset();
185 SetState(kStopped);
186 closed->Signal();
187 }
188
189 void CameraDeviceDelegate::Initialize() {
190 DCHECK(device_task_runner_->BelongsToCurrentThread());
191 DCHECK(state_ == kStarting);
192
193 device_ops_->Initialize(
194 callback_ops_.CreateInterfacePtrAndBind(),
195 base::Bind(&CameraDeviceDelegate::OnInitialized, this));
196 callback_ops_.set_connection_error_handler(
197 base::Bind(&CameraDeviceDelegate::OnMojoConnectionError, this));
198 }
199
200 void CameraDeviceDelegate::OnInitialized(int32_t result) {
201 DCHECK(device_task_runner_->BelongsToCurrentThread());
202 DCHECK(state_ == kStarting || state_ == kStopping);
203
204 if (state_ == kStopping) {
205 return;
206 }
207 if (result) {
208 SetErrorState(FROM_HERE, "Failed to initialize camera device");
209 return;
210 }
211 SetState(kInitialized);
212 ConfigureStreams();
213 }
214
215 void CameraDeviceDelegate::ConfigureStreams() {
216 DCHECK(device_task_runner_->BelongsToCurrentThread());
217 DCHECK(state_ == kInitialized || state_ == kStopping);
218
219 Camera3StreamConfigurationPtr stream_config =
220 Camera3StreamConfiguration::New();
221 stream_config->num_streams = streams_.size();
222 for (const auto& context : streams_) {
223 stream_config->streams.push_back(context.second.stream.Clone());
224 }
225 stream_config->operation_mode =
226 Camera3StreamConfigurationMode::CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
227 device_ops_->ConfigureStreams(
228 std::move(stream_config),
229 base::Bind(&CameraDeviceDelegate::OnConfiguredStreams, this));
230 }
231
232 void CameraDeviceDelegate::OnConfiguredStreams(
233 Camera3StreamConfigurationPtr updated_config) {
234 DCHECK(device_task_runner_->BelongsToCurrentThread());
235 DCHECK(state_ == kInitialized || state_ == kStopping);
236
237 if (state_ == kStopping) {
238 return;
239 }
240 for (size_t i = 0; i < updated_config->num_streams; ++i) {
241 auto& updated_stream = updated_config->streams[i];
242 Camera3RequestTemplate stream_type =
243 static_cast<Camera3RequestTemplate>(updated_stream->id);
244 StreamContext* stream_context = GetStreamContext(stream_type);
245 if (!stream_context) {
246 SetErrorState(FROM_HERE, "ConfigureStreams returned invalid stream");
247 continue;
248 }
249 // TODO(jcliang): Determine the best format from metadata.
250 VideoCaptureFormat capture_format = stream_context->params.requested_format;
251 capture_format.pixel_format = PIXEL_FORMAT_RGB32;
252 stream_context->capture_format = capture_format;
253 stream_context->stream->usage = updated_stream->usage;
254 stream_context->stream->max_buffers = updated_stream->max_buffers;
255
256 VLOG(2) << "Stream " << updated_stream->id
257 << " configured: usage=" << updated_stream->usage
258 << " max_buffers=" << updated_stream->max_buffers;
259
260 // Allocate buffers.
261 size_t num_buffers = stream_context->stream->max_buffers;
262 stream_context->buffers.resize(num_buffers);
263 for (size_t j = 0; j < num_buffers; ++j) {
264 const VideoCaptureFormat frame_format(
265 gfx::Size(stream_context->stream->width,
266 stream_context->stream->height),
267 0.0, stream_context->capture_format.pixel_format);
268 std::unique_ptr<base::SharedMemory> buffer(new base::SharedMemory());
269 base::SharedMemoryCreateOptions options;
270 options.size = frame_format.ImageAllocationSize();
271 options.share_read_only = false;
272 buffer->Create(options);
273 buffer->Map(buffer->requested_size());
274 stream_context->buffers[j] = std::move(buffer);
275 stream_context->free_buffers.push(j);
276 }
277 VLOG(2) << "Allocated " << stream_context->stream->max_buffers
278 << " buffers for stream " << stream_type;
279
280 // TODO(jcliang): Construct default request settings for still capture.
281 ConstructDefaultRequestSettings(
282 Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW);
283 }
284
285 client_->OnStarted();
286 }
287
288 void CameraDeviceDelegate::ConstructDefaultRequestSettings(
289 Camera3RequestTemplate stream_type) {
290 DCHECK(device_task_runner_->BelongsToCurrentThread());
291 DCHECK(GetStreamContext(stream_type));
292
293 device_ops_->ConstructDefaultRequestSettings(
294 stream_type,
295 base::Bind(&CameraDeviceDelegate::OnConstructedDefaultRequestSettings,
296 this, stream_type));
297 }
298
299 void CameraDeviceDelegate::OnConstructedDefaultRequestSettings(
300 Camera3RequestTemplate stream_type,
301 CameraMetadataPtr settings) {
302 DCHECK(device_task_runner_->BelongsToCurrentThread());
303
304 if (state_ == kStopping) {
305 return;
306 }
307 StreamContext* stream_context = GetStreamContext(stream_type);
308 DCHECK(stream_context);
309 stream_context->request_settings = std::move(settings);
310 // TODO(jcliang): Once we have the still capture stream we need to change it
311 // to only SetState when both preview and still capture streams
312 // are configured.
313 SetState(kStreamConfigured);
314 if (stream_type == Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW) {
315 StartCapture(stream_type);
316 }
317 }
318
319 void CameraDeviceDelegate::StartCapture(Camera3RequestTemplate stream_type) {
320 DCHECK(device_task_runner_->BelongsToCurrentThread());
321 // We may get here when either after the streams are configured, or when we
322 // start still capture while the preview capture is running.
323 DCHECK(state_ == kStreamConfigured || state_ == kCapturing ||
324 state_ == kStopping);
325
326 if (state_ == kStopping) {
327 return;
328 }
329 StreamContext* stream_context = GetStreamContext(stream_type);
330 DCHECK(stream_context);
331 DCHECK(!stream_context->request_settings.is_null());
332 SetState(kCapturing);
333 RegisterBuffer(stream_type);
334 }
335
336 void CameraDeviceDelegate::RegisterBuffer(Camera3RequestTemplate stream_type) {
337 DCHECK(device_task_runner_->BelongsToCurrentThread());
338 DCHECK(state_ == kCapturing || state_ == kStopping);
339
340 if (state_ == kStopping) {
341 return;
342 }
343 StreamContext* stream_context = GetStreamContext(stream_type);
344 DCHECK(stream_context);
345 if (stream_context->free_buffers.empty()) {
346 return;
347 }
348
349 const VideoCaptureParams& params = stream_context->params;
350 const Camera3StreamPtr& stream = stream_context->stream;
351 size_t buffer_id = stream_context->free_buffers.front();
352 stream_context->free_buffers.pop();
353 const base::SharedMemory* buffer = stream_context->buffers[buffer_id].get();
354
355 VideoPixelFormat buffer_format = stream_context->capture_format.pixel_format;
356 uint32_t drm_format = PixFormatChromiumToDrm(buffer_format);
357 if (!drm_format) {
358 SetErrorState(FROM_HERE, "Unsupported video pixel format");
359 return;
360 }
361 HalPixelFormat hal_pixel_format = stream->format;
362
363 size_t num_planes = VideoFrame::NumPlanes(buffer_format);
364 std::vector<mojo::ScopedHandle> fds(num_planes);
365 std::vector<uint32_t> strides(num_planes);
366 std::vector<uint32_t> offsets(num_planes);
367 for (size_t i = 0; i < num_planes; ++i) {
368 base::SharedMemoryHandle shm_handle = buffer->handle();
369 // Wrap the platform handle.
370 MojoHandle wrapped_handle;
371 MojoResult result = mojo::edk::CreatePlatformHandleWrapper(
372 mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(
373 base::SharedMemory::DuplicateHandle(shm_handle).fd)),
374 &wrapped_handle);
375 if (result != MOJO_RESULT_OK) {
376 SetErrorState(FROM_HERE, "Failed to wrap shared memory handle");
377 return;
378 }
379 fds[i].reset(mojo::Handle(wrapped_handle));
380 strides[i] = VideoFrame::RowBytes(i, buffer_format, stream->width);
381 if (!i) {
382 offsets[i] = 0;
383 } else {
384 offsets[i] = offsets[i - 1] +
385 VideoFrame::PlaneSize(buffer_format, i,
386 params.requested_format.frame_size)
387 .GetArea();
388 }
389 }
390 device_ops_->RegisterBuffer(
391 buffer_id, Camera3DeviceOps::BufferType::SHM, std::move(fds), drm_format,
392 hal_pixel_format, stream_context->stream->width,
393 stream_context->stream->height, std::move(strides), std::move(offsets),
394 base::Bind(&CameraDeviceDelegate::OnRegisteredBuffer, this, stream_type,
395 buffer_id));
396 VLOG(2) << "Registered buffer " << buffer_id << " of stream " << stream_type;
397 }
398
399 void CameraDeviceDelegate::OnRegisteredBuffer(
400 Camera3RequestTemplate stream_type,
401 size_t buffer_index,
402 int32_t result) {
403 DCHECK(device_task_runner_->BelongsToCurrentThread());
404 DCHECK(state_ == kCapturing || state_ == kStopping);
405
406 if (state_ == kStopping) {
407 return;
408 }
409 if (result) {
410 SetErrorState(FROM_HERE, "Failed to register buffer");
411 return;
412 }
413 ProcessCaptureRequest(stream_type, buffer_index);
414 }
415
416 void CameraDeviceDelegate::ProcessCaptureRequest(
417 Camera3RequestTemplate stream_type,
418 size_t buffer_index) {
419 DCHECK(device_task_runner_->BelongsToCurrentThread());
420 DCHECK(state_ == kCapturing || state_ == kStopping);
421
422 StreamContext* stream_context = GetStreamContext(stream_type);
423 DCHECK(stream_context);
424
425 Camera3StreamBufferPtr buffer = Camera3StreamBuffer::New();
426 buffer->stream_id =
427 static_cast<uint64_t>(Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW);
428 buffer->buffer_id = buffer_index;
429 buffer->status = Camera3BufferStatus::CAMERA3_BUFFER_STATUS_OK;
430
431 // TODO(jcliang): Also process still capture buffers after we enabled still
432 // capture stream.
433 Camera3CaptureRequestPtr request = Camera3CaptureRequest::New();
434 request->frame_number = frame_number_;
435 request->settings = stream_context->request_settings.Clone();
436 request->num_output_buffers = 1;
437 request->output_buffers.push_back(std::move(buffer));
438
439 device_ops_->ProcessCaptureRequest(
440 std::move(request),
441 base::Bind(&CameraDeviceDelegate::OnProcessedCaptureRequest, this,
442 stream_type));
443 VLOG(2) << "Requested capture for frame " << frame_number_ << " with buffer "
444 << buffer_index << " of stream " << stream_type;
445 frame_number_++;
446 }
447
448 void CameraDeviceDelegate::OnProcessedCaptureRequest(
449 Camera3RequestTemplate stream_type,
450 int32_t result) {
451 DCHECK(device_task_runner_->BelongsToCurrentThread());
452 DCHECK(state_ == kCapturing || state_ == kStopping);
453
454 if (state_ == kStopping) {
455 return;
456 }
457 if (result) {
458 SetErrorState(FROM_HERE, "Process capture request failed");
459 return;
460 }
461 RegisterBuffer(stream_type);
462 }
463
464 void CameraDeviceDelegate::ProcessCaptureResult(
465 arc::mojom::Camera3CaptureResultPtr result) {
466 DCHECK(device_task_runner_->BelongsToCurrentThread());
467
468 uint32_t frame_number = result->frame_number;
469 CaptureResult& partial_result = partial_results_[frame_number];
470 for (size_t i = 0; i < result->num_output_buffers; ++i) {
471 Camera3StreamBufferPtr& stream_buffer = result->output_buffers.value()[i];
472 Camera3RequestTemplate stream_type =
473 static_cast<Camera3RequestTemplate>(stream_buffer->stream_id);
474 // The camera HAL v3 API specifies that only one capture result can carry
475 // the result buffer for any given frame number.
476 if (partial_result.buffers.find(stream_type) !=
477 partial_result.buffers.end()) {
478 client_->OnLog(
479 std::string("Received multiple result buffers for frame ") +
480 std::to_string(frame_number));
481 continue;
482 }
483 if (stream_buffer->status ==
484 Camera3BufferStatus::CAMERA3_BUFFER_STATUS_ERROR) {
485 // TODO(jcliang): Discard buffer and continue maybe?
486 SetErrorState(FROM_HERE, "HAL encountered error while filling bufer");
487 return;
488 }
489 partial_results_[frame_number].buffers[stream_type] =
490 std::move(stream_buffer);
491 }
492
493 // |result->partial_result| is set to 0 if the capture result contains only
494 // the result buffer handles and no result metadata.
495 if (result->partial_result) {
496 partial_results_[frame_number].partial_stage = result->partial_result;
497 MergeMetadata(&partial_results_[frame_number].metadata, result->result);
498 }
499
500 if (partial_result.partial_stage == partial_result_count_) {
501 // This is the last capture results for the requests of this frame number.
502 auto it = partial_results_.find(frame_number);
503 // We can only submit the result buffer after we receive the shutter time.
504 if (it->second.reference_time != base::TimeTicks()) {
505 SubmitCaptureResult(frame_number);
506 }
507 }
508 }
509
510 void CameraDeviceDelegate::Notify(arc::mojom::Camera3NotifyMsgPtr message) {
511 // TODO(jcliang): unit tests.
512 DCHECK(device_task_runner_->BelongsToCurrentThread());
513
514 if (message->type == Camera3MsgType::CAMERA3_MSG_ERROR) {
515 // TODO(jcliang): Handle error notify.
516 } else { // Camera3MsgType::CAMERA3_MSG_SHUTTER
517 uint32_t frame_number = message->message->get_shutter()->frame_number;
518 uint64_t shutter_time = message->message->get_shutter()->timestamp;
519 CaptureResult& partial_result = partial_results_[frame_number];
520 // Shutter timestamp is in ns.
521 base::TimeTicks reference_time =
522 base::TimeTicks::FromInternalValue(shutter_time / 1000);
523 partial_result.reference_time = reference_time;
524 if (!frame_number) {
525 // Record the shutter time of the first frame for calculating the
526 // timestamp.
527 first_frame_shutter_time_ = reference_time;
528 partial_result.timestamp = base::TimeDelta::FromMicroseconds(0);
529 } else {
530 partial_result.timestamp = reference_time - first_frame_shutter_time_;
531 }
532 if (partial_result.partial_stage == partial_result_count_) {
533 SubmitCaptureResult(frame_number);
534 }
535 }
536 }
537
538 void CameraDeviceDelegate::SubmitCaptureResult(uint32_t frame_number) {
539 DCHECK(device_task_runner_->BelongsToCurrentThread());
540
541 if (partial_results_.begin()->first != frame_number) {
542 SetErrorState(FROM_HERE, "Received out-of-order frames from HAL");
543 return;
544 }
545
546 CaptureResult& partial_result = partial_results_[frame_number];
547 DCHECK_EQ(partial_result.partial_stage, partial_result_count_);
548 for (const auto& it : partial_result.buffers) {
549 Camera3RequestTemplate stream_type = it.first;
550 StreamContext* stream_context = GetStreamContext(stream_type);
551 const Camera3StreamBufferPtr& buffer = it.second;
552 uint32_t buffer_id = buffer->buffer_id;
553
554 // Wait on release fence before delivering the result buffer to client.
555 if (buffer->release_fence.is_valid()) {
556 const int kSyncWaitTimeoutMs = 1000;
557 mojo::edk::ScopedPlatformHandle fence;
558 MojoResult result = mojo::edk::PassWrappedPlatformHandle(
559 buffer->release_fence.release().value(), &fence);
560 if (result != MOJO_RESULT_OK) {
561 SetErrorState(FROM_HERE, "Failed to unwrap release fence fd");
562 return;
563 }
564 if (!sync_wait(fence.get().handle, kSyncWaitTimeoutMs)) {
565 SetErrorState(FROM_HERE, "Sync wait on release fence timed out");
566 return;
567 }
568 }
569
570 if (stream_type == Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW) {
571 // Deliver the captured data to client and then re-queue the buffer.
572 const base::SharedMemory* buffer =
573 stream_context->buffers[buffer_id].get();
574 client_->OnIncomingCapturedData(
575 reinterpret_cast<uint8_t*>(buffer->memory()), buffer->mapped_size(),
576 stream_context->capture_format, rotation_,
577 partial_result.reference_time, partial_result.timestamp);
578 stream_context->free_buffers.push(buffer_id);
579 device_task_runner_->PostTask(
580 FROM_HERE,
581 base::Bind(&CameraDeviceDelegate::RegisterBuffer, this,
582 Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW));
583 }
584 // TODO(jcliang): Handle still capture result for TakePhoto.
585 }
586 partial_results_.erase(frame_number);
587 }
588
589 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698