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

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

Powered by Google App Engine
This is Rietveld 408576698