1 /*
2 * v4l2_device.cpp - v4l2 device
3 *
4 * Copyright (c) 2014-2015 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 * Author: John Ye <john.ye@intel.com>
20 */
21
22 #include "v4l2_device.h"
23 #include <sys/ioctl.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <poll.h>
28 #include <errno.h>
29 #include <sys/mman.h>
30
31 #include "v4l2_buffer_proxy.h"
32
33 namespace XCam {
34
35 #define XCAM_V4L2_DEFAULT_BUFFER_COUNT 6
36
V4l2Device(const char * name)37 V4l2Device::V4l2Device (const char *name)
38 : _name (NULL)
39 , _fd (-1)
40 , _sensor_id (0)
41 , _capture_mode (0)
42 , _capture_buf_type (V4L2_BUF_TYPE_VIDEO_CAPTURE)
43 , _memory_type (V4L2_MEMORY_MMAP)
44 , _fps_n (0)
45 , _fps_d (0)
46 , _active (false)
47 , _buf_count (XCAM_V4L2_DEFAULT_BUFFER_COUNT)
48 {
49 if (name)
50 _name = strndup (name, XCAM_MAX_STR_SIZE);
51 xcam_mem_clear (_format);
52 }
53
~V4l2Device()54 V4l2Device::~V4l2Device ()
55 {
56 close();
57 if (_name)
58 xcam_free (_name);
59 }
60
61 bool
set_device_name(const char * name)62 V4l2Device::set_device_name (const char *name)
63 {
64 XCAM_ASSERT (name);
65
66 if (is_opened()) {
67 XCAM_LOG_WARNING ("can't set device name since device opened");
68 return false;
69 }
70 if (_name)
71 xcam_free (_name);
72 _name = strndup (name, XCAM_MAX_STR_SIZE);
73 return true;
74 }
75
76 bool
set_sensor_id(int id)77 V4l2Device::set_sensor_id (int id)
78 {
79 if (is_opened()) {
80 XCAM_LOG_WARNING ("can't set sensor id since device opened");
81 return false;
82 }
83 _sensor_id = id;
84 return true;
85 }
86
87 bool
set_capture_mode(uint32_t capture_mode)88 V4l2Device::set_capture_mode (uint32_t capture_mode)
89 {
90 if (is_opened()) {
91 XCAM_LOG_WARNING ("can't set sensor id since device opened");
92 return false;
93 }
94 _capture_mode = capture_mode;
95 return true;
96 }
97
98 bool
set_framerate(uint32_t n,uint32_t d)99 V4l2Device::set_framerate (uint32_t n, uint32_t d)
100 {
101 if (_format.fmt.pix.pixelformat) {
102 XCAM_LOG_WARNING ("device(%s) set framerate failed since formatted was already set.", XCAM_STR(_name));
103 return false;
104 }
105
106 _fps_n = n;
107 _fps_d = d;
108
109 return true;
110 }
111
112 void
get_framerate(uint32_t & n,uint32_t & d)113 V4l2Device::get_framerate (uint32_t &n, uint32_t &d)
114 {
115 n = _fps_n;
116 d = _fps_d;
117 }
118
119 bool
set_mem_type(enum v4l2_memory type)120 V4l2Device::set_mem_type (enum v4l2_memory type) {
121 if (is_activated ()) {
122 XCAM_LOG_WARNING ("device(%s) set mem type failed", XCAM_STR (_name));
123 return false;
124 }
125 _memory_type = type;
126 return true;
127 }
128
129 bool
set_buffer_count(uint32_t buf_count)130 V4l2Device::set_buffer_count (uint32_t buf_count)
131 {
132 if (is_activated ()) {
133 XCAM_LOG_WARNING ("device(%s) set buffer count failed", XCAM_STR (_name));
134 return false;
135 }
136 _buf_count = buf_count;
137 return true;
138 }
139
140
141 XCamReturn
open()142 V4l2Device::open ()
143 {
144 struct v4l2_streamparm param;
145
146 if (is_opened()) {
147 XCAM_LOG_DEBUG ("device(%s) was already opened", XCAM_STR(_name));
148 return XCAM_RETURN_NO_ERROR;
149 }
150
151 if (!_name) {
152 XCAM_LOG_DEBUG ("v4l2 device open failed, there's no device name");
153 return XCAM_RETURN_ERROR_PARAM;
154 }
155 _fd = ::open (_name, O_RDWR);
156 if (_fd == -1) {
157 XCAM_LOG_DEBUG ("open device(%s) failed", _name);
158 return XCAM_RETURN_ERROR_IOCTL;
159 }
160
161 // set sensor id
162 if (io_control (VIDIOC_S_INPUT, &_sensor_id) < 0) {
163 XCAM_LOG_WARNING ("set sensor id(%d) failed but continue", _sensor_id);
164 }
165
166 // set capture mode
167 xcam_mem_clear (param);
168 param.type = _capture_buf_type;
169 param.parm.capture.capturemode = _capture_mode;
170 if (io_control (VIDIOC_S_PARM, ¶m) < 0) {
171 XCAM_LOG_WARNING ("set capture mode(0x%08x) failed but continue", _capture_mode);
172 }
173
174 return XCAM_RETURN_NO_ERROR;
175 }
176
177 XCamReturn
close()178 V4l2Device::close ()
179 {
180 if (!is_opened())
181 return XCAM_RETURN_NO_ERROR;
182 ::close (_fd);
183 _fd = -1;
184 return XCAM_RETURN_NO_ERROR;
185 }
186
187 int
io_control(int cmd,void * arg)188 V4l2Device::io_control (int cmd, void *arg)
189
190 {
191 if (_fd <= 0)
192 return -1;
193
194 return xcam_device_ioctl (_fd, cmd, arg);
195 }
196
197 int
poll_event(int timeout_msec)198 V4l2Device::poll_event (int timeout_msec)
199 {
200 struct pollfd poll_fd;
201 int ret = 0;
202
203 XCAM_ASSERT (_fd > 0);
204
205 xcam_mem_clear (poll_fd);
206 poll_fd.fd = _fd;
207 poll_fd.events = (POLLPRI | POLLIN | POLLERR | POLLNVAL | POLLHUP);
208
209 ret = poll (&poll_fd, 1, timeout_msec);
210 if (ret > 0 && (poll_fd.revents & (POLLERR | POLLNVAL | POLLHUP))) {
211 XCAM_LOG_DEBUG ("v4l2 subdev(%s) polled error", XCAM_STR(_name));
212 return -1;
213 }
214 return ret;
215
216 }
217
218 XCamReturn
set_format(struct v4l2_format & format)219 V4l2Device::set_format (struct v4l2_format &format)
220 {
221 XCamReturn ret = XCAM_RETURN_NO_ERROR;
222
223 XCAM_FAIL_RETURN (ERROR, !is_activated (), XCAM_RETURN_ERROR_PARAM,
224 "Cannot set format to v4l2 device while it is active.");
225
226 XCAM_FAIL_RETURN (ERROR, is_opened (), XCAM_RETURN_ERROR_FILE,
227 "Cannot set format to v4l2 device while it is closed.");
228
229 struct v4l2_format tmp_format = format;
230
231 ret = pre_set_format (format);
232 if (ret != XCAM_RETURN_NO_ERROR) {
233 XCAM_LOG_WARNING ("device(%s) pre_set_format failed", XCAM_STR (_name));
234 return ret;
235 }
236
237 if (io_control (VIDIOC_S_FMT, &format) < 0) {
238 if (errno == EBUSY) {
239 // TODO log device name
240 XCAM_LOG_ERROR("Video device is busy, fail to set format.");
241 } else {
242 // TODO log format details and errno
243 XCAM_LOG_ERROR("Fail to set format: %s", strerror(errno));
244 }
245
246 return XCAM_RETURN_ERROR_IOCTL;
247 }
248
249 if (tmp_format.fmt.pix.width != format.fmt.pix.width || tmp_format.fmt.pix.height != format.fmt.pix.height) {
250 XCAM_LOG_ERROR (
251 "device(%s) set v4l2 format failed, supported format: width:%d, height:%d",
252 XCAM_STR (_name),
253 format.fmt.pix.width,
254 format.fmt.pix.height);
255
256 return XCAM_RETURN_ERROR_PARAM;
257 }
258
259 while (_fps_n && _fps_d) {
260 struct v4l2_streamparm param;
261 xcam_mem_clear (param);
262 param.type = _capture_buf_type;
263 if (io_control (VIDIOC_G_PARM, ¶m) < 0) {
264 XCAM_LOG_WARNING ("device(%s) set framerate failed on VIDIOC_G_PARM but continue", XCAM_STR (_name));
265 break;
266 }
267
268 if (!(param.parm.capture.capability & V4L2_CAP_TIMEPERFRAME))
269 break;
270
271 param.parm.capture.timeperframe.numerator = _fps_d;
272 param.parm.capture.timeperframe.denominator = _fps_n;
273
274 if (io_control (VIDIOC_S_PARM, ¶m) < 0) {
275 XCAM_LOG_WARNING ("device(%s) set framerate failed on VIDIOC_S_PARM but continue", XCAM_STR (_name));
276 break;
277 }
278 _fps_n = param.parm.capture.timeperframe.denominator;
279 _fps_d = param.parm.capture.timeperframe.numerator;
280 XCAM_LOG_INFO ("device(%s) set framerate(%d/%d)", XCAM_STR (_name), _fps_n, _fps_d);
281
282 // exit here, otherwise it is an infinite loop
283 break;
284 }
285
286 ret = post_set_format (format);
287 if (ret != XCAM_RETURN_NO_ERROR) {
288 XCAM_LOG_WARNING ("device(%s) post_set_format failed", XCAM_STR (_name));
289 return ret;
290 }
291
292 _format = format;
293 XCAM_LOG_INFO (
294 "device(%s) set format(w:%d, h:%d, pixelformat:%s, bytesperline:%d,image_size:%d)",
295 XCAM_STR (_name),
296 format.fmt.pix.width, format.fmt.pix.height,
297 xcam_fourcc_to_string (format.fmt.pix.pixelformat),
298 format.fmt.pix.bytesperline,
299 format.fmt.pix.sizeimage);
300
301 return XCAM_RETURN_NO_ERROR;
302 }
303
304 /*! \brief v4l2 set format
305 *
306 * \param[in] width format width
307 * \param[in] height format height
308 * \param[in] pixelformat fourcc
309 * \param[in] field V4L2_FIELD_INTERLACED or V4L2_FIELD_NONE
310 */
311 XCamReturn
set_format(uint32_t width,uint32_t height,uint32_t pixelformat,enum v4l2_field field,uint32_t bytes_perline)312 V4l2Device::set_format (
313 uint32_t width, uint32_t height,
314 uint32_t pixelformat, enum v4l2_field field, uint32_t bytes_perline)
315 {
316
317 struct v4l2_format format;
318 xcam_mem_clear (format);
319
320 format.type = _capture_buf_type;
321 format.fmt.pix.width = width;
322 format.fmt.pix.height = height;
323 format.fmt.pix.pixelformat = pixelformat;
324 format.fmt.pix.field = field;
325
326 if (bytes_perline != 0)
327 format.fmt.pix.bytesperline = bytes_perline;
328 return set_format (format);
329 }
330
331 XCamReturn
pre_set_format(struct v4l2_format & format)332 V4l2Device::pre_set_format (struct v4l2_format &format)
333 {
334 XCAM_UNUSED (format);
335 return XCAM_RETURN_NO_ERROR;
336 }
337
338 XCamReturn
post_set_format(struct v4l2_format & format)339 V4l2Device::post_set_format (struct v4l2_format &format)
340 {
341 XCAM_UNUSED (format);
342 return XCAM_RETURN_NO_ERROR;
343 }
344
345 std::list<struct v4l2_fmtdesc>
enum_formats()346 V4l2Device::enum_formats ()
347 {
348 std::list<struct v4l2_fmtdesc> formats;
349 struct v4l2_fmtdesc format;
350 uint32_t i = 0;
351
352 while (1) {
353 xcam_mem_clear (format);
354 format.index = i++;
355 format.type = _capture_buf_type;
356 if (this->io_control (VIDIOC_ENUM_FMT, &format) < 0) {
357 if (errno == EINVAL)
358 break;
359 else { // error
360 XCAM_LOG_DEBUG ("enum formats failed");
361 return formats;
362 }
363 }
364 formats.push_back (format);
365 }
366
367 return formats;
368 }
369
370 XCamReturn
get_format(struct v4l2_format & format)371 V4l2Device::get_format (struct v4l2_format &format)
372 {
373 if (is_activated ()) {
374 format = _format;
375 return XCAM_RETURN_NO_ERROR;
376 }
377
378 if (!is_opened ())
379 return XCAM_RETURN_ERROR_IOCTL;
380
381 xcam_mem_clear (format);
382 format.type = _capture_buf_type;
383
384 if (this->io_control (VIDIOC_G_FMT, &format) < 0) {
385 // FIXME: also log the device name?
386 XCAM_LOG_ERROR("Fail to get format via ioctl VIDVIO_G_FMT.");
387 return XCAM_RETURN_ERROR_IOCTL;
388 }
389
390 return XCAM_RETURN_NO_ERROR;
391 }
392
393 XCamReturn
start()394 V4l2Device::start ()
395 {
396 XCamReturn ret = XCAM_RETURN_NO_ERROR;
397 // request buffer first
398 ret = request_buffer ();
399 XCAM_FAIL_RETURN (
400 ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
401 "device(%s) start failed", XCAM_STR (_name));
402
403 //alloc buffers
404 ret = init_buffer_pool ();
405 XCAM_FAIL_RETURN (
406 ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
407 "device(%s) start failed", XCAM_STR (_name));
408
409 //queue all buffers
410 for (uint32_t i = 0; i < _buf_count; ++i) {
411 SmartPtr<V4l2Buffer> &buf = _buf_pool [i];
412 XCAM_ASSERT (buf.ptr());
413 XCAM_ASSERT (buf->get_buf().index == i);
414 ret = queue_buffer (buf);
415 if (ret != XCAM_RETURN_NO_ERROR) {
416 XCAM_LOG_ERROR (
417 "device(%s) start failed on queue index:%d",
418 XCAM_STR (_name), i);
419 stop ();
420 return ret;
421 }
422 }
423
424 // stream on
425 if (io_control (VIDIOC_STREAMON, &_capture_buf_type) < 0) {
426 XCAM_LOG_ERROR (
427 "device(%s) start failed on VIDIOC_STREAMON",
428 XCAM_STR (_name));
429 stop ();
430 return XCAM_RETURN_ERROR_IOCTL;
431 }
432 _active = true;
433 XCAM_LOG_INFO ("device(%s) started successfully", XCAM_STR (_name));
434 return XCAM_RETURN_NO_ERROR;
435 }
436
437 XCamReturn
stop()438 V4l2Device::stop ()
439 {
440 // stream off
441 if (_active) {
442 if (io_control (VIDIOC_STREAMOFF, &_capture_buf_type) < 0) {
443 XCAM_LOG_WARNING ("device(%s) steamoff failed", XCAM_STR (_name));
444 }
445 _active = false;
446 }
447
448 fini_buffer_pool ();
449
450 XCAM_LOG_INFO ("device(%s) stopped", XCAM_STR (_name));
451 return XCAM_RETURN_NO_ERROR;
452 }
453
454 XCamReturn
request_buffer()455 V4l2Device::request_buffer ()
456 {
457 struct v4l2_requestbuffers request_buf;
458
459 XCAM_ASSERT (!is_activated());
460
461 xcam_mem_clear (request_buf);
462 request_buf.type = _capture_buf_type;
463 request_buf.count = _buf_count;
464 request_buf.memory = _memory_type;
465
466 if (io_control (VIDIOC_REQBUFS, &request_buf) < 0) {
467 XCAM_LOG_INFO ("device(%s) starts failed on VIDIOC_REQBUFS", XCAM_STR (_name));
468 return XCAM_RETURN_ERROR_IOCTL;
469 }
470
471 if (request_buf.count != _buf_count) {
472 XCAM_LOG_DEBUG (
473 "device(%s) request buffer count doesn't match user settings, reset buffer count to %d",
474 XCAM_STR (_name), request_buf.count);
475 _buf_count = request_buf.count;
476 }
477 return XCAM_RETURN_NO_ERROR;
478 }
479
480 XCamReturn
allocate_buffer(SmartPtr<V4l2Buffer> & buf,const struct v4l2_format & format,const uint32_t index)481 V4l2Device::allocate_buffer (
482 SmartPtr<V4l2Buffer> &buf,
483 const struct v4l2_format &format,
484 const uint32_t index)
485 {
486 struct v4l2_buffer v4l2_buf;
487
488 xcam_mem_clear (v4l2_buf);
489 v4l2_buf.index = index;
490 v4l2_buf.type = _capture_buf_type;
491 v4l2_buf.memory = _memory_type;
492
493 switch (_memory_type) {
494 case V4L2_MEMORY_DMABUF:
495 {
496 struct v4l2_exportbuffer expbuf;
497 xcam_mem_clear (expbuf);
498 expbuf.type = _capture_buf_type;
499 expbuf.index = index;
500 expbuf.flags = O_CLOEXEC;
501 if (io_control (VIDIOC_EXPBUF, &expbuf) < 0) {
502 XCAM_LOG_WARNING ("device(%s) get dma buf(%d) failed", XCAM_STR (_name), index);
503 return XCAM_RETURN_ERROR_MEM;
504 }
505 v4l2_buf.m.fd = expbuf.fd;
506 v4l2_buf.length = format.fmt.pix.sizeimage;
507 }
508 break;
509 case V4L2_MEMORY_MMAP:
510 {
511 void *pointer;
512 int map_flags = MAP_SHARED;
513 #ifdef NEED_MAP_32BIT
514 map_flags |= MAP_32BIT;
515 #endif
516 if (io_control (VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
517 XCAM_LOG_WARNING("device(%s) query MMAP buf(%d) failed", XCAM_STR(_name), index);
518 return XCAM_RETURN_ERROR_MEM;
519 }
520 pointer = mmap (0, v4l2_buf.length, PROT_READ | PROT_WRITE, map_flags, _fd, v4l2_buf.m.offset);
521 if (pointer == MAP_FAILED) {
522 XCAM_LOG_WARNING("device(%s) mmap buf(%d) failed", XCAM_STR(_name), index);
523 return XCAM_RETURN_ERROR_MEM;
524 }
525 v4l2_buf.m.userptr = (uintptr_t) pointer;
526 }
527 break;
528 case V4L2_MEMORY_USERPTR:
529 default:
530 XCAM_ASSERT (false);
531 XCAM_LOG_WARNING (
532 "device(%s) allocated buffer mem_type(%d) doesn't support",
533 XCAM_STR (_name), _memory_type);
534 return XCAM_RETURN_ERROR_MEM;
535 }
536
537 buf = new V4l2Buffer (v4l2_buf, _format);
538
539 return XCAM_RETURN_NO_ERROR;
540 }
541
542 XCamReturn
init_buffer_pool()543 V4l2Device::init_buffer_pool ()
544 {
545 XCamReturn ret = XCAM_RETURN_NO_ERROR;
546 uint32_t i = 0;
547
548 _buf_pool.clear ();
549 _buf_pool.reserve (_buf_count);
550
551 for (; i < _buf_count; i++) {
552 SmartPtr<V4l2Buffer> new_buf;
553 ret = allocate_buffer (new_buf, _format, i);
554 if (ret != XCAM_RETURN_NO_ERROR) {
555 break;
556 }
557 _buf_pool.push_back (new_buf);
558 }
559
560 if (_buf_pool.empty()) {
561 XCAM_LOG_ERROR ("No bufer allocated in device(%s)", XCAM_STR (_name));
562 return XCAM_RETURN_ERROR_MEM;
563 }
564
565 if (i != _buf_count) {
566 XCAM_LOG_WARNING (
567 "device(%s) allocate buffer count:%d failback to %d",
568 XCAM_STR (_name), _buf_count, i);
569 _buf_count = i;
570 }
571
572 return XCAM_RETURN_NO_ERROR;
573 }
574
575 XCamReturn
fini_buffer_pool()576 V4l2Device::fini_buffer_pool()
577 {
578 _buf_pool.clear ();
579 return XCAM_RETURN_NO_ERROR;
580 }
581
582 XCamReturn
dequeue_buffer(SmartPtr<V4l2Buffer> & buf)583 V4l2Device::dequeue_buffer(SmartPtr<V4l2Buffer> &buf)
584 {
585 struct v4l2_buffer v4l2_buf;
586
587 if (!is_activated()) {
588 XCAM_LOG_DEBUG (
589 "device(%s) dequeue buffer failed since not activated", XCAM_STR (_name));
590 return XCAM_RETURN_ERROR_PARAM;
591 }
592
593 xcam_mem_clear (v4l2_buf);
594 v4l2_buf.type = _capture_buf_type;
595 v4l2_buf.memory = _memory_type;
596
597 if (this->io_control (VIDIOC_DQBUF, &v4l2_buf) < 0) {
598 XCAM_LOG_ERROR ("device(%s) fail to dequeue buffer.", XCAM_STR (_name));
599 return XCAM_RETURN_ERROR_IOCTL;
600 }
601
602 XCAM_LOG_DEBUG ("device(%s) dequeue buffer index:%d", XCAM_STR (_name), v4l2_buf.index);
603
604 if (v4l2_buf.index > _buf_count) {
605 XCAM_LOG_ERROR (
606 "device(%s) dequeue wrong buffer index:%d",
607 XCAM_STR (_name), v4l2_buf.index);
608 return XCAM_RETURN_ERROR_ISP;
609 }
610 buf = _buf_pool [v4l2_buf.index];
611 buf->set_timestamp (v4l2_buf.timestamp);
612 buf->set_timecode (v4l2_buf.timecode);
613 buf->set_sequence (v4l2_buf.sequence);
614 //buf.set_length (v4l2_buf.length); // not necessary to set length
615 return XCAM_RETURN_NO_ERROR;
616 }
617
618 XCamReturn
queue_buffer(SmartPtr<V4l2Buffer> & buf)619 V4l2Device::queue_buffer (SmartPtr<V4l2Buffer> &buf)
620 {
621 XCAM_ASSERT (buf.ptr());
622 buf->reset ();
623
624 struct v4l2_buffer v4l2_buf = buf->get_buf ();
625 XCAM_ASSERT (v4l2_buf.index < _buf_count);
626
627 XCAM_LOG_DEBUG ("device(%s) queue buffer index:%d", XCAM_STR (_name), v4l2_buf.index);
628 if (io_control (VIDIOC_QBUF, &v4l2_buf) < 0) {
629 XCAM_LOG_ERROR("fail to enqueue buffer index:%d.", v4l2_buf.index);
630 return XCAM_RETURN_ERROR_IOCTL;
631 }
632 return XCAM_RETURN_NO_ERROR;
633 }
634
V4l2SubDevice(const char * name)635 V4l2SubDevice::V4l2SubDevice (const char *name)
636 : V4l2Device (name)
637 {
638 }
639
640 XCamReturn
subscribe_event(int event)641 V4l2SubDevice::subscribe_event (int event)
642 {
643 struct v4l2_event_subscription sub;
644 int ret = 0;
645
646 XCAM_ASSERT (is_opened());
647
648 xcam_mem_clear (sub);
649 sub.type = event;
650
651 ret = this->io_control (VIDIOC_SUBSCRIBE_EVENT, &sub);
652 if (ret < 0) {
653 XCAM_LOG_DEBUG ("subdev(%s) subscribe event(%d) failed", XCAM_STR(_name), event);
654 return XCAM_RETURN_ERROR_IOCTL;
655 }
656 return XCAM_RETURN_NO_ERROR;
657 }
658
659 XCamReturn
unsubscribe_event(int event)660 V4l2SubDevice::unsubscribe_event (int event)
661 {
662 struct v4l2_event_subscription sub;
663 int ret = 0;
664
665 XCAM_ASSERT (is_opened());
666
667 xcam_mem_clear (sub);
668 sub.type = event;
669
670 ret = this->io_control (VIDIOC_UNSUBSCRIBE_EVENT, &sub);
671 if (ret < 0) {
672 XCAM_LOG_DEBUG ("subdev(%s) unsubscribe event(%d) failed", XCAM_STR(_name), event);
673 return XCAM_RETURN_ERROR_IOCTL;
674 }
675 return XCAM_RETURN_NO_ERROR;
676 }
677
678 XCamReturn
dequeue_event(struct v4l2_event & event)679 V4l2SubDevice::dequeue_event (struct v4l2_event &event)
680 {
681 int ret = 0;
682 XCAM_ASSERT (is_opened());
683
684 ret = this->io_control (VIDIOC_DQEVENT, &event);
685 if (ret < 0) {
686 XCAM_LOG_DEBUG ("subdev(%s) dequeue event failed", XCAM_STR(_name));
687 return XCAM_RETURN_ERROR_IOCTL;
688 }
689
690 return XCAM_RETURN_NO_ERROR;
691 }
692
start()693 XCamReturn V4l2SubDevice::start ()
694 {
695 if (!is_opened())
696 return XCAM_RETURN_ERROR_PARAM;
697
698 _active = true;
699 return XCAM_RETURN_NO_ERROR;
700 }
701
stop()702 XCamReturn V4l2SubDevice::stop ()
703 {
704 if (_active)
705 _active = false;
706
707 return XCAM_RETURN_NO_ERROR;
708 }
709
710 };
711