1 /*
2 Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
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
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "mm_qcamera_dbg.h"
31 #include "mm_qcamera_app.h"
32
mm_app_preview_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)33 static 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
mm_app_zsl_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)56 static 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
mm_app_add_preview_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_buf_notify_t stream_cb,void * userdata,uint8_t num_bufs)149 mm_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
mm_app_add_snapshot_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_buf_notify_t stream_cb,void * userdata,uint8_t num_bufs,uint8_t num_burst)193 mm_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
mm_app_add_preview_channel(mm_camera_test_obj_t * test_obj)243 mm_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
mm_app_stop_and_del_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)272 int 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
mm_app_start_preview(mm_camera_test_obj_t * test_obj)300 int 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
mm_app_stop_preview(mm_camera_test_obj_t * test_obj)327 int 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
mm_app_start_preview_zsl(mm_camera_test_obj_t * test_obj)342 int 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
mm_app_stop_preview_zsl(mm_camera_test_obj_t * test_obj)402 int 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