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