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