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