summaryrefslogtreecommitdiff
path: root/v3/fake-pipeline2/camera_hw.cpp (plain)
blob: 6ea014c5d8cb773afc09fb520f5ecd5d36d7a48d
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 (ioctl(vinfo->fd, VIDIOC_STREAMON, &type) < 0)
162 DBG_LOGB("VIDIOC_STREAMON, errno=%d\n", errno);
163
164 vinfo->isStreaming = true;
165 return 0;
166}
167
168int stop_capturing(struct VideoInfo *vinfo)
169{
170 enum v4l2_buf_type type;
171 int res = 0;
172 int i;
173
174 if (!vinfo->isStreaming)
175 return -1;
176
177 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
178 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0) {
179 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
180 res = -1;
181 }
182
183 for (i = 0; i < (int)vinfo->preview.rb.count; ++i) {
184 if (munmap(vinfo->mem[i], vinfo->preview.buf.length) < 0) {
185 DBG_LOGB("munmap failed errno=%d", errno);
186 res = -1;
187 }
188 }
189
190 vinfo->isStreaming = false;
191 return res;
192}
193
194int releasebuf_and_stop_capturing(struct VideoInfo *vinfo)
195{
196 enum v4l2_buf_type type;
197 int res = 0 ,ret;
198 int i;
199
200 if (!vinfo->isStreaming)
201 return -1;
202
203 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
204 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0) {
205 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
206 res = -1;
207 }
208 if (!vinfo->preview.buf.length) {
209 vinfo->preview.buf.length = vinfo->tempbuflen;
210 }
211 for (i = 0; i < (int)vinfo->preview.rb.count; ++i) {
212 if (munmap(vinfo->mem[i], vinfo->preview.buf.length) < 0) {
213 DBG_LOGB("munmap failed errno=%d", errno);
214 res = -1;
215 }
216 }
217 vinfo->isStreaming = false;
218
219 vinfo->preview.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
220 vinfo->preview.rb.memory = V4L2_MEMORY_MMAP;
221 vinfo->preview.rb.count = 0;
222
223 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->preview.rb);
224 if (ret < 0) {
225 DBG_LOGB("VIDIOC_REQBUFS failed: %s", strerror(errno));
226 //return ret;
227 }else{
228 DBG_LOGA("VIDIOC_REQBUFS delete buffer success\n");
229 }
230 return res;
231}
232
233
234uintptr_t get_frame_phys(struct VideoInfo *vinfo)
235{
236 CLEAR(vinfo->preview.buf);
237
238 vinfo->preview.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
239 vinfo->preview.buf.memory = V4L2_MEMORY_MMAP;
240
241 if (ioctl(vinfo->fd, VIDIOC_DQBUF, &vinfo->preview.buf) < 0) {
242 switch (errno) {
243 case EAGAIN:
244 return 0;
245
246 case EIO:
247 /* Could ignore EIO, see spec. */
248
249 /* fall through */
250
251 default:
252 DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno);
253 exit(1);
254 }
255 DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno);
256 }
257
258 return (uintptr_t)vinfo->preview.buf.m.userptr;
259}
260
261void *get_frame(struct VideoInfo *vinfo)
262{
263 CLEAR(vinfo->preview.buf);
264
265 vinfo->preview.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
266 vinfo->preview.buf.memory = V4L2_MEMORY_MMAP;
267
268 if (ioctl(vinfo->fd, VIDIOC_DQBUF, &vinfo->preview.buf) < 0) {
269 switch (errno) {
270 case EAGAIN:
271 return NULL;
272
273 case EIO:
274 /* Could ignore EIO, see spec. */
275
276 /* fall through */
277
278 default:
279 CAMHAL_LOGDB("VIDIOC_DQBUF failed, errno=%d\n", errno); //CAMHAL_LOGDB
280 //exit(1); /*here will generate crash, so delete. when ocour error, should break while() loop*/
281 set_device_status(vinfo);
282 return NULL;
283 }
284 }
285 //DBG_LOGA("get frame\n");
286 return vinfo->mem[vinfo->preview.buf.index];
287}
288
289int putback_frame(struct VideoInfo *vinfo)
290{
291 if (vinfo->dev_status == -1)
292 return 0;
293
294 if (!vinfo->preview.buf.length) {
295 vinfo->preview.buf.length = vinfo->tempbuflen;
296 }
297
298 if (ioctl(vinfo->fd, VIDIOC_QBUF, &vinfo->preview.buf) < 0) {
299 DBG_LOGB("QBUF failed error=%d\n", errno);
300 if (errno == ENODEV) {
301 set_device_status(vinfo);
302 }
303 }
304
305 return 0;
306}
307
308int putback_picture_frame(struct VideoInfo *vinfo)
309{
310
311 if (ioctl(vinfo->fd, VIDIOC_QBUF, &vinfo->picture.buf) < 0)
312 DBG_LOGB("QBUF failed error=%d\n", errno);
313
314 return 0;
315}
316
317int start_picture(struct VideoInfo *vinfo, int rotate)
318{
319 int ret = 0;
320 int i;
321 enum v4l2_buf_type type;
322 struct v4l2_buffer buf;
323 bool usbcamera = false;
324
325 CLEAR(vinfo->picture.rb);
326
327 //step 1 : ioctl VIDIOC_S_FMT
328 ret = ioctl(vinfo->fd, VIDIOC_S_FMT, &vinfo->picture.format);
329 if (ret < 0) {
330 DBG_LOGB("Open: VIDIOC_S_FMT Failed: %s, ret=%d\n", strerror(errno), ret);
331 }
332
333 //step 2 : request buffer
334 vinfo->picture.rb.count = 1;
335 vinfo->picture.rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
336 //TODO DMABUF & ION
337 vinfo->picture.rb.memory = V4L2_MEMORY_MMAP;
338
339 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->picture.rb);
340 if (ret < 0) {
341 DBG_LOGB("camera idx:%d does not support "
342 "memory mapping, errno=%d\n", vinfo->idx, errno);
343 }
344
345 if (vinfo->picture.rb.count < 1) {
346 DBG_LOGB( "Insufficient buffer memory on /dev/video%d, errno=%d\n",
347 vinfo->idx, errno);
348 return -EINVAL;
349 }
350
351 //step 3: mmap buffer
352 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
353
354 CLEAR(vinfo->picture.buf);
355
356 vinfo->picture.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
357 vinfo->picture.buf.memory = V4L2_MEMORY_MMAP;
358 vinfo->picture.buf.index = i;
359
360 if (ioctl(vinfo->fd, VIDIOC_QUERYBUF, &vinfo->picture.buf) < 0) {
361 DBG_LOGB("VIDIOC_QUERYBUF, errno=%d", errno);
362 }
363 vinfo->mem_pic[i] = mmap(NULL /* start anywhere */,
364 vinfo->picture.buf.length,
365 PROT_READ | PROT_WRITE /* required */,
366 MAP_SHARED /* recommended */,
367 vinfo->fd,
368 vinfo->picture.buf.m.offset);
369
370 if (MAP_FAILED == vinfo->mem_pic[i]) {
371 DBG_LOGB("mmap failed, errno=%d\n", errno);
372 }
373 }
374
375 //step 4 : QBUF
376 ////////////////////////////////
377 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
378
379 CLEAR(buf);
380 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
381 buf.memory = V4L2_MEMORY_MMAP;
382 buf.index = i;
383
384 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
385 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
386 }
387
388 if (vinfo->isPicture) {
389 DBG_LOGA("already stream on\n");
390 }
391
392 if (strstr((const char *)vinfo->cap.driver, "uvcvideo")) {
393 usbcamera = true;
394 }
395 if (!usbcamera) {
396 set_rotate_value(vinfo->fd,rotate);
397 }
398 //step 5: Stream ON
399 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
400 if (ioctl(vinfo->fd, VIDIOC_STREAMON, &type) < 0)
401 DBG_LOGB("VIDIOC_STREAMON, errno=%d\n", errno);
402 vinfo->isPicture = true;
403
404 return 0;
405}
406
407void *get_picture(struct VideoInfo *vinfo)
408{
409 CLEAR(vinfo->picture.buf);
410
411 vinfo->picture.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
412 vinfo->picture.buf.memory = V4L2_MEMORY_MMAP;
413
414 if (ioctl(vinfo->fd, VIDIOC_DQBUF, &vinfo->picture.buf) < 0) {
415 switch (errno) {
416 case EAGAIN:
417 return NULL;
418 case EIO:
419 /* Could ignore EIO, see spec. */
420 /* fall through */
421 default:
422 DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno);
423 exit(1);
424 }
425 }
426 DBG_LOGA("get picture\n");
427 return vinfo->mem_pic[vinfo->picture.buf.index];
428}
429
430void stop_picture(struct VideoInfo *vinfo)
431{
432 enum v4l2_buf_type type;
433 struct v4l2_buffer buf;
434 int i;
435
436 if (!vinfo->isPicture)
437 return ;
438
439 //QBUF
440 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
441 CLEAR(buf);
442 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
443 buf.memory = V4L2_MEMORY_MMAP;
444 buf.index = i;
445 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
446 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
447 }
448
449 //stream off and unmap buffer
450 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
451 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0)
452 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
453
454 for (i = 0; i < (int)vinfo->picture.rb.count; i++)
455 {
456 if (munmap(vinfo->mem_pic[i], vinfo->picture.buf.length) < 0)
457 DBG_LOGB("munmap failed errno=%d", errno);
458 }
459
460 set_rotate_value(vinfo->fd,0);
461 vinfo->isPicture = false;
462 setBuffersFormat(vinfo);
463 start_capturing(vinfo);
464}
465
466void releasebuf_and_stop_picture(struct VideoInfo *vinfo)
467{
468 enum v4l2_buf_type type;
469 struct v4l2_buffer buf;
470 int i,ret;
471
472 if (!vinfo->isPicture)
473 return ;
474
475 //QBUF
476 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
477 CLEAR(buf);
478 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
479 buf.memory = V4L2_MEMORY_MMAP;
480 buf.index = i;
481 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
482 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
483 }
484
485 //stream off and unmap buffer
486 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
487 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0)
488 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
489
490 for (i = 0; i < (int)vinfo->picture.rb.count; i++)
491 {
492 if (munmap(vinfo->mem_pic[i], vinfo->picture.buf.length) < 0)
493 DBG_LOGB("munmap failed errno=%d", errno);
494 }
495
496 vinfo->isPicture = false;
497
498 vinfo->picture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
499 vinfo->picture.rb.memory = V4L2_MEMORY_MMAP;
500 vinfo->picture.rb.count = 0;
501 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->picture.rb);
502 if (ret < 0) {
503 DBG_LOGB("VIDIOC_REQBUFS failed: %s", strerror(errno));
504 //return ret;
505 }else{
506 DBG_LOGA("VIDIOC_REQBUFS delete buffer success\n");
507 }
508 setBuffersFormat(vinfo);
509 start_capturing(vinfo);
510}
511
512void camera_close(struct VideoInfo *vinfo)
513{
514 if (NULL == vinfo) {
515 DBG_LOGA("vinfo is null\n");
516 return ;
517 }
518
519 if (close(vinfo->fd) != 0)
520 DBG_LOGB("close failed, errno=%d\n", errno);
521
522 vinfo->fd = -1;
523}
524#ifdef __cplusplus
525//}
526#endif
527#endif
528