summaryrefslogtreecommitdiff
path: root/v3/fake-pipeline2/camera_hw.cpp (plain)
blob: ec74667c5c83af13a9581b8204d6c2755eb12ca9
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->dev_status == -1) {
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 (ioctl(vinfo->fd, VIDIOC_QBUF, &vinfo->preview.buf) < 0)
295 DBG_LOGB("QBUF failed error=%d\n", errno);
296
297 return 0;
298}
299
300int putback_picture_frame(struct VideoInfo *vinfo)
301{
302
303 if (ioctl(vinfo->fd, VIDIOC_QBUF, &vinfo->picture.buf) < 0)
304 DBG_LOGB("QBUF failed error=%d\n", errno);
305
306 return 0;
307}
308
309int start_picture(struct VideoInfo *vinfo, int rotate)
310{
311 int ret = 0;
312 int i;
313 enum v4l2_buf_type type;
314 struct v4l2_buffer buf;
315 bool usbcamera = false;
316
317 CLEAR(vinfo->picture.rb);
318
319 //step 1 : ioctl VIDIOC_S_FMT
320 ret = ioctl(vinfo->fd, VIDIOC_S_FMT, &vinfo->picture.format);
321 if (ret < 0) {
322 DBG_LOGB("Open: VIDIOC_S_FMT Failed: %s, ret=%d\n", strerror(errno), ret);
323 }
324
325 //step 2 : request buffer
326 vinfo->picture.rb.count = 1;
327 vinfo->picture.rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
328 //TODO DMABUF & ION
329 vinfo->picture.rb.memory = V4L2_MEMORY_MMAP;
330
331 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->picture.rb);
332 if (ret < 0) {
333 DBG_LOGB("camera idx:%d does not support "
334 "memory mapping, errno=%d\n", vinfo->idx, errno);
335 }
336
337 if (vinfo->picture.rb.count < 1) {
338 DBG_LOGB( "Insufficient buffer memory on /dev/video%d, errno=%d\n",
339 vinfo->idx, errno);
340 return -EINVAL;
341 }
342
343 //step 3: mmap buffer
344 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
345
346 CLEAR(vinfo->picture.buf);
347
348 vinfo->picture.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
349 vinfo->picture.buf.memory = V4L2_MEMORY_MMAP;
350 vinfo->picture.buf.index = i;
351
352 if (ioctl(vinfo->fd, VIDIOC_QUERYBUF, &vinfo->picture.buf) < 0) {
353 DBG_LOGB("VIDIOC_QUERYBUF, errno=%d", errno);
354 }
355 vinfo->mem_pic[i] = mmap(NULL /* start anywhere */,
356 vinfo->picture.buf.length,
357 PROT_READ | PROT_WRITE /* required */,
358 MAP_SHARED /* recommended */,
359 vinfo->fd,
360 vinfo->picture.buf.m.offset);
361
362 if (MAP_FAILED == vinfo->mem_pic[i]) {
363 DBG_LOGB("mmap failed, errno=%d\n", errno);
364 }
365 }
366
367 //step 4 : QBUF
368 ////////////////////////////////
369 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
370
371 CLEAR(buf);
372 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
373 buf.memory = V4L2_MEMORY_MMAP;
374 buf.index = i;
375
376 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
377 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
378 }
379
380 if (vinfo->isPicture) {
381 DBG_LOGA("already stream on\n");
382 }
383
384 if (strstr((const char *)vinfo->cap.driver, "uvcvideo")) {
385 usbcamera = true;
386 }
387 if (!usbcamera) {
388 set_rotate_value(vinfo->fd,rotate);
389 }
390 //step 5: Stream ON
391 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
392 if (ioctl(vinfo->fd, VIDIOC_STREAMON, &type) < 0)
393 DBG_LOGB("VIDIOC_STREAMON, errno=%d\n", errno);
394 vinfo->isPicture = true;
395
396 return 0;
397}
398
399void *get_picture(struct VideoInfo *vinfo)
400{
401 CLEAR(vinfo->picture.buf);
402
403 vinfo->picture.buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
404 vinfo->picture.buf.memory = V4L2_MEMORY_MMAP;
405
406 if (ioctl(vinfo->fd, VIDIOC_DQBUF, &vinfo->picture.buf) < 0) {
407 switch (errno) {
408 case EAGAIN:
409 return NULL;
410 case EIO:
411 /* Could ignore EIO, see spec. */
412 /* fall through */
413 default:
414 DBG_LOGB("VIDIOC_DQBUF failed, errno=%d\n", errno);
415 exit(1);
416 }
417 }
418 DBG_LOGA("get picture\n");
419 return vinfo->mem_pic[vinfo->picture.buf.index];
420}
421
422void stop_picture(struct VideoInfo *vinfo)
423{
424 enum v4l2_buf_type type;
425 struct v4l2_buffer buf;
426 int i;
427
428 if (!vinfo->isPicture)
429 return ;
430
431 //QBUF
432 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
433 CLEAR(buf);
434 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
435 buf.memory = V4L2_MEMORY_MMAP;
436 buf.index = i;
437 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
438 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
439 }
440
441 //stream off and unmap buffer
442 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
443 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0)
444 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
445
446 for (i = 0; i < (int)vinfo->picture.rb.count; i++)
447 {
448 if (munmap(vinfo->mem_pic[i], vinfo->picture.buf.length) < 0)
449 DBG_LOGB("munmap failed errno=%d", errno);
450 }
451
452 set_rotate_value(vinfo->fd,0);
453 vinfo->isPicture = false;
454 setBuffersFormat(vinfo);
455 start_capturing(vinfo);
456}
457
458void releasebuf_and_stop_picture(struct VideoInfo *vinfo)
459{
460 enum v4l2_buf_type type;
461 struct v4l2_buffer buf;
462 int i,ret;
463
464 if (!vinfo->isPicture)
465 return ;
466
467 //QBUF
468 for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
469 CLEAR(buf);
470 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
471 buf.memory = V4L2_MEMORY_MMAP;
472 buf.index = i;
473 if (ioctl(vinfo->fd, VIDIOC_QBUF, &buf) < 0)
474 DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
475 }
476
477 //stream off and unmap buffer
478 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
479 if (ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type) < 0)
480 DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
481
482 for (i = 0; i < (int)vinfo->picture.rb.count; i++)
483 {
484 if (munmap(vinfo->mem_pic[i], vinfo->picture.buf.length) < 0)
485 DBG_LOGB("munmap failed errno=%d", errno);
486 }
487
488 vinfo->isPicture = false;
489
490 vinfo->picture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
491 vinfo->picture.rb.memory = V4L2_MEMORY_MMAP;
492 vinfo->picture.rb.count = 0;
493 ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->picture.rb);
494 if (ret < 0) {
495 DBG_LOGB("VIDIOC_REQBUFS failed: %s", strerror(errno));
496 //return ret;
497 }else{
498 DBG_LOGA("VIDIOC_REQBUFS delete buffer success\n");
499 }
500 setBuffersFormat(vinfo);
501 start_capturing(vinfo);
502}
503
504void camera_close(struct VideoInfo *vinfo)
505{
506 if (NULL == vinfo) {
507 DBG_LOGA("vinfo is null\n");
508 return ;
509 }
510
511 if (close(vinfo->fd) != 0)
512 DBG_LOGB("close failed, errno=%d\n", errno);
513
514 vinfo->fd = -1;
515}
516#ifdef __cplusplus
517//}
518#endif
519#endif
520