1/*
2Copyright (c) 2012-2014, 2016, 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// Camera dependencies
31#include "mm_qcamera_app.h"
32#include "mm_qcamera_dbg.h"
33
34static void mm_app_video_notify_cb(mm_camera_super_buf_t *bufs,
35                                   void *user_data)
36{
37    char file_name[64];
38    mm_camera_buf_def_t *frame = bufs->bufs[0];
39    mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
40
41    LOGD("BEGIN - length=%zu, frame idx = %d\n",
42          frame->frame_len, frame->frame_idx);
43    snprintf(file_name, sizeof(file_name), "V_C%d", pme->cam->camera_handle);
44    mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
45
46    if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
47                                            bufs->ch_id,
48                                            frame)) {
49        LOGE("Failed in Preview Qbuf\n");
50    }
51    mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
52                     ION_IOC_INV_CACHES);
53
54    LOGD("END\n");
55}
56
57mm_camera_stream_t * mm_app_add_video_stream(mm_camera_test_obj_t *test_obj,
58                                             mm_camera_channel_t *channel,
59                                             mm_camera_buf_notify_t stream_cb,
60                                             void *userdata,
61                                             uint8_t num_bufs)
62{
63    int rc = MM_CAMERA_OK;
64    mm_camera_stream_t *stream = NULL;
65    cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
66
67    stream = mm_app_add_stream(test_obj, channel);
68    if (NULL == stream) {
69        LOGE("add stream failed\n");
70        return NULL;
71    }
72
73    stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
74    stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
75    stream->s_config.mem_vtbl.clean_invalidate_buf =
76      mm_app_stream_clean_invalidate_buf;
77    stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
78    stream->s_config.mem_vtbl.user_data = (void *)stream;
79    stream->s_config.stream_cb = stream_cb;
80    stream->s_config.stream_cb_sync = NULL;
81    stream->s_config.userdata = userdata;
82    stream->num_of_bufs = num_bufs;
83
84    stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
85    memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
86    stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_VIDEO;
87    stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
88    stream->s_config.stream_info->fmt = DEFAULT_VIDEO_FORMAT;
89    stream->s_config.stream_info->dim.width = DEFAULT_VIDEO_WIDTH;
90    stream->s_config.stream_info->dim.height = DEFAULT_VIDEO_HEIGHT;
91    stream->s_config.padding_info = cam_cap->padding_info;
92
93    rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
94    if (MM_CAMERA_OK != rc) {
95        LOGE("config preview stream err=%d\n",  rc);
96        return NULL;
97    }
98
99    return stream;
100}
101
102mm_camera_channel_t * mm_app_add_video_channel(mm_camera_test_obj_t *test_obj)
103{
104    mm_camera_channel_t *channel = NULL;
105    mm_camera_stream_t *stream = NULL;
106
107    channel = mm_app_add_channel(test_obj,
108                                 MM_CHANNEL_TYPE_VIDEO,
109                                 NULL,
110                                 NULL,
111                                 NULL);
112    if (NULL == channel) {
113        LOGE("add channel failed");
114        return NULL;
115    }
116
117    stream = mm_app_add_video_stream(test_obj,
118                                     channel,
119                                     mm_app_video_notify_cb,
120                                     (void *)test_obj,
121                                     1);
122    if (NULL == stream) {
123        LOGE("add video stream failed\n");
124        mm_app_del_channel(test_obj, channel);
125        return NULL;
126    }
127
128    return channel;
129}
130
131int mm_app_start_record_preview(mm_camera_test_obj_t *test_obj)
132{
133    int rc = MM_CAMERA_OK;
134    mm_camera_channel_t *p_ch = NULL;
135    mm_camera_channel_t *v_ch = NULL;
136    mm_camera_channel_t *s_ch = NULL;
137
138    p_ch = mm_app_add_preview_channel(test_obj);
139    if (NULL == p_ch) {
140        LOGE("add preview channel failed");
141        return -MM_CAMERA_E_GENERAL;
142    }
143
144    v_ch = mm_app_add_video_channel(test_obj);
145    if (NULL == v_ch) {
146        LOGE("add video channel failed");
147        mm_app_del_channel(test_obj, p_ch);
148        return -MM_CAMERA_E_GENERAL;
149    }
150
151    s_ch = mm_app_add_snapshot_channel(test_obj);
152    if (NULL == s_ch) {
153        LOGE("add snapshot channel failed");
154        mm_app_del_channel(test_obj, p_ch);
155        mm_app_del_channel(test_obj, v_ch);
156        return -MM_CAMERA_E_GENERAL;
157    }
158
159    rc = mm_app_start_channel(test_obj, p_ch);
160    if (MM_CAMERA_OK != rc) {
161        LOGE("start preview failed rc=%d\n", rc);
162        mm_app_del_channel(test_obj, p_ch);
163        mm_app_del_channel(test_obj, v_ch);
164        mm_app_del_channel(test_obj, s_ch);
165        return rc;
166    }
167
168    return rc;
169}
170
171int mm_app_stop_record_preview(mm_camera_test_obj_t *test_obj)
172{
173    int rc = MM_CAMERA_OK;
174    mm_camera_channel_t *p_ch = NULL;
175    mm_camera_channel_t *v_ch = NULL;
176    mm_camera_channel_t *s_ch = NULL;
177
178    p_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
179    v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
180    s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
181
182    rc = mm_app_stop_and_del_channel(test_obj, p_ch);
183    if (MM_CAMERA_OK != rc) {
184        LOGE("Stop Preview failed rc=%d\n", rc);
185    }
186
187    rc = mm_app_stop_and_del_channel(test_obj, v_ch);
188    if (MM_CAMERA_OK != rc) {
189        LOGE("Stop Preview failed rc=%d\n", rc);
190    }
191
192    rc = mm_app_stop_and_del_channel(test_obj, s_ch);
193    if (MM_CAMERA_OK != rc) {
194        LOGE("Stop Preview failed rc=%d\n", rc);
195    }
196
197    return rc;
198}
199
200int mm_app_start_record(mm_camera_test_obj_t *test_obj)
201{
202    int rc = MM_CAMERA_OK;
203    mm_camera_channel_t *v_ch = NULL;
204
205    v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
206
207    rc = mm_app_start_channel(test_obj, v_ch);
208    if (MM_CAMERA_OK != rc) {
209        LOGE("start recording failed rc=%d\n", rc);
210    }
211
212    return rc;
213}
214
215int mm_app_stop_record(mm_camera_test_obj_t *test_obj)
216{
217    int rc = MM_CAMERA_OK;
218    mm_camera_channel_t *v_ch = NULL;
219
220    v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
221
222    rc = mm_app_stop_channel(test_obj, v_ch);
223    if (MM_CAMERA_OK != rc) {
224        LOGE("stop recording failed rc=%d\n", rc);
225    }
226
227    return rc;
228}
229
230int mm_app_start_live_snapshot(mm_camera_test_obj_t *test_obj)
231{
232    int rc = MM_CAMERA_OK;
233    mm_camera_channel_t *s_ch = NULL;
234
235    s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
236
237    rc = mm_app_start_channel(test_obj, s_ch);
238    if (MM_CAMERA_OK != rc) {
239        LOGE("start recording failed rc=%d\n", rc);
240    }
241
242    return rc;
243}
244
245int mm_app_stop_live_snapshot(mm_camera_test_obj_t *test_obj)
246{
247    int rc = MM_CAMERA_OK;
248    mm_camera_channel_t *s_ch = NULL;
249
250    s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
251
252    rc = mm_app_stop_channel(test_obj, s_ch);
253    if (MM_CAMERA_OK != rc) {
254        LOGE("stop recording failed rc=%d\n", rc);
255    }
256
257    return rc;
258}
259