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