xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rk_stream/rkvi_demo/rkvi_demo_isp.c_part (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1
2
3#define BUFFER_COUNT 4
4#define CLEAR(x) memset(&(x), 0, sizeof(x))
5#define FMT_NUM_PLANES 1
6
7struct buffer {
8    void *start;
9    size_t length;
10    int export_fd;
11    int sequence;
12};
13
14
15enum v4l2_buf_type g_buf_type;
16struct buffer *g_buffers;
17unsigned int g_n_buffers;
18
19static int g_ispfd = -1;
20
21static int xioctl(int fh, int request, void *arg)
22{
23        int r;
24        do {
25                r = ioctl(fh, request, arg);
26        } while (-1 == r && EINTR == errno && g_aiq_quit == 0);
27        return r;
28}
29
30static void errno_exit(const char *s)
31{
32        printf("%s: %s error %d, %s\n", g_sns_name, s, errno, strerror(errno));
33}
34
35static void init_mmap(void)
36{
37    struct v4l2_requestbuffers req;
38    CLEAR(req);
39
40    req.count = BUFFER_COUNT;
41    req.type = g_buf_type;
42    req.memory = V4L2_MEMORY_MMAP;
43
44    struct buffer *tmp_buffers = NULL;
45
46    if (-1 == xioctl(g_ispfd, VIDIOC_REQBUFS, &req)) {
47        if (EINVAL == errno) {
48            printf("%s: %s does not support "
49                     "memory mapping\n" ,g_sns_name ,VIDEO_DEVNAME);
50        } else {
51            errno_exit("VIDIOC_REQBUFS");
52        }
53    }
54
55    if (req.count < 2) {
56        printf("%s: Insufficient buffer memory on %s\n",g_sns_name,
57                 VIDEO_DEVNAME);
58    }
59
60    tmp_buffers = (struct buffer*)calloc(req.count, sizeof(struct buffer));
61
62    if (!tmp_buffers) {
63            printf("%s: Out of memory\n",g_sns_name);
64    }
65
66    g_buffers = tmp_buffers;
67    unsigned int n_buffers;
68
69    for (n_buffers = 0; n_buffers < req.count; n_buffers++ ) {
70        struct v4l2_buffer buf;
71        struct v4l2_plane planes[FMT_NUM_PLANES];
72        CLEAR(buf);
73        CLEAR(planes);
74
75        buf.type = g_buf_type;
76        buf.memory = V4L2_MEMORY_MMAP;
77        buf.index = n_buffers;
78
79        if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == g_buf_type) {
80            buf.m.planes = planes;
81            buf.length = FMT_NUM_PLANES;
82        }
83
84        if (-1 == xioctl(g_ispfd, VIDIOC_QUERYBUF, &buf))
85                errno_exit("VIDIOC_QUERYBUF");
86
87        if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == g_buf_type) {
88            tmp_buffers[n_buffers].length = buf.m.planes[0].length;
89            tmp_buffers[n_buffers].start =
90                mmap(NULL /* start anywhere */,
91                      buf.m.planes[0].length,
92                      PROT_READ | PROT_WRITE /* required */,
93                      MAP_SHARED /* recommended */,
94                      g_ispfd, buf.m.planes[0].m.mem_offset);
95        } else {
96            tmp_buffers[n_buffers].length = buf.length;
97            tmp_buffers[n_buffers].start =
98                mmap(NULL /* start anywhere */,
99                      buf.length,
100                      PROT_READ | PROT_WRITE /* required */,
101                      MAP_SHARED /* recommended */,
102                      g_ispfd, buf.m.offset);
103        }
104
105        if (MAP_FAILED == tmp_buffers[n_buffers].start)
106                errno_exit("mmap");
107
108        // export buf dma fd
109        struct v4l2_exportbuffer expbuf;
110        xcam_mem_clear (expbuf);
111        expbuf.type = g_buf_type;
112        expbuf.index = n_buffers;
113        expbuf.flags = O_CLOEXEC;
114        if (xioctl(g_ispfd, VIDIOC_EXPBUF, &expbuf) < 0) {
115            errno_exit("get dma buf failed\n");
116        } else {
117            printf("%s: get dma buf(%d)-fd: %d\n",g_sns_name, n_buffers, expbuf.fd);
118        }
119        tmp_buffers[n_buffers].export_fd = expbuf.fd;
120    }
121    g_n_buffers = n_buffers;
122}
123
124void rkisp_init_device(int w, int h)
125{
126    struct v4l2_capability cap;
127    struct v4l2_format fmt;
128    struct v4l2_selection selection;
129
130    if (-1 == xioctl(g_ispfd, VIDIOC_QUERYCAP, &cap)) {
131            if (EINVAL == errno) {
132                    printf("%s: %s is no V4L2 device\n",g_sns_name, VIDEO_DEVNAME);
133            } else {
134                    errno_exit("VIDIOC_QUERYCAP");
135            }
136    }
137
138    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) &&
139            !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) {
140        printf("%s: %s is not a video capture device, capabilities: %x\n",
141                     g_sns_name, VIDEO_DEVNAME, cap.capabilities);
142    }
143
144    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
145            printf("%s: %s does not support streaming i/o\n",g_sns_name,
146                VIDEO_DEVNAME);
147    }
148
149    if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
150        g_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
151        CLEAR(fmt);
152        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
153        fmt.fmt.pix.width = w;
154        fmt.fmt.pix.height = h;
155        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
156        fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
157        fmt.fmt.pix.quantization = V4L2_QUANTIZATION_FULL_RANGE;
158    } else if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) {
159        g_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
160        CLEAR(fmt);
161        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
162        fmt.fmt.pix_mp.width = w;
163        fmt.fmt.pix_mp.height = h;
164        fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
165        fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
166        fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
167    }
168
169    if (-1 == xioctl(g_ispfd, VIDIOC_S_FMT, &fmt))
170            errno_exit("VIDIOC_S_FMT");
171
172    memset(&selection, 0, sizeof(selection));
173
174    selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
175    selection.target = V4L2_SEL_TGT_CROP;
176    selection.flags = 0;
177    selection.r.left = 0;
178    selection.r.top = 0;
179    selection.r.width = w;
180    selection.r.height = h;
181
182    if (-1 == xioctl(g_ispfd, VIDIOC_S_SELECTION, &selection))
183            errno_exit("VIDIOC_S_SELECTION");
184
185    init_mmap();
186}
187
188void rkisp_uninit_device(void)
189{
190        unsigned int i;
191
192        for (i = 0; i < g_n_buffers; ++i) {
193            if (-1 == munmap(g_buffers[i].start, g_buffers[i].length))
194                    errno_exit("munmap");
195
196            close(g_buffers[i].export_fd);
197        }
198
199        free(g_buffers);
200}
201
202void rkisp_start_capturing(void)
203{
204        unsigned int i;
205        enum v4l2_buf_type type;
206
207        for (i = 0; i < g_n_buffers; ++i) {
208                struct v4l2_buffer buf;
209
210                CLEAR(buf);
211                buf.type = g_buf_type;
212                buf.memory = V4L2_MEMORY_MMAP;
213                buf.index = i;
214
215                if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == g_buf_type) {
216                    struct v4l2_plane planes[FMT_NUM_PLANES];
217
218                    buf.m.planes = planes;
219                    buf.length = FMT_NUM_PLANES;
220                }
221                if (-1 == xioctl(g_ispfd, VIDIOC_QBUF, &buf))
222                        errno_exit("VIDIOC_QBUF");
223        }
224        type = g_buf_type;
225        printf("%s:-------- stream on output -------------\n",g_sns_name);
226        if (-1 == xioctl(g_ispfd, VIDIOC_STREAMON, &type))
227                errno_exit("VIDIOC_STREAMON");
228}
229
230void rkisp_stop_capturing(void)
231{
232        enum v4l2_buf_type type;
233
234        type = g_buf_type;
235        if (-1 == xioctl(g_ispfd, VIDIOC_STREAMOFF, &type))
236            errno_exit("VIDIOC_STREAMOFF");
237}
238
239static int write_yuv_to_file(const void *p,
240                             int size, int sequence)
241{
242    char file_name[64] = {0};
243
244    snprintf(file_name, sizeof(file_name),
245             "/tmp/frame%d.yuv", sequence);
246    FILE *fp = fopen(file_name, "wb");
247    if (fp == NULL) {
248        printf("fopen yuv file %s failed!\n", file_name);
249        return -1;
250    }
251
252    fwrite(p, size, 1, fp);
253    fflush(fp);
254
255    if (fp) {
256        fclose(fp);
257        fp = NULL;
258    }
259    printf("write_yuv_to_file %s %d!\n", file_name, size);
260    return 0;
261}
262
263
264static void* isp_thread(void* args) {
265    struct v4l2_buffer buf = {0};
266    int i, bytesused;
267    int cnt = 0;
268
269/*
270    rk_aiq_gamma_attr_t gama_attr;
271    gama_attr.atrrV30.mode = RK_AIQ_GAMMA_MODE_OFF;
272    gama_attr.atrrV21.mode = RK_AIQ_GAMMA_MODE_OFF;
273    rk_aiq_user_api2_agamma_SetAttrib(g_aiq_ctx, gama_attr);
274
275    aeMeasAreaType_t aeMeasArea;
276    memset(&aeMeasArea, 0, sizeof(aeMeasAreaType_t));
277    rk_aiq_uapi2_setBLCMode(g_aiq_ctx, false, aeMeasArea);
278
279
280    rk_aiq_dpcc_attrib_V20_t dpcc_attr;
281    memset(&dpcc_attr, 0, sizeof(rk_aiq_dpcc_attrib_V20_t));
282    rk_aiq_user_api2_adpcc_SetAttrib(g_aiq_ctx, &dpcc_attr);
283
284    rk_aiq_cpsl_cfg_t cpsl_cfg;
285    memset(&cpsl_cfg, 0, sizeof(rk_aiq_cpsl_cfg_t));
286    rk_aiq_uapi2_sysctl_setCpsLtCfg(g_aiq_ctx, &cpsl_cfg);
287
288    //acp_attrib_t acp_addr;
289    //memset(&acp_addr, 0, sizeof(acp_attrib_t));
290    //rk_aiq_user_api2_acp_SetAttrib(g_aiq_ctx, acp_addr);
291
292    rk_aiq_lsc_attrib_t lsc_attr;
293    memset(&lsc_attr, 0, sizeof(rk_aiq_lsc_attrib_t));
294    rk_aiq_user_api2_alsc_SetAttrib(g_aiq_ctx, lsc_attr);
295
296    //adebayer_attrib_t debayer_attr;
297    //memset(&debayer_attr, 0, sizeof(adebayer_attrib_t));
298    //rk_aiq_user_api2_adebayer_SetAttrib(g_aiq_ctx, debayer_attr);
299*/
300
301    while(g_aiq_quit == 0){
302        if(g_aiq_pause == 0){
303            CLEAR(buf);
304
305            buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
306            buf.memory = V4L2_MEMORY_MMAP;
307
308            struct v4l2_plane planes[FMT_NUM_PLANES];
309            memset(planes, 0, sizeof(struct v4l2_plane)*FMT_NUM_PLANES);
310            buf.m.planes = planes;
311            buf.length = FMT_NUM_PLANES;
312
313            if (-1 == xioctl(g_ispfd, VIDIOC_DQBUF, &buf))
314                    errno_exit( "VIDIOC_DQBUF");
315
316            printf("********* DQBUF sucess! buf.sequence %d\n", buf.sequence);
317            i = buf.index;
318            bytesused = buf.m.planes[0].bytesused;
319
320            if(bytesused > 0){
321                write_yuv_to_file(g_buffers[i].start,  bytesused, cnt);
322            }
323
324            if (-1 == xioctl(g_ispfd, VIDIOC_QBUF, &buf))
325                errno_exit("VIDIOC_QBUF");
326            usleep(1000);
327            cnt++;
328       }
329        usleep(10000);
330    }
331
332    return 0;
333}
334