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 = 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.user_data = (void *)stream;
154 stream->s_config.stream_cb = stream_cb;
155 stream->s_config.stream_cb_sync = NULL;
156 stream->s_config.userdata = userdata;
157 stream->num_of_bufs = num_bufs;
158
159 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
160 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
161 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
162 if (num_burst == 0) {
163 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
164 } else {
165 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
166 stream->s_config.stream_info->num_of_burst = num_burst;
167 }
168 stream->s_config.stream_info->fmt = DEFAULT_RAW_FORMAT;
169 LOGD(" RAW: w: %d, h: %d ",
170 cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
171
172 stream->s_config.stream_info->dim.width = cam_cap->raw_dim[0].width;
173 stream->s_config.stream_info->dim.height = cam_cap->raw_dim[0].height;
174 stream->s_config.padding_info = cam_cap->padding_info;
175
176 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
177 if (MM_CAMERA_OK != rc) {
178 LOGE("config rdi stream err=%d\n", rc);
179 return NULL;
180 }
181
182 buf_planes = &stream->s_config.stream_info->buf_planes;
183 rdi_len = buf_planes->plane_info.mp[0].len;
184 LOGD(" plane_info %dx%d len:%d frame_len:%d\n",
185 buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline,
186 buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len);
187
188 return stream;
189 }
190
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)191 mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj,
192 mm_camera_channel_t *channel,
193 mm_camera_buf_notify_t stream_cb,
194 void *userdata,
195 uint8_t num_bufs,
196 uint8_t num_burst)
197 {
198 int rc = MM_CAMERA_OK;
199 mm_camera_stream_t *stream = NULL;
200 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
201
202 stream = mm_app_add_stream(test_obj, channel);
203 if (NULL == stream) {
204 LOGE(" add stream failed\n");
205 return NULL;
206 }
207
208 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
209 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
210 stream->s_config.mem_vtbl.clean_invalidate_buf =
211 mm_app_stream_clean_invalidate_buf;
212 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
213 stream->s_config.mem_vtbl.user_data = (void *)stream;
214 stream->s_config.stream_cb = stream_cb;
215 stream->s_config.stream_cb_sync = NULL;
216 stream->s_config.userdata = userdata;
217 stream->num_of_bufs = num_bufs;
218
219 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
220 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
221 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
222 if (num_burst == 0) {
223 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
224 } else {
225 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
226 stream->s_config.stream_info->num_of_burst = num_burst;
227 }
228 stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
229 stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
230 stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
231 stream->s_config.padding_info = cam_cap->padding_info;
232
233 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
234 if (MM_CAMERA_OK != rc) {
235 LOGE("config rdi stream err=%d\n", rc);
236 return NULL;
237 }
238
239 return stream;
240 }
241
mm_app_add_rdi_channel(mm_camera_test_obj_t * test_obj,uint8_t num_burst)242 mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
243 {
244 mm_camera_channel_t *channel = NULL;
245 mm_camera_stream_t *stream = NULL;
246
247 channel = mm_app_add_channel(test_obj,
248 MM_CHANNEL_TYPE_RDI,
249 NULL,
250 NULL,
251 NULL);
252 if (NULL == channel) {
253 LOGE(" add channel failed");
254 return NULL;
255 }
256
257 stream = mm_app_add_rdi_stream(test_obj,
258 channel,
259 mm_app_rdi_notify_cb,
260 (void *)test_obj,
261 RDI_BUF_NUM,
262 num_burst);
263 if (NULL == stream) {
264 LOGE(" add stream failed\n");
265 mm_app_del_channel(test_obj, channel);
266 return NULL;
267 }
268
269 LOGD(" channel=%d stream=%d\n", channel->ch_id, stream->s_id);
270 return channel;
271 }
272
mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)273 int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj,
274 mm_camera_channel_t *channel)
275 {
276 int rc = MM_CAMERA_OK;
277 mm_camera_stream_t *stream = NULL;
278 uint8_t i;
279 cam_stream_size_info_t abc ;
280 memset (&abc , 0, sizeof (cam_stream_size_info_t));
281
282 rc = mm_app_stop_channel(test_obj, channel);
283 if (MM_CAMERA_OK != rc) {
284 LOGE("Stop RDI failed rc=%d\n", rc);
285 }
286
287 if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
288 for (i = 0; i < channel->num_streams; i++) {
289 stream = &channel->streams[i];
290 rc = mm_app_del_stream(test_obj, channel, stream);
291 if (MM_CAMERA_OK != rc) {
292 LOGE("del stream(%d) failed rc=%d\n", i, rc);
293 }
294 }
295 } else {
296 LOGE(" num_streams = %d. Should not be more than %d\n",
297 channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
298 }
299 rc = setmetainfoCommand(test_obj, &abc);
300 if (rc != MM_CAMERA_OK) {
301 LOGE(" meta info command failed\n");
302 }
303 rc = mm_app_del_channel(test_obj, channel);
304 if (MM_CAMERA_OK != rc) {
305 LOGE("delete channel failed rc=%d\n", rc);
306 }
307
308 return rc;
309 }
310
mm_app_start_rdi(mm_camera_test_obj_t * test_obj,uint8_t num_burst)311 int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
312 {
313 int rc = MM_CAMERA_OK;
314 mm_camera_channel_t *channel = NULL;
315
316 channel = mm_app_add_rdi_channel(test_obj, num_burst);
317 if (NULL == channel) {
318 LOGE(" add channel failed");
319 return -MM_CAMERA_E_GENERAL;
320 }
321
322 rc = mm_app_start_channel(test_obj, channel);
323 if (MM_CAMERA_OK != rc) {
324 LOGE("start rdi failed rc=%d\n", rc);
325 mm_app_del_channel(test_obj, channel);
326 return rc;
327 }
328
329 return rc;
330 }
331
mm_app_stop_rdi(mm_camera_test_obj_t * test_obj)332 int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj)
333 {
334 int rc = MM_CAMERA_OK;
335
336 mm_camera_channel_t *channel =
337 mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI);
338
339 rc = mm_app_stop_and_del_rdi_channel(test_obj, channel);
340 if (MM_CAMERA_OK != rc) {
341 LOGE("Stop RDI failed rc=%d\n", rc);
342 }
343
344 return rc;
345 }
346
347