1 /*
2 Copyright (c) 2012-2016, 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 // System dependencies
31 #include <fcntl.h>
32 #include <unistd.h>
33
34 // Camera dependencies
35 #include "mm_qcamera_app.h"
36 #include "mm_qcamera_dbg.h"
37
38 static uint32_t rdi_len = 0;
39
mm_app_rdi_dump_frame(mm_camera_buf_def_t * frame,char * name,char * ext,uint32_t frame_idx)40 static void mm_app_rdi_dump_frame(mm_camera_buf_def_t *frame,
41 char *name,
42 char *ext,
43 uint32_t frame_idx)
44 {
45 char file_name[FILENAME_MAX];
46 int file_fd;
47 int i;
48
49 if (frame != NULL) {
50 snprintf(file_name, sizeof(file_name),
51 QCAMERA_DUMP_FRM_LOCATION"%s_%03u.%s", name, frame_idx, ext);
52 file_fd = open(file_name, O_RDWR | O_CREAT, 0777);
53 if (file_fd < 0) {
54 LOGE(" cannot open file %s \n", file_name);
55 } else {
56 for (i = 0; i < frame->planes_buf.num_planes; i++) {
57 write(file_fd,
58 (uint8_t *)frame->buffer + frame->planes_buf.planes[i].data_offset,
59 rdi_len);
60 }
61
62 close(file_fd);
63 LOGD(" dump rdi frame %s", file_name);
64 }
65 }
66 }
67
mm_app_rdi_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)68 static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs,
69 void *user_data)
70 {
71 char file_name[FILENAME_MAX];
72 mm_camera_buf_def_t *frame = bufs->bufs[0];
73 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
74
75 LOGD(" BEGIN - length=%zu, frame idx = %d stream_id=%d\n",
76 frame->frame_len, frame->frame_idx, frame->stream_id);
77 snprintf(file_name, sizeof(file_name), "RDI_dump_%d", pme->cam->camera_handle);
78 mm_app_rdi_dump_frame(frame, file_name, "raw", frame->frame_idx);
79
80 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
81 bufs->ch_id,
82 frame)) {
83 LOGE(" Failed in RDI Qbuf\n");
84 }
85 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
86 ION_IOC_INV_CACHES);
87
88 LOGD(" END\n");
89 }
90
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)91 mm_camera_stream_t * mm_app_add_rdi_stream(mm_camera_test_obj_t *test_obj,
92 mm_camera_channel_t *channel,
93 mm_camera_buf_notify_t stream_cb,
94 void *userdata,
95 uint8_t num_bufs,
96 uint8_t num_burst)
97 {
98 int rc = MM_CAMERA_OK;
99 size_t i;
100 mm_camera_stream_t *stream = NULL;
101 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
102 cam_format_t fmt = CAM_FORMAT_MAX;
103 cam_stream_buf_plane_info_t *buf_planes;
104 cam_stream_size_info_t abc ;
105 memset (&abc , 0, sizeof (cam_stream_size_info_t));
106
107
108
109 LOGE(" raw_dim w:%d height:%d\n", cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
110 for (i = 0;i < cam_cap->supported_raw_fmt_cnt;i++) {
111 LOGE(" supported_raw_fmts[%zd]=%d\n",
112 i, (int)cam_cap->supported_raw_fmts[i]);
113 if (((CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG <= cam_cap->supported_raw_fmts[i]) &&
114 (CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR >= cam_cap->supported_raw_fmts[i])) ||
115 (cam_cap->supported_raw_fmts[i] == CAM_FORMAT_META_RAW_8BIT) ||
116 (cam_cap->supported_raw_fmts[i] == CAM_FORMAT_JPEG_RAW_8BIT) ||
117 (cam_cap->supported_raw_fmts[i] == CAM_FORMAT_BAYER_MIPI_RAW_14BPP_BGGR))
118 {
119 fmt = cam_cap->supported_raw_fmts[i];
120 LOGE(" fmt=%d\n", fmt);
121 }
122 }
123
124 if (CAM_FORMAT_MAX == fmt) {
125 LOGE(" rdi format not supported\n");
126 return NULL;
127 }
128
129 abc.num_streams = 1;
130 abc.postprocess_mask[0] = 0;
131 abc.stream_sizes[0].width = cam_cap->raw_dim[0].width;
132 abc.stream_sizes[0].height = cam_cap->raw_dim[0].height;
133 abc.type[0] = CAM_STREAM_TYPE_RAW;
134 abc.buffer_info.min_buffers = num_bufs;
135 abc.buffer_info.max_buffers = num_bufs;
136 abc.is_type[0] = IS_TYPE_NONE;
137
138 rc = setmetainfoCommand(test_obj, &abc);
139 if (rc != MM_CAMERA_OK) {
140 LOGE(" meta info command failed\n");
141 }
142
143 stream = mm_app_add_stream(test_obj, channel);
144 if (NULL == stream) {
145 LOGE(" add stream failed\n");
146 return NULL;
147 }
148
149 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
150 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
151 stream->s_config.mem_vtbl.clean_invalidate_buf =
152 mm_app_stream_clean_invalidate_buf;
153 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
154 stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
155 stream->s_config.mem_vtbl.user_data = (void *)stream;
156 stream->s_config.stream_cb = stream_cb;
157 stream->s_config.stream_cb_sync = NULL;
158 stream->s_config.userdata = userdata;
159 stream->num_of_bufs = num_bufs;
160
161 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
162 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
163 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
164 if (num_burst == 0) {
165 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
166 } else {
167 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
168 stream->s_config.stream_info->num_of_burst = num_burst;
169 }
170 stream->s_config.stream_info->fmt = DEFAULT_RAW_FORMAT;
171 stream->s_config.stream_info->num_bufs = num_bufs;
172 LOGD(" RAW: w: %d, h: %d ",
173 cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
174
175 stream->s_config.stream_info->dim.width = cam_cap->raw_dim[0].width;
176 stream->s_config.stream_info->dim.height = cam_cap->raw_dim[0].height;
177 stream->s_config.padding_info = cam_cap->padding_info;
178
179 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
180 if (MM_CAMERA_OK != rc) {
181 LOGE("config rdi stream err=%d\n", rc);
182 return NULL;
183 }
184
185 buf_planes = &stream->s_config.stream_info->buf_planes;
186 rdi_len = buf_planes->plane_info.mp[0].len;
187 LOGD(" plane_info %dx%d len:%d frame_len:%d\n",
188 buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline,
189 buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len);
190
191 return stream;
192 }
193
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)194 mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj,
195 mm_camera_channel_t *channel,
196 mm_camera_buf_notify_t stream_cb,
197 void *userdata,
198 uint8_t num_bufs,
199 uint8_t num_burst)
200 {
201 int rc = MM_CAMERA_OK;
202 mm_camera_stream_t *stream = NULL;
203 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
204
205 stream = mm_app_add_stream(test_obj, channel);
206 if (NULL == stream) {
207 LOGE(" add stream failed\n");
208 return NULL;
209 }
210
211 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
212 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
213 stream->s_config.mem_vtbl.clean_invalidate_buf =
214 mm_app_stream_clean_invalidate_buf;
215 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
216 stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
217 stream->s_config.mem_vtbl.user_data = (void *)stream;
218 stream->s_config.stream_cb = stream_cb;
219 stream->s_config.stream_cb_sync = NULL;
220 stream->s_config.userdata = userdata;
221 stream->num_of_bufs = num_bufs;
222
223 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
224 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
225 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
226 if (num_burst == 0) {
227 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
228 } else {
229 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
230 stream->s_config.stream_info->num_of_burst = num_burst;
231 }
232 stream->s_config.stream_info->num_bufs = num_bufs;
233 stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
234 stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
235 stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
236 stream->s_config.padding_info = cam_cap->padding_info;
237
238 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
239 if (MM_CAMERA_OK != rc) {
240 LOGE("config rdi stream err=%d\n", rc);
241 return NULL;
242 }
243
244 return stream;
245 }
246
mm_app_add_rdi_channel(mm_camera_test_obj_t * test_obj,uint8_t num_burst)247 mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
248 {
249 mm_camera_channel_t *channel = NULL;
250 mm_camera_stream_t *stream = NULL;
251
252 channel = mm_app_add_channel(test_obj,
253 MM_CHANNEL_TYPE_RDI,
254 NULL,
255 NULL,
256 NULL);
257 if (NULL == channel) {
258 LOGE(" add channel failed");
259 return NULL;
260 }
261
262 stream = mm_app_add_rdi_stream(test_obj,
263 channel,
264 mm_app_rdi_notify_cb,
265 (void *)test_obj,
266 RDI_BUF_NUM,
267 num_burst);
268 if (NULL == stream) {
269 LOGE(" add stream failed\n");
270 mm_app_del_channel(test_obj, channel);
271 return NULL;
272 }
273
274 LOGD(" channel=%d stream=%d\n", channel->ch_id, stream->s_id);
275 return channel;
276 }
277
mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)278 int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj,
279 mm_camera_channel_t *channel)
280 {
281 int rc = MM_CAMERA_OK;
282 mm_camera_stream_t *stream = NULL;
283 uint8_t i;
284 cam_stream_size_info_t abc ;
285 memset (&abc , 0, sizeof (cam_stream_size_info_t));
286
287 rc = mm_app_stop_channel(test_obj, channel);
288 if (MM_CAMERA_OK != rc) {
289 LOGE("Stop RDI failed rc=%d\n", rc);
290 }
291
292 if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
293 for (i = 0; i < channel->num_streams; i++) {
294 stream = &channel->streams[i];
295 rc = mm_app_del_stream(test_obj, channel, stream);
296 if (MM_CAMERA_OK != rc) {
297 LOGE("del stream(%d) failed rc=%d\n", i, rc);
298 }
299 }
300 } else {
301 LOGE(" num_streams = %d. Should not be more than %d\n",
302 channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
303 }
304 rc = setmetainfoCommand(test_obj, &abc);
305 if (rc != MM_CAMERA_OK) {
306 LOGE(" meta info command failed\n");
307 }
308 rc = mm_app_del_channel(test_obj, channel);
309 if (MM_CAMERA_OK != rc) {
310 LOGE("delete channel failed rc=%d\n", rc);
311 }
312
313 return rc;
314 }
315
mm_app_start_rdi(mm_camera_test_obj_t * test_obj,uint8_t num_burst)316 int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
317 {
318 int rc = MM_CAMERA_OK;
319 mm_camera_channel_t *channel = NULL;
320
321 channel = mm_app_add_rdi_channel(test_obj, num_burst);
322 if (NULL == channel) {
323 LOGE(" add channel failed");
324 return -MM_CAMERA_E_GENERAL;
325 }
326
327 rc = mm_app_start_channel(test_obj, channel);
328 if (MM_CAMERA_OK != rc) {
329 LOGE("start rdi failed rc=%d\n", rc);
330 mm_app_del_channel(test_obj, channel);
331 return rc;
332 }
333
334 return rc;
335 }
336
mm_app_stop_rdi(mm_camera_test_obj_t * test_obj)337 int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj)
338 {
339 int rc = MM_CAMERA_OK;
340
341 mm_camera_channel_t *channel =
342 mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI);
343
344 rc = mm_app_stop_and_del_rdi_channel(test_obj, channel);
345 if (MM_CAMERA_OK != rc) {
346 LOGE("Stop RDI failed rc=%d\n", rc);
347 }
348
349 return rc;
350 }
351
352