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