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