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