summaryrefslogtreecommitdiff
path: root/v3/fake-pipeline2/camera_hw.cpp (plain)
blob: 13a6826af80f51d2c12c2e8f160fe8930b3604d2
1#ifndef __CAMERA_HW__
2#define __CAMERA_HW__
3
4//#define LOG_NDEBUG 0
5#define LOG_TAG "Camera_hw"
6
7#include <errno.h>
8#include "camera_hw.h"
9
10#ifdef __cplusplus
11//extern "C" {
12#endif
13static int set_rotate_value(int camera_fd, int value)
14{
15 int ret = 0;
16 struct v4l2_control ctl;
17 if(camera_fd<0)
18 return -1;
19 if((value!=0)&&(value!=90)&&(value!=180)&&(value!=270)){
20 CAMHAL_LOGDB("Set rotate value invalid: %d.", value);
21 return -1;
22 }
23 memset( &ctl, 0, sizeof(ctl));
24 ctl.value=value;
25 ctl.id = V4L2_CID_ROTATE;
26 ALOGD("set_rotate_value:: id =%x , value=%d",ctl.id,ctl.value);
27 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
28 if(ret<0){
29 CAMHAL_LOGDB("Set rotate value fail: %s,errno=%d. ret=%d", strerror(errno),errno,ret);
30 }
31 return ret ;
32}
33
34void set_device_status(struct VideoInfo *vinfo)
35{
36 vinfo->dev_status = -1;
37}
38
39int get_device_status(struct VideoInfo *vinfo)
40{
41 return vinfo->dev_status;
42}
43
44int camera_open(struct VideoInfo *cam_dev)
45{
46 char dev_name[128];
47 int ret;
48
49 sprintf(dev_name, "%s%d", "/dev/video", cam_dev->idx);
50 cam_dev->fd = open(dev_name, O_RDWR | O_NONBLOCK);
51 //cam_dev->fd = open("/dev/video0", O_RDWR | O_NONBLOCK);
52 if (cam_dev->fd < 0){
53 DBG_LOGB("open %s failed, errno=%d\n", dev_name, errno);
54 return -ENOTTY;
55 }
56
57 ret = ioctl(cam_dev->fd, VIDIOC_QUERYCAP, &cam_dev->cap);
58 if (ret < 0) {
59 DBG_LOGB("VIDIOC_QUERYCAP, errno=%d", errno);
60 }
61
62 if (!(cam_dev->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
63 DBG_LOGB( "%s is not video capture device\n",
64 dev_name);
65 }
66
67 if (!(cam_dev->cap.capabilities & V4L2_CAP_STREAMING)) {
68 DBG_LOGB( "video%d does not support streaming i/o\n",
69 cam_dev->idx);
70 }
71
72 return ret;
73}
74
75int setBuffersFormat(struct VideoInfo *cam_dev)
76{
77 int ret = 0;
78 if ((cam_dev->preview.format.fmt.pix.width != 0) && (cam_dev->preview.format.fmt.pix.height != 0)) {
79 int pixelformat = cam_dev->preview.format.fmt.pix.pixelformat;
80
81 ret = ioctl(cam_dev->fd, VIDIOC_S_FMT, &cam_dev->preview.format);
82 if (ret < 0) {
83 DBG_LOGB("Open: VIDIOC_S_FMT Failed: %s, ret=%d\n", strerror(errno), ret);
84 }
85
86 CAMHAL_LOGIB("Width * Height %d x %d expect pixelfmt:%.4s, get:%.4s\n",
87 cam_dev->preview.format.fmt.pix.width,
88 cam_dev->preview.format.fmt.pix.height,
89 (char*)&pixelformat,
90 (char*)&cam_dev->preview.format.fmt.pix.pixelformat);
91 }
92 return ret;
93}
94
95int start_capturing(struct VideoInfo *vinfo)
96{
97 int ret = 0;
98 int i;
99 enum v4l2_buf_type type;
100 struct v4l2_buffer buf;
101
102 if (vinfo->isStreaming) {
103 DBG_LOGA("already stream on\n");
104 }
105 CLEAR(vinfo->preview.rb);
106
107 vinfo->preview.rb.count = 6;
108 vinfo->preview.rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
109 //TODO DMABUF & ION
110 vinfo->preview.rb.memory = V4L2_MEMORY_MMAP;
111
112 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->preview.rb);
113 if (ret < 0) {
114 DBG_LOGB("camera idx:%d does not support "
115 "memory mapping, errno=%d\n", vinfo->idx, errno);
116 }
117
118 if (vinfo->preview.rb.count < 2) {
119 DBG_LOGB( "Insufficient buffer memory on /dev/video%d, errno=%d\n",
120 vinfo->idx, errno);
121 return -EINVAL;
122 }
123
124 for (i = 0; i < (int)vinfo->preview.rb.count; ++i) {
125
126 CLEAR(vinfo->preview.buf);
127
128 vinfo->preview.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
129 vinfo->preview.buf.memory = V4L2_MEMORY_MMAP;
130 vinfo->preview.buf.index = i;
131
132 if (ioctl(vinfo->fd, VIDIOC_QUERYBUF, &vinfo->preview.buf) < 0) {
133 DBG_LOGB("VIDIOC_QUERYBUF, errno=%d", errno);
134 }
135 /*pluge usb camera when preview, vinfo->preview.buf.length value will equal to 0, so save this value*/
136 vinfo->tempbuflen = vinfo->preview.buf.length;
137 vinfo->mem[i] = mmap(NULL /* start anywhere */,
138 vinfo->preview.buf.length,
139 PROT_READ | PROT_WRITE /* required */,
140 MAP_SHARED /* recommended */,
141 vinfo->fd,
142 vinfo->preview.buf.m.offset);
143
144 if (MAP_FAILED == vinfo->mem[i]) {
145 DBG_LOGB("mmap failed, errno=%d\n", errno);
146 }
147 }
148 ////////////////////////////////
149 for (i = 0; i < (int)vinfo->preview.rb.count; ++i) {
150
151 CLEAR(buf);
152 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
153 buf.memory = V4L2_MEMORY_MMAP;
154 buf.index = i;
155
156 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
157 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
158 }
159
160 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
161 if ((vinfo->preview.format.fmt.pix.width != 0) &&
162 (vinfo->preview.format.fmt.pix.height != 0)) {
163 if (ioctl(vinfo->fd, VIDIOC_STREAMON, &type) < 0)
164 DBG_LOGB("VIDIOC_STREAMON, errno=%d\n", errno);
165 }
166
167 vinfo->isStreaming = true;
168 return 0;
169}
170
171int stop_capturing(struct VideoInfo *vinfo)
172{
173 enum v4l2_buf_type type;
174 int res = 0;
175 int i;
176
177 if (!vinfo->isStreaming)
178 return -1;
179
180 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
181 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0) {
182 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
183 res = -1;
184 }
185
186 for (i = 0; i < (int)vinfo->preview.rb.count; ++i) {
187 if (munmap(vinfo->mem[i], vinfo->preview.buf.length) < 0) {
188 DBG_LOGB("munmap failed errno=%d", errno);
189 res = -1;
190 }
191 }
192
193 vinfo->isStreaming = false;
194 return res;
195}
196
197int releasebuf_and_stop_capturing(struct VideoInfo *vinfo)
198{
199 enum v4l2_buf_type type;
200 int res = 0 ,ret;
201 int i;
202
203 if (!vinfo->isStreaming)
204 return -1;
205
206 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
207 if ((vinfo->preview.format.fmt.pix.width != 0) &&
208 (vinfo->preview.format.fmt.pix.height != 0)) {
209 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0) {
210 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
211 res = -1;
212 }
213 }
214 if (!vinfo->preview.buf.length) {
215 vinfo->preview.buf.length = vinfo->tempbuflen;
216 }
217 for (i = 0; i < (int)vinfo->preview.rb.count; ++i) {
218 if (munmap(vinfo->mem[i], vinfo->preview.buf.length) < 0) {
219 DBG_LOGB("munmap failed errno=%d", errno);
220 res = -1;
221 }
222 }
223 vinfo->isStreaming = false;
224
225 vinfo->preview.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
226 vinfo->preview.rb.memory = V4L2_MEMORY_MMAP;
227 vinfo->preview.rb.count = 0;
228
229 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->preview.rb);
230 if (ret < 0) {
231 DBG_LOGB("VIDIOC_REQBUFS failed: %s", strerror(errno));
232 //return ret;
233 }else{
234 DBG_LOGA("VIDIOC_REQBUFS delete buffer success\n");
235 }
236 return res;
237}
238
239
240uintptr_t get_frame_phys(struct VideoInfo *vinfo)
241{
242 CLEAR(vinfo->preview.buf);
243
244 vinfo->preview.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
245 vinfo->preview.buf.memory = V4L2_MEMORY_MMAP;
246
247 if (ioctl(vinfo->fd, VIDIOC_DQBUF, &vinfo->preview.buf) < 0) {
248 switch (errno) {
249 case EAGAIN:
250 return 0;
251
252 case EIO:
253 /* Could ignore EIO, see spec. */
254
255 /* fall through */
256
257 default:
258 DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno);
259 exit(1);
260 }
261 DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno);
262 }
263
264 return (uintptr_t)vinfo->preview.buf.m.userptr;
265}
266
267void *get_frame(struct VideoInfo *vinfo)
268{
269 CLEAR(vinfo->preview.buf);
270
271 vinfo->preview.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
272 vinfo->preview.buf.memory = V4L2_MEMORY_MMAP;
273
274 if (ioctl(vinfo->fd, VIDIOC_DQBUF, &vinfo->preview.buf) < 0) {
275 switch (errno) {
276 case EAGAIN:
277 return NULL;
278
279 case EIO:
280 /* Could ignore EIO, see spec. */
281
282 /* fall through */
283
284 default:
285 CAMHAL_LOGDB("VIDIOC_DQBUF failed, errno=%d\n", errno); //CAMHAL_LOGDB
286 //exit(1); /*here will generate crash, so delete. when ocour error, should break while() loop*/
287 set_device_status(vinfo);
288 return NULL;
289 }
290 }
291 //DBG_LOGA("get frame\n");
292 return vinfo->mem[vinfo->preview.buf.index];
293}
294
295int putback_frame(struct VideoInfo *vinfo)
296{
297 if (vinfo->dev_status == -1)
298 return 0;
299
300 if (!vinfo->preview.buf.length) {
301 vinfo->preview.buf.length = vinfo->tempbuflen;
302 }
303
304 if (ioctl(vinfo->fd, VIDIOC_QBUF, &vinfo->preview.buf) < 0) {
305 DBG_LOGB("QBUF failed error=%d\n", errno);
306 if (errno == ENODEV) {
307 set_device_status(vinfo);
308 }
309 }
310
311 return 0;
312}
313
314int putback_picture_frame(struct VideoInfo *vinfo)
315{
316
317 if (ioctl(vinfo->fd, VIDIOC_QBUF, &vinfo->picture.buf) < 0)
318 DBG_LOGB("QBUF failed error=%d\n", errno);
319
320 return 0;
321}
322
323int start_picture(struct VideoInfo *vinfo, int rotate)
324{
325 int ret = 0;
326 int i;
327 enum v4l2_buf_type type;
328 struct v4l2_buffer buf;
329 bool usbcamera = false;
330
331 CLEAR(vinfo->picture.rb);
332
333 //step 1 : ioctl VIDIOC_S_FMT
334 ret = ioctl(vinfo->fd, VIDIOC_S_FMT, &vinfo->picture.format);
335 if (ret < 0) {
336 DBG_LOGB("Open: VIDIOC_S_FMT Failed: %s, ret=%d\n", strerror(errno), ret);
337 }
338
339 //step 2 : request buffer
340 vinfo->picture.rb.count = 1;
341 vinfo->picture.rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
342 //TODO DMABUF & ION
343 vinfo->picture.rb.memory = V4L2_MEMORY_MMAP;
344
345 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->picture.rb);
346 if (ret < 0) {
347 DBG_LOGB("camera idx:%d does not support "
348 "memory mapping, errno=%d\n", vinfo->idx, errno);
349 }
350
351 if (vinfo->picture.rb.count < 1) {
352 DBG_LOGB( "Insufficient buffer memory on /dev/video%d, errno=%d\n",
353 vinfo->idx, errno);
354 return -EINVAL;
355 }
356
357 //step 3: mmap buffer
358 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
359
360 CLEAR(vinfo->picture.buf);
361
362 vinfo->picture.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
363 vinfo->picture.buf.memory = V4L2_MEMORY_MMAP;
364 vinfo->picture.buf.index = i;
365
366 if (ioctl(vinfo->fd, VIDIOC_QUERYBUF, &vinfo->picture.buf) < 0) {
367 DBG_LOGB("VIDIOC_QUERYBUF, errno=%d", errno);
368 }
369 vinfo->mem_pic[i] = mmap(NULL /* start anywhere */,
370 vinfo->picture.buf.length,
371 PROT_READ | PROT_WRITE /* required */,
372 MAP_SHARED /* recommended */,
373 vinfo->fd,
374 vinfo->picture.buf.m.offset);
375
376 if (MAP_FAILED == vinfo->mem_pic[i]) {
377 DBG_LOGB("mmap failed, errno=%d\n", errno);
378 }
379 }
380
381 //step 4 : QBUF
382 ////////////////////////////////
383 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
384
385 CLEAR(buf);
386 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
387 buf.memory = V4L2_MEMORY_MMAP;
388 buf.index = i;
389
390 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
391 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
392 }
393
394 if (vinfo->isPicture) {
395 DBG_LOGA("already stream on\n");
396 }
397
398 if (strstr((const char *)vinfo->cap.driver, "uvcvideo")) {
399 usbcamera = true;
400 }
401 if (!usbcamera) {
402 set_rotate_value(vinfo->fd,rotate);
403 }
404 //step 5: Stream ON
405 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
406 if (ioctl(vinfo->fd, VIDIOC_STREAMON, &type) < 0)
407 DBG_LOGB("VIDIOC_STREAMON, errno=%d\n", errno);
408 vinfo->isPicture = true;
409
410 return 0;
411}
412
413void *get_picture(struct VideoInfo *vinfo)
414{
415 CLEAR(vinfo->picture.buf);
416
417 vinfo->picture.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
418 vinfo->picture.buf.memory = V4L2_MEMORY_MMAP;
419
420 if (ioctl(vinfo->fd, VIDIOC_DQBUF, &vinfo->picture.buf) < 0) {
421 switch (errno) {
422 case EAGAIN:
423 return NULL;
424 case EIO:
425 /* Could ignore EIO, see spec. */
426 /* fall through */
427 default:
428 DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno);
429 exit(1);
430 }
431 }
432 DBG_LOGA("get picture\n");
433 return vinfo->mem_pic[vinfo->picture.buf.index];
434}
435
436void stop_picture(struct VideoInfo *vinfo)
437{
438 enum v4l2_buf_type type;
439 struct v4l2_buffer buf;
440 int i;
441
442 if (!vinfo->isPicture)
443 return ;
444
445 //QBUF
446 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
447 CLEAR(buf);
448 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
449 buf.memory = V4L2_MEMORY_MMAP;
450 buf.index = i;
451 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
452 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
453 }
454
455 //stream off and unmap buffer
456 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
457 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0)
458 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
459
460 for (i = 0; i < (int)vinfo->picture.rb.count; i++)
461 {
462 if (munmap(vinfo->mem_pic[i], vinfo->picture.buf.length) < 0)
463 DBG_LOGB("munmap failed errno=%d", errno);
464 }
465
466 set_rotate_value(vinfo->fd,0);
467 vinfo->isPicture = false;
468 setBuffersFormat(vinfo);
469 start_capturing(vinfo);
470}
471
472void releasebuf_and_stop_picture(struct VideoInfo *vinfo)
473{
474 enum v4l2_buf_type type;
475 struct v4l2_buffer buf;
476 int i,ret;
477
478 if (!vinfo->isPicture)
479 return ;
480
481 //QBUF
482 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
483 CLEAR(buf);
484 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
485 buf.memory = V4L2_MEMORY_MMAP;
486 buf.index = i;
487 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
488 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
489 }
490
491 //stream off and unmap buffer
492 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
493 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0)
494 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
495
496 for (i = 0; i < (int)vinfo->picture.rb.count; i++)
497 {
498 if (munmap(vinfo->mem_pic[i], vinfo->picture.buf.length) < 0)
499 DBG_LOGB("munmap failed errno=%d", errno);
500 }
501
502 vinfo->isPicture = false;
503
504 vinfo->picture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
505 vinfo->picture.rb.memory = V4L2_MEMORY_MMAP;
506 vinfo->picture.rb.count = 0;
507 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->picture.rb);
508 if (ret < 0) {
509 DBG_LOGB("VIDIOC_REQBUFS failed: %s", strerror(errno));
510 //return ret;
511 }else{
512 DBG_LOGA("VIDIOC_REQBUFS delete buffer success\n");
513 }
514 setBuffersFormat(vinfo);
515 start_capturing(vinfo);
516}
517
518void camera_close(struct VideoInfo *vinfo)
519{
520 if (NULL == vinfo) {
521 DBG_LOGA("vinfo is null\n");
522 return ;
523 }
524
525 if (close(vinfo->fd) != 0)
526 DBG_LOGB("close failed, errno=%d\n", errno);
527
528 vinfo->fd = -1;
529}
530#ifdef __cplusplus
531//}
532#endif
533#endif
534