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