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