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