mm_qcamera_rdi.c revision 6f83d735d8e3b918da42e6b559fcd0efb78133e5
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.user_data = (void *)stream;
123    stream->s_config.stream_cb = stream_cb;
124    stream->s_config.userdata = userdata;
125    stream->num_of_bufs = num_bufs;
126
127    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
128    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
129    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
130    if (num_burst == 0) {
131        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
132    } else {
133        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
134        stream->s_config.stream_info->num_of_burst = num_burst;
135    }
136    stream->s_config.stream_info->fmt = fmt;
137    stream->s_config.stream_info->dim.width = cam_cap->raw_dim.width;
138    stream->s_config.stream_info->dim.height = cam_cap->raw_dim.height;
139    stream->s_config.padding_info = cam_cap->padding_info;
140
141    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
142    if (MM_CAMERA_OK != rc) {
143        CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
144        return NULL;
145    }
146
147    buf_planes = &stream->s_config.stream_info->buf_planes;
148    rdi_len = buf_planes->plane_info.mp[0].len;
149    CDBG("%s: plane_info %dx%d len:%d frame_len:%d\n", __func__,
150        buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline,
151        buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len);
152
153    return stream;
154}
155
156mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj,
157                                                mm_camera_channel_t *channel,
158                                                mm_camera_buf_notify_t stream_cb,
159                                                void *userdata,
160                                                uint8_t num_bufs,
161                                                uint8_t num_burst)
162{
163    int rc = MM_CAMERA_OK;
164    mm_camera_stream_t *stream = NULL;
165    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
166
167    stream = mm_app_add_stream(test_obj, channel);
168    if (NULL == stream) {
169        CDBG_ERROR("%s: add stream failed\n", __func__);
170        return NULL;
171    }
172
173    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
174    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
175    stream->s_config.mem_vtbl.user_data = (void *)stream;
176    stream->s_config.stream_cb = stream_cb;
177    stream->s_config.userdata = userdata;
178    stream->num_of_bufs = num_bufs;
179
180    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
181    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
182    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
183    if (num_burst == 0) {
184        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
185    } else {
186        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
187        stream->s_config.stream_info->num_of_burst = num_burst;
188    }
189    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
190    stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
191    stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
192    stream->s_config.padding_info = cam_cap->padding_info;
193
194    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
195    if (MM_CAMERA_OK != rc) {
196        CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
197        return NULL;
198    }
199
200    return stream;
201}
202
203mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
204{
205    mm_camera_channel_t *channel = NULL;
206    mm_camera_stream_t *stream = NULL;
207
208    channel = mm_app_add_channel(test_obj,
209                                 MM_CHANNEL_TYPE_RDI,
210                                 NULL,
211                                 NULL,
212                                 NULL);
213    if (NULL == channel) {
214        CDBG_ERROR("%s: add channel failed", __func__);
215        return NULL;
216    }
217
218    stream = mm_app_add_rdi_stream(test_obj,
219                                       channel,
220                                       mm_app_rdi_notify_cb,
221                                       (void *)test_obj,
222                                       RDI_BUF_NUM,
223                                       num_burst);
224    if (NULL == stream) {
225        CDBG_ERROR("%s: add stream failed\n", __func__);
226        mm_app_del_channel(test_obj, channel);
227        return NULL;
228    }
229
230    CDBG("%s: channel=%d stream=%d\n", __func__, channel->ch_id, stream->s_id);
231    return channel;
232}
233
234int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj,
235                                mm_camera_channel_t *channel)
236{
237    int rc = MM_CAMERA_OK;
238    mm_camera_stream_t *stream = NULL;
239    uint8_t i;
240
241    rc = mm_app_stop_channel(test_obj, channel);
242    if (MM_CAMERA_OK != rc) {
243        CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
244    }
245
246    for (i = 0; i < channel->num_streams; i++) {
247        stream = &channel->streams[i];
248        rc = mm_app_del_stream(test_obj, channel, stream);
249        if (MM_CAMERA_OK != rc) {
250            CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
251        }
252    }
253
254    rc = mm_app_del_channel(test_obj, channel);
255    if (MM_CAMERA_OK != rc) {
256        CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
257    }
258
259    return rc;
260}
261
262int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
263{
264    int rc = MM_CAMERA_OK;
265    mm_camera_channel_t *channel = NULL;
266
267    channel = mm_app_add_rdi_channel(test_obj, num_burst);
268    if (NULL == channel) {
269        CDBG_ERROR("%s: add channel failed", __func__);
270        return -MM_CAMERA_E_GENERAL;
271    }
272
273    rc = mm_app_start_channel(test_obj, channel);
274    if (MM_CAMERA_OK != rc) {
275        CDBG_ERROR("%s:start rdi failed rc=%d\n", __func__, rc);
276        mm_app_del_channel(test_obj, channel);
277        return rc;
278    }
279
280    return rc;
281}
282
283int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj)
284{
285    int rc = MM_CAMERA_OK;
286
287    mm_camera_channel_t *channel =
288        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI);
289
290    rc = mm_app_stop_and_del_rdi_channel(test_obj, channel);
291    if (MM_CAMERA_OK != rc) {
292        CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
293    }
294
295    return rc;
296}
297
298