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 
mm_app_preview_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)33 static void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
34                                      void *user_data)
35 {
36     char file_name[64];
37     mm_camera_buf_def_t *frame = bufs->bufs[0];
38     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
39 
40     CDBG("%s: BEGIN - length=%d, frame idx = %d\n",
41          __func__, frame->frame_len, frame->frame_idx);
42     snprintf(file_name, sizeof(file_name), "P_C%d", pme->cam->camera_handle);
43     mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
44 
45     if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
46                                             bufs->ch_id,
47                                             frame)) {
48         CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
49     }
50     mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
51                      ION_IOC_INV_CACHES);
52 
53     CDBG("%s: END\n", __func__);
54 }
55 
mm_app_zsl_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)56 static void mm_app_zsl_notify_cb(mm_camera_super_buf_t *bufs,
57                                  void *user_data)
58 {
59     int i = 0;
60     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
61     mm_camera_channel_t *channel = NULL;
62     mm_camera_stream_t *p_stream = NULL;
63     mm_camera_stream_t *m_stream = NULL;
64     mm_camera_buf_def_t *p_frame = NULL;
65     mm_camera_buf_def_t *m_frame = NULL;
66 
67     CDBG("%s: BEGIN\n", __func__);
68 
69     /* find channel */
70     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
71         if (pme->channels[i].ch_id == bufs->ch_id) {
72             channel = &pme->channels[i];
73             break;
74         }
75     }
76     if (NULL == channel) {
77         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
78         return;
79     }
80 
81     /* find preview stream */
82     for (i = 0; i < channel->num_streams; i++) {
83         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
84             p_stream = &channel->streams[i];
85             break;
86         }
87     }
88     if (NULL == p_stream) {
89         CDBG_ERROR("%s: cannot find preview stream", __func__);
90         return;
91     }
92 
93     /* find snapshot stream */
94     for (i = 0; i < channel->num_streams; i++) {
95         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
96             m_stream = &channel->streams[i];
97             break;
98         }
99     }
100     if (NULL == m_stream) {
101         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
102         return;
103     }
104 
105     /* find preview frame */
106     for (i = 0; i < bufs->num_bufs; i++) {
107         if (bufs->bufs[i]->stream_id == p_stream->s_id) {
108             p_frame = bufs->bufs[i];
109             break;
110         }
111     }
112 
113     /* find snapshot frame */
114     for (i = 0; i < bufs->num_bufs; i++) {
115         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
116             m_frame = bufs->bufs[i];
117             break;
118         }
119     }
120 
121     if (!m_frame || !p_frame) {
122         CDBG_ERROR("%s: cannot find preview/snapshot frame", __func__);
123         return;
124     }
125 
126     mm_app_dump_frame(p_frame, "zsl_preview", "yuv", p_frame->frame_idx);
127     mm_app_dump_frame(m_frame, "zsl_main", "yuv", m_frame->frame_idx);
128 
129     if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
130                                             bufs->ch_id,
131                                             p_frame)) {
132         CDBG_ERROR("%s: Failed in preview Qbuf\n", __func__);
133     }
134     mm_app_cache_ops((mm_camera_app_meminfo_t *)p_frame->mem_info,
135                      ION_IOC_INV_CACHES);
136 
137 
138     if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
139                                             bufs->ch_id,
140                                             m_frame)) {
141         CDBG_ERROR("%s: Failed in main Qbuf\n", __func__);
142     }
143     mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
144                      ION_IOC_INV_CACHES);
145 
146     CDBG("%s: END\n", __func__);
147 }
148 
mm_app_add_preview_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)149 mm_camera_stream_t * mm_app_add_preview_stream(mm_camera_test_obj_t *test_obj,
150                                                mm_camera_channel_t *channel,
151                                                mm_camera_buf_notify_t stream_cb,
152                                                void *userdata,
153                                                uint8_t num_bufs)
154 {
155     int rc = MM_CAMERA_OK;
156     mm_camera_stream_t *stream = NULL;
157     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
158 
159     stream = mm_app_add_stream(test_obj, channel);
160     if (NULL == stream) {
161         CDBG_ERROR("%s: add stream failed\n", __func__);
162         return NULL;
163     }
164 
165     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
166     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
167     stream->s_config.mem_vtbl.clean_invalidate_buf =
168       mm_app_stream_clean_invalidate_buf;
169     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
170     stream->s_config.mem_vtbl.user_data = (void *)stream;
171     stream->s_config.stream_cb = stream_cb;
172     stream->s_config.userdata = userdata;
173     stream->num_of_bufs = num_bufs;
174 
175     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
176     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
177     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
178     stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
179     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
180     stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
181     stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
182     stream->s_config.padding_info = cam_cap->padding_info;
183 
184     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
185     if (MM_CAMERA_OK != rc) {
186         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
187         return NULL;
188     }
189 
190     return stream;
191 }
192 
mm_app_add_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_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         CDBG_ERROR("%s: add stream failed\n", __func__);
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.userdata = userdata;
218     stream->num_of_bufs = num_bufs;
219 
220     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
221     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
222     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
223     if (num_burst == 0) {
224         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
225     } else {
226         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
227         stream->s_config.stream_info->num_of_burst = num_burst;
228     }
229     stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
230     stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
231     stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
232     stream->s_config.padding_info = cam_cap->padding_info;
233 
234     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
235     if (MM_CAMERA_OK != rc) {
236         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
237         return NULL;
238     }
239 
240     return stream;
241 }
242 
mm_app_add_preview_channel(mm_camera_test_obj_t * test_obj)243 mm_camera_channel_t * mm_app_add_preview_channel(mm_camera_test_obj_t *test_obj)
244 {
245     mm_camera_channel_t *channel = NULL;
246     mm_camera_stream_t *stream = NULL;
247 
248     channel = mm_app_add_channel(test_obj,
249                                  MM_CHANNEL_TYPE_PREVIEW,
250                                  NULL,
251                                  NULL,
252                                  NULL);
253     if (NULL == channel) {
254         CDBG_ERROR("%s: add channel failed", __func__);
255         return NULL;
256     }
257 
258     stream = mm_app_add_preview_stream(test_obj,
259                                        channel,
260                                        mm_app_preview_notify_cb,
261                                        (void *)test_obj,
262                                        PREVIEW_BUF_NUM);
263     if (NULL == stream) {
264         CDBG_ERROR("%s: add stream failed\n", __func__);
265         mm_app_del_channel(test_obj, channel);
266         return NULL;
267     }
268 
269     return channel;
270 }
271 
mm_app_stop_and_del_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)272 int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
273                                 mm_camera_channel_t *channel)
274 {
275     int rc = MM_CAMERA_OK;
276     mm_camera_stream_t *stream = NULL;
277     uint8_t i;
278 
279     rc = mm_app_stop_channel(test_obj, channel);
280     if (MM_CAMERA_OK != rc) {
281         CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
282     }
283 
284     for (i = 0; i < channel->num_streams; i++) {
285         stream = &channel->streams[i];
286         rc = mm_app_del_stream(test_obj, channel, stream);
287         if (MM_CAMERA_OK != rc) {
288             CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
289         }
290     }
291 
292     rc = mm_app_del_channel(test_obj, channel);
293     if (MM_CAMERA_OK != rc) {
294         CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
295     }
296 
297     return rc;
298 }
299 
mm_app_start_preview(mm_camera_test_obj_t * test_obj)300 int mm_app_start_preview(mm_camera_test_obj_t *test_obj)
301 {
302     int rc = MM_CAMERA_OK;
303     mm_camera_channel_t *channel = NULL;
304     mm_camera_stream_t *stream = NULL;
305     uint8_t i;
306 
307     channel =  mm_app_add_preview_channel(test_obj);
308     if (NULL == channel) {
309         CDBG_ERROR("%s: add channel failed", __func__);
310         return -MM_CAMERA_E_GENERAL;
311     }
312 
313     rc = mm_app_start_channel(test_obj, channel);
314     if (MM_CAMERA_OK != rc) {
315         CDBG_ERROR("%s:start preview failed rc=%d\n", __func__, rc);
316         for (i = 0; i < channel->num_streams; i++) {
317             stream = &channel->streams[i];
318             mm_app_del_stream(test_obj, channel, stream);
319         }
320         mm_app_del_channel(test_obj, channel);
321         return rc;
322     }
323 
324     return rc;
325 }
326 
mm_app_stop_preview(mm_camera_test_obj_t * test_obj)327 int mm_app_stop_preview(mm_camera_test_obj_t *test_obj)
328 {
329     int rc = MM_CAMERA_OK;
330 
331     mm_camera_channel_t *channel =
332         mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
333 
334     rc = mm_app_stop_and_del_channel(test_obj, channel);
335     if (MM_CAMERA_OK != rc) {
336         CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
337     }
338 
339     return rc;
340 }
341 
mm_app_start_preview_zsl(mm_camera_test_obj_t * test_obj)342 int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj)
343 {
344     int32_t rc = MM_CAMERA_OK;
345     mm_camera_channel_t *channel = NULL;
346     mm_camera_stream_t *s_preview = NULL;
347     mm_camera_stream_t *s_main = NULL;
348     mm_camera_channel_attr_t attr;
349 
350     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
351     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
352     attr.look_back = 2;
353     attr.post_frame_skip = 0;
354     attr.water_mark = 2;
355     attr.max_unmatched_frames = 3;
356     channel = mm_app_add_channel(test_obj,
357                                  MM_CHANNEL_TYPE_ZSL,
358                                  &attr,
359                                  mm_app_zsl_notify_cb,
360                                  test_obj);
361     if (NULL == channel) {
362         CDBG_ERROR("%s: add channel failed", __func__);
363         return -MM_CAMERA_E_GENERAL;
364     }
365 
366     s_preview = mm_app_add_preview_stream(test_obj,
367                                           channel,
368                                           mm_app_preview_notify_cb,
369                                           (void *)test_obj,
370                                           PREVIEW_BUF_NUM);
371     if (NULL == s_preview) {
372         CDBG_ERROR("%s: add preview stream failed\n", __func__);
373         mm_app_del_channel(test_obj, channel);
374         return rc;
375     }
376 
377     s_main = mm_app_add_snapshot_stream(test_obj,
378                                         channel,
379                                         NULL,
380                                         NULL,
381                                         PREVIEW_BUF_NUM,
382                                         0);
383     if (NULL == s_main) {
384         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
385         mm_app_del_stream(test_obj, channel, s_preview);
386         mm_app_del_channel(test_obj, channel);
387         return rc;
388     }
389 
390     rc = mm_app_start_channel(test_obj, channel);
391     if (MM_CAMERA_OK != rc) {
392         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
393         mm_app_del_stream(test_obj, channel, s_preview);
394         mm_app_del_stream(test_obj, channel, s_main);
395         mm_app_del_channel(test_obj, channel);
396         return rc;
397     }
398 
399     return rc;
400 }
401 
mm_app_stop_preview_zsl(mm_camera_test_obj_t * test_obj)402 int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj)
403 {
404     int rc = MM_CAMERA_OK;
405 
406     mm_camera_channel_t *channel =
407         mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_ZSL);
408 
409     rc = mm_app_stop_and_del_channel(test_obj, channel);
410     if (MM_CAMERA_OK != rc) {
411         CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
412     }
413 
414     return rc;
415 }
416