mm_qcamera_preview.c revision 6591d7fc4818d50ce096e781b14deda6903dbe57
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.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
193mm_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
243mm_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
272int 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
300int 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
327int 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
342int 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
402int 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