mm_qcamera_rdi.c revision a1724bc599bec5b2fbe3f4a34d0eca2406ba4c5f
1/*
2Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7    * Redistributions of source code must retain the above copyright
8      notice, this list of conditions and the following disclaimer.
9    * Redistributions in binary form must reproduce the above
10      copyright notice, this list of conditions and the following
11      disclaimer in the documentation and/or other materials provided
12      with the distribution.
13    * Neither the name of The Linux Foundation nor the names of its
14      contributors may be used to endorse or promote products derived
15      from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include "mm_qcamera_dbg.h"
31#include "mm_qcamera_app.h"
32
33static uint32_t rdi_len = 0;
34
35static void mm_app_rdi_dump_frame(mm_camera_buf_def_t *frame,
36                                  char *name,
37                                  char *ext,
38                                  int frame_idx)
39{
40    char file_name[64];
41    int file_fd;
42    int i;
43    if (frame != NULL) {
44        snprintf(file_name, sizeof(file_name), "/data/%s_%03d.%s", name, frame_idx, ext);
45        file_fd = open(file_name, O_RDWR | O_CREAT, 0777);
46        if (file_fd < 0) {
47            CDBG_ERROR("%s: cannot open file %s \n", __func__, file_name);
48        } else {
49            for (i = 0; i < frame->num_planes; i++) {
50                write(file_fd,
51                      (uint8_t *)frame->buffer + frame->planes[i].data_offset,
52                      rdi_len);
53            }
54
55            close(file_fd);
56            CDBG("dump %s", file_name);
57        }
58    }
59}
60
61static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs,
62                                 void *user_data)
63{
64    char file_name[64];
65    mm_camera_buf_def_t *frame = bufs->bufs[0];
66    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
67
68    CDBG("%s: BEGIN - length=%d, frame idx = %d stream_id=%d\n",
69         __func__, frame->frame_len, frame->frame_idx, frame->stream_id);
70    snprintf(file_name, sizeof(file_name), "RDI_dump_%d", pme->cam->camera_handle);
71    mm_app_rdi_dump_frame(frame, file_name, "raw", frame->frame_idx);
72
73    if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
74                                            bufs->ch_id,
75                                            frame)) {
76        CDBG_ERROR("%s: Failed in RDI Qbuf\n", __func__);
77    }
78    mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
79                     ION_IOC_INV_CACHES);
80
81    CDBG("%s: END\n", __func__);
82}
83
84mm_camera_stream_t * mm_app_add_rdi_stream(mm_camera_test_obj_t *test_obj,
85                                               mm_camera_channel_t *channel,
86                                               mm_camera_buf_notify_t stream_cb,
87                                               void *userdata,
88                                               uint8_t num_bufs,
89                                               uint8_t num_burst)
90{
91    int rc = MM_CAMERA_OK;
92    int i;
93    mm_camera_stream_t *stream = NULL;
94    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
95    cam_format_t fmt = CAM_FORMAT_MAX;
96    cam_stream_buf_plane_info_t *buf_planes;
97
98    stream = mm_app_add_stream(test_obj, channel);
99    if (NULL == stream) {
100        CDBG_ERROR("%s: add stream failed\n", __func__);
101        return NULL;
102    }
103
104    CDBG_ERROR("%s: raw_dim w:%d height:%d\n", __func__, cam_cap->raw_dim.width, cam_cap->raw_dim.height);
105    for (i = 0;i < cam_cap->supported_raw_fmt_cnt;i++) {
106        CDBG_ERROR("%s: supported_raw_fmts[%d]=%d\n", __func__, i, cam_cap->supported_raw_fmts[i]);
107        if (CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG <= cam_cap->supported_raw_fmts[i] &&
108            CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR >= cam_cap->supported_raw_fmts[i])
109        {
110            fmt = cam_cap->supported_raw_fmts[i];
111            CDBG_ERROR("%s: fmt=%d\n", __func__, fmt);
112        }
113    }
114
115    if (CAM_FORMAT_MAX == fmt) {
116        CDBG_ERROR("%s: rdi format not supported\n", __func__);
117        return NULL;
118    }
119
120    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
121    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
122    stream->s_config.mem_vtbl.clean_invalidate_buf =
123      mm_app_stream_clean_invalidate_buf;
124    stream->s_config.mem_vtbl.user_data = (void *)stream;
125    stream->s_config.stream_cb = stream_cb;
126    stream->s_config.userdata = userdata;
127    stream->num_of_bufs = num_bufs;
128
129    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
130    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
131    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
132    if (num_burst == 0) {
133        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
134    } else {
135        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
136        stream->s_config.stream_info->num_of_burst = num_burst;
137    }
138    stream->s_config.stream_info->fmt = fmt;
139    stream->s_config.stream_info->dim.width = cam_cap->raw_dim.width;
140    stream->s_config.stream_info->dim.height = cam_cap->raw_dim.height;
141    stream->s_config.padding_info = cam_cap->padding_info;
142
143    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
144    if (MM_CAMERA_OK != rc) {
145        CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
146        return NULL;
147    }
148
149    buf_planes = &stream->s_config.stream_info->buf_planes;
150    rdi_len = buf_planes->plane_info.mp[0].len;
151    CDBG("%s: plane_info %dx%d len:%d frame_len:%d\n", __func__,
152        buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline,
153        buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len);
154
155    return stream;
156}
157
158mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj,
159                                                mm_camera_channel_t *channel,
160                                                mm_camera_buf_notify_t stream_cb,
161                                                void *userdata,
162                                                uint8_t num_bufs,
163                                                uint8_t num_burst)
164{
165    int rc = MM_CAMERA_OK;
166    mm_camera_stream_t *stream = NULL;
167    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
168
169    stream = mm_app_add_stream(test_obj, channel);
170    if (NULL == stream) {
171        CDBG_ERROR("%s: add stream failed\n", __func__);
172        return NULL;
173    }
174
175    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
176    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
177    stream->s_config.mem_vtbl.clean_invalidate_buf =
178      mm_app_stream_clean_invalidate_buf;
179    stream->s_config.mem_vtbl.user_data = (void *)stream;
180    stream->s_config.stream_cb = stream_cb;
181    stream->s_config.userdata = userdata;
182    stream->num_of_bufs = num_bufs;
183
184    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
185    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
186    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
187    if (num_burst == 0) {
188        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
189    } else {
190        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
191        stream->s_config.stream_info->num_of_burst = num_burst;
192    }
193    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
194    stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
195    stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
196    stream->s_config.padding_info = cam_cap->padding_info;
197
198    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
199    if (MM_CAMERA_OK != rc) {
200        CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
201        return NULL;
202    }
203
204    return stream;
205}
206
207mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
208{
209    mm_camera_channel_t *channel = NULL;
210    mm_camera_stream_t *stream = NULL;
211
212    channel = mm_app_add_channel(test_obj,
213                                 MM_CHANNEL_TYPE_RDI,
214                                 NULL,
215                                 NULL,
216                                 NULL);
217    if (NULL == channel) {
218        CDBG_ERROR("%s: add channel failed", __func__);
219        return NULL;
220    }
221
222    stream = mm_app_add_rdi_stream(test_obj,
223                                       channel,
224                                       mm_app_rdi_notify_cb,
225                                       (void *)test_obj,
226                                       RDI_BUF_NUM,
227                                       num_burst);
228    if (NULL == stream) {
229        CDBG_ERROR("%s: add stream failed\n", __func__);
230        mm_app_del_channel(test_obj, channel);
231        return NULL;
232    }
233
234    CDBG("%s: channel=%d stream=%d\n", __func__, channel->ch_id, stream->s_id);
235    return channel;
236}
237
238int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj,
239                                mm_camera_channel_t *channel)
240{
241    int rc = MM_CAMERA_OK;
242    mm_camera_stream_t *stream = NULL;
243    uint8_t i;
244
245    rc = mm_app_stop_channel(test_obj, channel);
246    if (MM_CAMERA_OK != rc) {
247        CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
248    }
249
250    for (i = 0; i < channel->num_streams; i++) {
251        stream = &channel->streams[i];
252        rc = mm_app_del_stream(test_obj, channel, stream);
253        if (MM_CAMERA_OK != rc) {
254            CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
255        }
256    }
257
258    rc = mm_app_del_channel(test_obj, channel);
259    if (MM_CAMERA_OK != rc) {
260        CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
261    }
262
263    return rc;
264}
265
266int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
267{
268    int rc = MM_CAMERA_OK;
269    mm_camera_channel_t *channel = NULL;
270
271    channel = mm_app_add_rdi_channel(test_obj, num_burst);
272    if (NULL == channel) {
273        CDBG_ERROR("%s: add channel failed", __func__);
274        return -MM_CAMERA_E_GENERAL;
275    }
276
277    rc = mm_app_start_channel(test_obj, channel);
278    if (MM_CAMERA_OK != rc) {
279        CDBG_ERROR("%s:start rdi failed rc=%d\n", __func__, rc);
280        mm_app_del_channel(test_obj, channel);
281        return rc;
282    }
283
284    return rc;
285}
286
287int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj)
288{
289    int rc = MM_CAMERA_OK;
290
291    mm_camera_channel_t *channel =
292        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI);
293
294    rc = mm_app_stop_and_del_rdi_channel(test_obj, channel);
295    if (MM_CAMERA_OK != rc) {
296        CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
297    }
298
299    return rc;
300}
301
302