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_video_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), "V_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
56mm_camera_stream_t * mm_app_add_video_stream(mm_camera_test_obj_t *test_obj,
57                                             mm_camera_channel_t *channel,
58                                             mm_camera_buf_notify_t stream_cb,
59                                             void *userdata,
60                                             uint8_t num_bufs)
61{
62    int rc = MM_CAMERA_OK;
63    mm_camera_stream_t *stream = NULL;
64    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
65
66    stream = mm_app_add_stream(test_obj, channel);
67    if (NULL == stream) {
68        CDBG_ERROR("%s: add stream failed\n", __func__);
69        return NULL;
70    }
71
72    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
73    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
74    stream->s_config.mem_vtbl.clean_invalidate_buf =
75      mm_app_stream_clean_invalidate_buf;
76    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
77    stream->s_config.mem_vtbl.user_data = (void *)stream;
78    stream->s_config.stream_cb = stream_cb;
79    stream->s_config.userdata = userdata;
80    stream->num_of_bufs = num_bufs;
81
82    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
83    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
84    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_VIDEO;
85    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
86    stream->s_config.stream_info->fmt = DEFAULT_VIDEO_FORMAT;
87    stream->s_config.stream_info->dim.width = DEFAULT_VIDEO_WIDTH;
88    stream->s_config.stream_info->dim.height = DEFAULT_VIDEO_HEIGHT;
89    stream->s_config.padding_info = cam_cap->padding_info;
90
91    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
92    if (MM_CAMERA_OK != rc) {
93        CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
94        return NULL;
95    }
96
97    return stream;
98}
99
100mm_camera_channel_t * mm_app_add_video_channel(mm_camera_test_obj_t *test_obj)
101{
102    mm_camera_channel_t *channel = NULL;
103    mm_camera_stream_t *stream = NULL;
104
105    channel = mm_app_add_channel(test_obj,
106                                 MM_CHANNEL_TYPE_VIDEO,
107                                 NULL,
108                                 NULL,
109                                 NULL);
110    if (NULL == channel) {
111        CDBG_ERROR("%s: add channel failed", __func__);
112        return NULL;
113    }
114
115    stream = mm_app_add_video_stream(test_obj,
116                                     channel,
117                                     mm_app_video_notify_cb,
118                                     (void *)test_obj,
119                                     1);
120    if (NULL == stream) {
121        CDBG_ERROR("%s: add video stream failed\n", __func__);
122        mm_app_del_channel(test_obj, channel);
123        return NULL;
124    }
125
126    return channel;
127}
128
129int mm_app_start_record_preview(mm_camera_test_obj_t *test_obj)
130{
131    int rc = MM_CAMERA_OK;
132    mm_camera_channel_t *p_ch = NULL;
133    mm_camera_channel_t *v_ch = NULL;
134    mm_camera_channel_t *s_ch = NULL;
135
136    p_ch = mm_app_add_preview_channel(test_obj);
137    if (NULL == p_ch) {
138        CDBG_ERROR("%s: add preview channel failed", __func__);
139        return -MM_CAMERA_E_GENERAL;
140    }
141
142    v_ch = mm_app_add_video_channel(test_obj);
143    if (NULL == v_ch) {
144        CDBG_ERROR("%s: add video channel failed", __func__);
145        mm_app_del_channel(test_obj, p_ch);
146        return -MM_CAMERA_E_GENERAL;
147    }
148
149    s_ch = mm_app_add_snapshot_channel(test_obj);
150    if (NULL == s_ch) {
151        CDBG_ERROR("%s: add snapshot channel failed", __func__);
152        mm_app_del_channel(test_obj, p_ch);
153        mm_app_del_channel(test_obj, v_ch);
154        return -MM_CAMERA_E_GENERAL;
155    }
156
157    rc = mm_app_start_channel(test_obj, p_ch);
158    if (MM_CAMERA_OK != rc) {
159        CDBG_ERROR("%s:start preview failed rc=%d\n", __func__, rc);
160        mm_app_del_channel(test_obj, p_ch);
161        mm_app_del_channel(test_obj, v_ch);
162        mm_app_del_channel(test_obj, s_ch);
163        return rc;
164    }
165
166    return rc;
167}
168
169int mm_app_stop_record_preview(mm_camera_test_obj_t *test_obj)
170{
171    int rc = MM_CAMERA_OK;
172    mm_camera_channel_t *p_ch = NULL;
173    mm_camera_channel_t *v_ch = NULL;
174    mm_camera_channel_t *s_ch = NULL;
175
176    p_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
177    v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
178    s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
179
180    rc = mm_app_stop_and_del_channel(test_obj, p_ch);
181    if (MM_CAMERA_OK != rc) {
182        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
183    }
184
185    rc = mm_app_stop_and_del_channel(test_obj, v_ch);
186    if (MM_CAMERA_OK != rc) {
187        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
188    }
189
190    rc = mm_app_stop_and_del_channel(test_obj, s_ch);
191    if (MM_CAMERA_OK != rc) {
192        CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
193    }
194
195    return rc;
196}
197
198int mm_app_start_record(mm_camera_test_obj_t *test_obj)
199{
200    int rc = MM_CAMERA_OK;
201    mm_camera_channel_t *v_ch = NULL;
202
203    v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
204
205    rc = mm_app_start_channel(test_obj, v_ch);
206    if (MM_CAMERA_OK != rc) {
207        CDBG_ERROR("%s:start recording failed rc=%d\n", __func__, rc);
208    }
209
210    return rc;
211}
212
213int mm_app_stop_record(mm_camera_test_obj_t *test_obj)
214{
215    int rc = MM_CAMERA_OK;
216    mm_camera_channel_t *v_ch = NULL;
217
218    v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
219
220    rc = mm_app_stop_channel(test_obj, v_ch);
221    if (MM_CAMERA_OK != rc) {
222        CDBG_ERROR("%s:stop recording failed rc=%d\n", __func__, rc);
223    }
224
225    return rc;
226}
227
228int mm_app_start_live_snapshot(mm_camera_test_obj_t *test_obj)
229{
230    int rc = MM_CAMERA_OK;
231    mm_camera_channel_t *s_ch = NULL;
232
233    s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
234
235    rc = mm_app_start_channel(test_obj, s_ch);
236    if (MM_CAMERA_OK != rc) {
237        CDBG_ERROR("%s:start recording failed rc=%d\n", __func__, rc);
238    }
239
240    return rc;
241}
242
243int mm_app_stop_live_snapshot(mm_camera_test_obj_t *test_obj)
244{
245    int rc = MM_CAMERA_OK;
246    mm_camera_channel_t *s_ch = NULL;
247
248    s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
249
250    rc = mm_app_stop_channel(test_obj, s_ch);
251    if (MM_CAMERA_OK != rc) {
252        CDBG_ERROR("%s:stop recording failed rc=%d\n", __func__, rc);
253    }
254
255    return rc;
256}
257