mm_qcamera_preview.c revision 6f83d735d8e3b918da42e6b559fcd0efb78133e5
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.user_data = (void *)stream;
168    stream->s_config.stream_cb = stream_cb;
169    stream->s_config.userdata = userdata;
170    stream->num_of_bufs = num_bufs;
171
172    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
173    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
174    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
175    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
176    stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
177    stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
178    stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
179    stream->s_config.padding_info = cam_cap->padding_info;
180
181    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
182    if (MM_CAMERA_OK != rc) {
183        CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
184        return NULL;
185    }
186
187    return stream;
188}
189
190mm_camera_stream_t * mm_app_add_snapshot_stream(mm_camera_test_obj_t *test_obj,
191                                                mm_camera_channel_t *channel,
192                                                mm_camera_buf_notify_t stream_cb,
193                                                void *userdata,
194                                                uint8_t num_bufs,
195                                                uint8_t num_burst)
196{
197    int rc = MM_CAMERA_OK;
198    mm_camera_stream_t *stream = NULL;
199    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
200
201    stream = mm_app_add_stream(test_obj, channel);
202    if (NULL == stream) {
203        CDBG_ERROR("%s: add stream failed\n", __func__);
204        return NULL;
205    }
206
207    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
208    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
209    stream->s_config.mem_vtbl.user_data = (void *)stream;
210    stream->s_config.stream_cb = stream_cb;
211    stream->s_config.userdata = userdata;
212    stream->num_of_bufs = num_bufs;
213
214    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
215    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
216    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
217    if (num_burst == 0) {
218        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
219    } else {
220        stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
221        stream->s_config.stream_info->num_of_burst = num_burst;
222    }
223    stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
224    stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
225    stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
226    stream->s_config.padding_info = cam_cap->padding_info;
227
228    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
229    if (MM_CAMERA_OK != rc) {
230        CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
231        return NULL;
232    }
233
234    return stream;
235}
236
237mm_camera_channel_t * mm_app_add_preview_channel(mm_camera_test_obj_t *test_obj)
238{
239    mm_camera_channel_t *channel = NULL;
240    mm_camera_stream_t *stream = NULL;
241
242    channel = mm_app_add_channel(test_obj,
243                                 MM_CHANNEL_TYPE_PREVIEW,
244                                 NULL,
245                                 NULL,
246                                 NULL);
247    if (NULL == channel) {
248        CDBG_ERROR("%s: add channel failed", __func__);
249        return NULL;
250    }
251
252    stream = mm_app_add_preview_stream(test_obj,
253                                       channel,
254                                       mm_app_preview_notify_cb,
255                                       (void *)test_obj,
256                                       PREVIEW_BUF_NUM);
257    if (NULL == stream) {
258        CDBG_ERROR("%s: add stream failed\n", __func__);
259        mm_app_del_channel(test_obj, channel);
260        return NULL;
261    }
262
263    return channel;
264}
265
266int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
267                                mm_camera_channel_t *channel)
268{
269    int rc = MM_CAMERA_OK;
270    mm_camera_stream_t *stream = NULL;
271    uint8_t i;
272
273    rc = mm_app_stop_channel(test_obj, channel);
274    if (MM_CAMERA_OK != rc) {
275        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
276    }
277
278    for (i = 0; i < channel->num_streams; i++) {
279        stream = &channel->streams[i];
280        rc = mm_app_del_stream(test_obj, channel, stream);
281        if (MM_CAMERA_OK != rc) {
282            CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
283        }
284    }
285
286    rc = mm_app_del_channel(test_obj, channel);
287    if (MM_CAMERA_OK != rc) {
288        CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
289    }
290
291    return rc;
292}
293
294int mm_app_start_preview(mm_camera_test_obj_t *test_obj)
295{
296    int rc = MM_CAMERA_OK;
297    mm_camera_channel_t *channel = NULL;
298    mm_camera_stream_t *stream = NULL;
299    uint8_t i;
300
301    channel =  mm_app_add_preview_channel(test_obj);
302    if (NULL == channel) {
303        CDBG_ERROR("%s: add channel failed", __func__);
304        return -MM_CAMERA_E_GENERAL;
305    }
306
307    rc = mm_app_start_channel(test_obj, channel);
308    if (MM_CAMERA_OK != rc) {
309        CDBG_ERROR("%s:start preview failed rc=%d\n", __func__, rc);
310        for (i = 0; i < channel->num_streams; i++) {
311            stream = &channel->streams[i];
312            mm_app_del_stream(test_obj, channel, stream);
313        }
314        mm_app_del_channel(test_obj, channel);
315        return rc;
316    }
317
318    return rc;
319}
320
321int mm_app_stop_preview(mm_camera_test_obj_t *test_obj)
322{
323    int rc = MM_CAMERA_OK;
324
325    mm_camera_channel_t *channel =
326        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
327
328    rc = mm_app_stop_and_del_channel(test_obj, channel);
329    if (MM_CAMERA_OK != rc) {
330        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
331    }
332
333    return rc;
334}
335
336int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj)
337{
338    int32_t rc = MM_CAMERA_OK;
339    mm_camera_channel_t *channel = NULL;
340    mm_camera_stream_t *s_preview = NULL;
341    mm_camera_stream_t *s_main = NULL;
342    mm_camera_channel_attr_t attr;
343
344    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
345    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
346    attr.look_back = 2;
347    attr.post_frame_skip = 0;
348    attr.water_mark = 2;
349    attr.max_unmatched_frames = 3;
350    channel = mm_app_add_channel(test_obj,
351                                 MM_CHANNEL_TYPE_ZSL,
352                                 &attr,
353                                 mm_app_zsl_notify_cb,
354                                 test_obj);
355    if (NULL == channel) {
356        CDBG_ERROR("%s: add channel failed", __func__);
357        return -MM_CAMERA_E_GENERAL;
358    }
359
360    s_preview = mm_app_add_preview_stream(test_obj,
361                                          channel,
362                                          mm_app_preview_notify_cb,
363                                          (void *)test_obj,
364                                          PREVIEW_BUF_NUM);
365    if (NULL == s_preview) {
366        CDBG_ERROR("%s: add preview stream failed\n", __func__);
367        mm_app_del_channel(test_obj, channel);
368        return rc;
369    }
370
371    s_main = mm_app_add_snapshot_stream(test_obj,
372                                        channel,
373                                        NULL,
374                                        NULL,
375                                        PREVIEW_BUF_NUM,
376                                        0);
377    if (NULL == s_main) {
378        CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
379        mm_app_del_stream(test_obj, channel, s_preview);
380        mm_app_del_channel(test_obj, channel);
381        return rc;
382    }
383
384    rc = mm_app_start_channel(test_obj, channel);
385    if (MM_CAMERA_OK != rc) {
386        CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
387        mm_app_del_stream(test_obj, channel, s_preview);
388        mm_app_del_stream(test_obj, channel, s_main);
389        mm_app_del_channel(test_obj, channel);
390        return rc;
391    }
392
393    return rc;
394}
395
396int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj)
397{
398    int rc = MM_CAMERA_OK;
399
400    mm_camera_channel_t *channel =
401        mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_ZSL);
402
403    rc = mm_app_stop_and_del_channel(test_obj, channel);
404    if (MM_CAMERA_OK != rc) {
405        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
406    }
407
408    return rc;
409}
410