mm_qcamera_preview.c revision a1724bc599bec5b2fbe3f4a34d0eca2406ba4c5f
1/*
2Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
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
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include "mm_qcamera_dbg.h"
31#include "mm_qcamera_app.h"
32
33static 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
56static 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
149mm_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.user_data = (void *)stream;
170    stream->s_config.stream_cb = stream_cb;
171    stream->s_config.userdata = userdata;
172    stream->num_of_bufs = num_bufs;
173
174    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
175    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
176    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
177    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
178    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
179    stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
180    stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
181    stream->s_config.padding_info = cam_cap->padding_info;
182
183    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
184    if (MM_CAMERA_OK != rc) {
185        CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
186        return NULL;
187    }
188
189    return stream;
190}
191
192mm_camera_stream_t * mm_app_add_snapshot_stream(mm_camera_test_obj_t *test_obj,
193                                                mm_camera_channel_t *channel,
194                                                mm_camera_buf_notify_t stream_cb,
195                                                void *userdata,
196                                                uint8_t num_bufs,
197                                                uint8_t num_burst)
198{
199    int rc = MM_CAMERA_OK;
200    mm_camera_stream_t *stream = NULL;
201    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
202
203    stream = mm_app_add_stream(test_obj, channel);
204    if (NULL == stream) {
205        CDBG_ERROR("%s: add stream failed\n", __func__);
206        return NULL;
207    }
208
209    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
210    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
211    stream->s_config.mem_vtbl.clean_invalidate_buf =
212      mm_app_stream_clean_invalidate_buf;
213    stream->s_config.mem_vtbl.user_data = (void *)stream;
214    stream->s_config.stream_cb = stream_cb;
215    stream->s_config.userdata = userdata;
216    stream->num_of_bufs = num_bufs;
217
218    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
219    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
220    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
221    if (num_burst == 0) {
222        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
223    } else {
224        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
225        stream->s_config.stream_info->num_of_burst = num_burst;
226    }
227    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
228    stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
229    stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
230    stream->s_config.padding_info = cam_cap->padding_info;
231
232    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
233    if (MM_CAMERA_OK != rc) {
234        CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
235        return NULL;
236    }
237
238    return stream;
239}
240
241mm_camera_channel_t * mm_app_add_preview_channel(mm_camera_test_obj_t *test_obj)
242{
243    mm_camera_channel_t *channel = NULL;
244    mm_camera_stream_t *stream = NULL;
245
246    channel = mm_app_add_channel(test_obj,
247                                 MM_CHANNEL_TYPE_PREVIEW,
248                                 NULL,
249                                 NULL,
250                                 NULL);
251    if (NULL == channel) {
252        CDBG_ERROR("%s: add channel failed", __func__);
253        return NULL;
254    }
255
256    stream = mm_app_add_preview_stream(test_obj,
257                                       channel,
258                                       mm_app_preview_notify_cb,
259                                       (void *)test_obj,
260                                       PREVIEW_BUF_NUM);
261    if (NULL == stream) {
262        CDBG_ERROR("%s: add stream failed\n", __func__);
263        mm_app_del_channel(test_obj, channel);
264        return NULL;
265    }
266
267    return channel;
268}
269
270int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
271                                mm_camera_channel_t *channel)
272{
273    int rc = MM_CAMERA_OK;
274    mm_camera_stream_t *stream = NULL;
275    uint8_t i;
276
277    rc = mm_app_stop_channel(test_obj, channel);
278    if (MM_CAMERA_OK != rc) {
279        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
280    }
281
282    for (i = 0; i < channel->num_streams; i++) {
283        stream = &channel->streams[i];
284        rc = mm_app_del_stream(test_obj, channel, stream);
285        if (MM_CAMERA_OK != rc) {
286            CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
287        }
288    }
289
290    rc = mm_app_del_channel(test_obj, channel);
291    if (MM_CAMERA_OK != rc) {
292        CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
293    }
294
295    return rc;
296}
297
298int mm_app_start_preview(mm_camera_test_obj_t *test_obj)
299{
300    int rc = MM_CAMERA_OK;
301    mm_camera_channel_t *channel = NULL;
302    mm_camera_stream_t *stream = NULL;
303    uint8_t i;
304
305    channel =  mm_app_add_preview_channel(test_obj);
306    if (NULL == channel) {
307        CDBG_ERROR("%s: add channel failed", __func__);
308        return -MM_CAMERA_E_GENERAL;
309    }
310
311    rc = mm_app_start_channel(test_obj, channel);
312    if (MM_CAMERA_OK != rc) {
313        CDBG_ERROR("%s:start preview failed rc=%d\n", __func__, rc);
314        for (i = 0; i < channel->num_streams; i++) {
315            stream = &channel->streams[i];
316            mm_app_del_stream(test_obj, channel, stream);
317        }
318        mm_app_del_channel(test_obj, channel);
319        return rc;
320    }
321
322    return rc;
323}
324
325int mm_app_stop_preview(mm_camera_test_obj_t *test_obj)
326{
327    int rc = MM_CAMERA_OK;
328
329    mm_camera_channel_t *channel =
330        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
331
332    rc = mm_app_stop_and_del_channel(test_obj, channel);
333    if (MM_CAMERA_OK != rc) {
334        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
335    }
336
337    return rc;
338}
339
340int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj)
341{
342    int32_t rc = MM_CAMERA_OK;
343    mm_camera_channel_t *channel = NULL;
344    mm_camera_stream_t *s_preview = NULL;
345    mm_camera_stream_t *s_main = NULL;
346    mm_camera_channel_attr_t attr;
347
348    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
349    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
350    attr.look_back = 2;
351    attr.post_frame_skip = 0;
352    attr.water_mark = 2;
353    attr.max_unmatched_frames = 3;
354    channel = mm_app_add_channel(test_obj,
355                                 MM_CHANNEL_TYPE_ZSL,
356                                 &attr,
357                                 mm_app_zsl_notify_cb,
358                                 test_obj);
359    if (NULL == channel) {
360        CDBG_ERROR("%s: add channel failed", __func__);
361        return -MM_CAMERA_E_GENERAL;
362    }
363
364    s_preview = mm_app_add_preview_stream(test_obj,
365                                          channel,
366                                          mm_app_preview_notify_cb,
367                                          (void *)test_obj,
368                                          PREVIEW_BUF_NUM);
369    if (NULL == s_preview) {
370        CDBG_ERROR("%s: add preview stream failed\n", __func__);
371        mm_app_del_channel(test_obj, channel);
372        return rc;
373    }
374
375    s_main = mm_app_add_snapshot_stream(test_obj,
376                                        channel,
377                                        NULL,
378                                        NULL,
379                                        PREVIEW_BUF_NUM,
380                                        0);
381    if (NULL == s_main) {
382        CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
383        mm_app_del_stream(test_obj, channel, s_preview);
384        mm_app_del_channel(test_obj, channel);
385        return rc;
386    }
387
388    rc = mm_app_start_channel(test_obj, channel);
389    if (MM_CAMERA_OK != rc) {
390        CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
391        mm_app_del_stream(test_obj, channel, s_preview);
392        mm_app_del_stream(test_obj, channel, s_main);
393        mm_app_del_channel(test_obj, channel);
394        return rc;
395    }
396
397    return rc;
398}
399
400int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj)
401{
402    int rc = MM_CAMERA_OK;
403
404    mm_camera_channel_t *channel =
405        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_ZSL);
406
407    rc = mm_app_stop_and_del_channel(test_obj, channel);
408    if (MM_CAMERA_OK != rc) {
409        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
410    }
411
412    return rc;
413}
414