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