1 /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #include "mm_qcamera_dbg.h" 31 #include "mm_qcamera_app.h" 32 33 /* This callback is received once the complete JPEG encoding is done */ 34 static void jpeg_encode_cb(jpeg_job_status_t status, 35 uint32_t client_hdl, 36 uint32_t jobId, 37 mm_jpeg_output_t *p_buf, 38 void *userData) 39 { 40 int i = 0; 41 mm_camera_test_obj_t *pme = NULL; 42 CDBG("%s: BEGIN\n", __func__); 43 44 pme = (mm_camera_test_obj_t *)userData; 45 if (pme->jpeg_hdl != client_hdl || 46 jobId != pme->current_job_id || 47 !pme->current_job_frames) { 48 CDBG_ERROR("%s: NULL current job frames or not matching job ID (%d, %d)", 49 __func__, jobId, pme->current_job_id); 50 return; 51 } 52 53 /* dump jpeg img */ 54 CDBG_ERROR("%s: job %d, status=%d", __func__, jobId, status); 55 if (status == JPEG_JOB_STATUS_DONE && p_buf != NULL) { 56 mm_app_dump_jpeg_frame(p_buf->buf_vaddr, p_buf->buf_filled_len, "jpeg", "jpg", jobId); 57 } 58 59 /* buf done current encoding frames */ 60 pme->current_job_id = 0; 61 for (i = 0; i < pme->current_job_frames->num_bufs; i++) { 62 if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->current_job_frames->camera_handle, 63 pme->current_job_frames->ch_id, 64 pme->current_job_frames->bufs[i])) { 65 CDBG_ERROR("%s: Failed in Qbuf\n", __func__); 66 } 67 mm_app_cache_ops((mm_camera_app_meminfo_t *) pme->current_job_frames->bufs[i]->mem_info, 68 ION_IOC_INV_CACHES); 69 } 70 71 free(pme->jpeg_buf.buf.buffer); 72 free(pme->current_job_frames); 73 pme->current_job_frames = NULL; 74 75 /* signal snapshot is done */ 76 mm_camera_app_done(); 77 } 78 79 int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame, 80 mm_camera_stream_t *m_stream) 81 { 82 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer); 83 84 int rc = -MM_CAMERA_E_GENERAL; 85 mm_jpeg_job_t job; 86 87 /* remember current frames being encoded */ 88 test_obj->current_job_frames = 89 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 90 if (!test_obj->current_job_frames) { 91 CDBG_ERROR("%s: No memory for current_job_frames", __func__); 92 return rc; 93 } 94 *(test_obj->current_job_frames) = *recvd_frame; 95 96 memset(&job, 0, sizeof(job)); 97 job.job_type = JPEG_JOB_TYPE_ENCODE; 98 job.encode_job.session_id = test_obj->current_jpeg_sess_id; 99 100 // TODO: Rotation should be set according to 101 // sensor&device orientation 102 job.encode_job.rotation = 0; 103 if (cam_cap->position == CAM_POSITION_BACK) { 104 job.encode_job.rotation = 270; 105 } 106 107 /* fill in main src img encode param */ 108 job.encode_job.main_dim.src_dim = m_stream->s_config.stream_info->dim; 109 job.encode_job.main_dim.dst_dim = m_stream->s_config.stream_info->dim; 110 job.encode_job.src_index = 0; 111 112 job.encode_job.thumb_dim.src_dim = m_stream->s_config.stream_info->dim; 113 job.encode_job.thumb_dim.dst_dim.width = DEFAULT_PREVIEW_WIDTH; 114 job.encode_job.thumb_dim.dst_dim.height = DEFAULT_PREVIEW_HEIGHT; 115 116 /* fill in sink img param */ 117 job.encode_job.dst_index = 0; 118 119 if (test_obj->metadata != NULL) { 120 job.encode_job.p_metadata = test_obj->metadata; 121 } else { 122 CDBG_ERROR("%s: Metadata null, not set for jpeg encoding", __func__); 123 } 124 125 rc = test_obj->jpeg_ops.start_job(&job, &test_obj->current_job_id); 126 if ( 0 != rc ) { 127 free(test_obj->current_job_frames); 128 test_obj->current_job_frames = NULL; 129 } 130 131 return rc; 132 } 133 134 int createEncodingSession(mm_camera_test_obj_t *test_obj, 135 mm_camera_stream_t *m_stream, 136 mm_camera_buf_def_t *m_frame) 137 { 138 mm_jpeg_encode_params_t encode_param; 139 140 memset(&encode_param, 0, sizeof(mm_jpeg_encode_params_t)); 141 encode_param.jpeg_cb = jpeg_encode_cb; 142 encode_param.userdata = (void*)test_obj; 143 encode_param.encode_thumbnail = 0; 144 encode_param.quality = 85; 145 encode_param.color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 146 encode_param.thumb_color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 147 148 /* fill in main src img encode param */ 149 encode_param.num_src_bufs = 1; 150 encode_param.src_main_buf[0].index = 0; 151 encode_param.src_main_buf[0].buf_size = m_frame->frame_len; 152 encode_param.src_main_buf[0].buf_vaddr = (uint8_t *)m_frame->buffer; 153 encode_param.src_main_buf[0].fd = m_frame->fd; 154 encode_param.src_main_buf[0].format = MM_JPEG_FMT_YUV; 155 encode_param.src_main_buf[0].offset = m_stream->offset; 156 157 /* fill in sink img param */ 158 encode_param.num_dst_bufs = 1; 159 encode_param.dest_buf[0].index = 0; 160 encode_param.dest_buf[0].buf_size = test_obj->jpeg_buf.buf.frame_len; 161 encode_param.dest_buf[0].buf_vaddr = (uint8_t *)test_obj->jpeg_buf.buf.buffer; 162 encode_param.dest_buf[0].fd = test_obj->jpeg_buf.buf.fd; 163 encode_param.dest_buf[0].format = MM_JPEG_FMT_YUV; 164 165 /* main dimension */ 166 encode_param.main_dim.src_dim = m_stream->s_config.stream_info->dim; 167 encode_param.main_dim.dst_dim = m_stream->s_config.stream_info->dim; 168 169 return test_obj->jpeg_ops.create_session(test_obj->jpeg_hdl, 170 &encode_param, 171 &test_obj->current_jpeg_sess_id); 172 } 173 174 /** mm_app_snapshot_metadata_notify_cb 175 * @bufs: Pointer to super buffer 176 * @user_data: Pointer to user data 177 * 178 * 179 **/ 180 static void mm_app_snapshot_metadata_notify_cb(mm_camera_super_buf_t *bufs, 181 void *user_data) 182 { 183 int i = 0; 184 mm_camera_channel_t *channel = NULL; 185 mm_camera_stream_t *p_stream = NULL; 186 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 187 mm_camera_buf_def_t *frame = bufs->bufs[0]; 188 metadata_buffer_t *pMetadata; 189 cam_auto_focus_data_t *focus_data; 190 191 if (NULL == bufs || NULL == user_data) { 192 CDBG_ERROR("%s: bufs or user_data are not valid ", __func__); 193 return; 194 } 195 196 /* find channel */ 197 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) { 198 if (pme->channels[i].ch_id == bufs->ch_id) { 199 channel = &pme->channels[i]; 200 break; 201 } 202 } 203 /* find meta stream */ 204 for (i = 0; i < channel->num_streams; i++) { 205 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) { 206 p_stream = &channel->streams[i]; 207 break; 208 } 209 } 210 /* find meta frame */ 211 for (i = 0; i < bufs->num_bufs; i++) { 212 if (bufs->bufs[i]->stream_id == p_stream->s_id) { 213 frame = bufs->bufs[i]; 214 break; 215 } 216 } 217 218 if (NULL == p_stream) { 219 CDBG_ERROR("%s: cannot find metadata stream", __func__); 220 return; 221 } 222 if (!pme->metadata) { 223 /* The app will free the metadata, we don't need to bother here */ 224 pme->metadata = malloc(sizeof(metadata_buffer_t)); 225 } 226 memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t)); 227 228 pMetadata = (metadata_buffer_t *)frame->buffer; 229 230 if (IS_META_AVAILABLE(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata)) { 231 focus_data = (cam_auto_focus_data_t *) 232 POINTER_OF_META(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata); 233 if (focus_data->focus_state == CAM_AF_FOCUSED) { 234 CDBG_ERROR("%s: AutoFocus Done Call Back Received\n",__func__); 235 mm_camera_app_done(); 236 } else if (focus_data->focus_state == CAM_AF_NOT_FOCUSED) { 237 CDBG_ERROR("%s: AutoFocus failed\n",__func__); 238 mm_camera_app_done(); 239 } 240 } 241 242 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 243 bufs->ch_id, 244 frame)) { 245 CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__); 246 } 247 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info, 248 ION_IOC_INV_CACHES); 249 } 250 251 static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs, 252 void *user_data) 253 { 254 255 int rc; 256 int i = 0; 257 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 258 mm_camera_channel_t *channel = NULL; 259 mm_camera_stream_t *m_stream = NULL; 260 mm_camera_buf_def_t *m_frame = NULL; 261 262 CDBG("%s: BEGIN\n", __func__); 263 264 /* find channel */ 265 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) { 266 if (pme->channels[i].ch_id == bufs->ch_id) { 267 channel = &pme->channels[i]; 268 break; 269 } 270 } 271 if (NULL == channel) { 272 CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id); 273 rc = -1; 274 goto EXIT; 275 } 276 277 /* find snapshot stream */ 278 for (i = 0; i < channel->num_streams; i++) { 279 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) { 280 m_stream = &channel->streams[i]; 281 break; 282 } 283 } 284 if (NULL == m_stream) { 285 CDBG_ERROR("%s: cannot find snapshot stream", __func__); 286 rc = -1; 287 goto EXIT; 288 } 289 290 /* find snapshot frame */ 291 for (i = 0; i < bufs->num_bufs; i++) { 292 if (bufs->bufs[i]->stream_id == m_stream->s_id) { 293 m_frame = bufs->bufs[i]; 294 break; 295 } 296 } 297 if (NULL == m_frame) { 298 CDBG_ERROR("%s: main frame is NULL", __func__); 299 rc = -1; 300 goto EXIT; 301 } 302 303 mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx); 304 305 EXIT: 306 for (i=0; i<bufs->num_bufs; i++) { 307 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 308 bufs->ch_id, 309 bufs->bufs[i])) { 310 CDBG_ERROR("%s: Failed in Qbuf\n", __func__); 311 } 312 } 313 314 mm_camera_app_done(); 315 316 CDBG("%s: END\n", __func__); 317 } 318 319 static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs, 320 void *user_data) 321 { 322 323 int rc = 0; 324 int i = 0; 325 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 326 mm_camera_channel_t *channel = NULL; 327 mm_camera_stream_t *p_stream = NULL; 328 mm_camera_stream_t *m_stream = NULL; 329 mm_camera_buf_def_t *p_frame = NULL; 330 mm_camera_buf_def_t *m_frame = NULL; 331 332 CDBG("%s: BEGIN\n", __func__); 333 334 /* find channel */ 335 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) { 336 if (pme->channels[i].ch_id == bufs->ch_id) { 337 channel = &pme->channels[i]; 338 break; 339 } 340 } 341 if (NULL == channel) { 342 CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id); 343 rc = -1; 344 goto error; 345 } 346 347 /* find snapshot stream */ 348 for (i = 0; i < channel->num_streams; i++) { 349 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) { 350 m_stream = &channel->streams[i]; 351 break; 352 } 353 } 354 if (NULL == m_stream) { 355 CDBG_ERROR("%s: cannot find snapshot stream", __func__); 356 rc = -1; 357 goto error; 358 } 359 360 /* find snapshot frame */ 361 for (i = 0; i < bufs->num_bufs; i++) { 362 if (bufs->bufs[i]->stream_id == m_stream->s_id) { 363 m_frame = bufs->bufs[i]; 364 break; 365 } 366 } 367 if (NULL == m_frame) { 368 CDBG_ERROR("%s: main frame is NULL", __func__); 369 rc = -1; 370 goto error; 371 } 372 373 mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx); 374 375 /* find postview stream */ 376 for (i = 0; i < channel->num_streams; i++) { 377 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) { 378 p_stream = &channel->streams[i]; 379 break; 380 } 381 } 382 if (NULL != p_stream) { 383 /* find preview frame */ 384 for (i = 0; i < bufs->num_bufs; i++) { 385 if (bufs->bufs[i]->stream_id == p_stream->s_id) { 386 p_frame = bufs->bufs[i]; 387 break; 388 } 389 } 390 if (NULL != p_frame) { 391 mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx); 392 } 393 } 394 395 mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info, 396 ION_IOC_CLEAN_INV_CACHES); 397 398 pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len); 399 if ( NULL == pme->jpeg_buf.buf.buffer ) { 400 CDBG_ERROR("%s: error allocating jpeg output buffer", __func__); 401 goto error; 402 } 403 404 pme->jpeg_buf.buf.frame_len = m_frame->frame_len; 405 /* create a new jpeg encoding session */ 406 rc = createEncodingSession(pme, m_stream, m_frame); 407 if (0 != rc) { 408 CDBG_ERROR("%s: error creating jpeg session", __func__); 409 free(pme->jpeg_buf.buf.buffer); 410 goto error; 411 } 412 413 /* start jpeg encoding job */ 414 rc = encodeData(pme, bufs, m_stream); 415 if (0 != rc) { 416 CDBG_ERROR("%s: error creating jpeg session", __func__); 417 free(pme->jpeg_buf.buf.buffer); 418 goto error; 419 } 420 421 error: 422 /* buf done rcvd frames in error case */ 423 if ( 0 != rc ) { 424 for (i=0; i<bufs->num_bufs; i++) { 425 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 426 bufs->ch_id, 427 bufs->bufs[i])) { 428 CDBG_ERROR("%s: Failed in Qbuf\n", __func__); 429 } 430 mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info, 431 ION_IOC_INV_CACHES); 432 } 433 } 434 435 CDBG("%s: END\n", __func__); 436 } 437 438 mm_camera_channel_t * mm_app_add_snapshot_channel(mm_camera_test_obj_t *test_obj) 439 { 440 mm_camera_channel_t *channel = NULL; 441 mm_camera_stream_t *stream = NULL; 442 443 channel = mm_app_add_channel(test_obj, 444 MM_CHANNEL_TYPE_SNAPSHOT, 445 NULL, 446 NULL, 447 NULL); 448 if (NULL == channel) { 449 CDBG_ERROR("%s: add channel failed", __func__); 450 return NULL; 451 } 452 453 stream = mm_app_add_snapshot_stream(test_obj, 454 channel, 455 mm_app_snapshot_notify_cb, 456 (void *)test_obj, 457 1, 458 1); 459 if (NULL == stream) { 460 CDBG_ERROR("%s: add snapshot stream failed\n", __func__); 461 mm_app_del_channel(test_obj, channel); 462 return NULL; 463 } 464 465 return channel; 466 } 467 468 mm_camera_stream_t * mm_app_add_postview_stream(mm_camera_test_obj_t *test_obj, 469 mm_camera_channel_t *channel, 470 mm_camera_buf_notify_t stream_cb, 471 void *userdata, 472 uint8_t num_bufs, 473 uint8_t num_burst) 474 { 475 int rc = MM_CAMERA_OK; 476 mm_camera_stream_t *stream = NULL; 477 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer); 478 479 stream = mm_app_add_stream(test_obj, channel); 480 if (NULL == stream) { 481 CDBG_ERROR("%s: add stream failed\n", __func__); 482 return NULL; 483 } 484 485 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf; 486 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf; 487 stream->s_config.mem_vtbl.clean_invalidate_buf = 488 mm_app_stream_clean_invalidate_buf; 489 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf; 490 stream->s_config.mem_vtbl.user_data = (void *)stream; 491 stream->s_config.stream_cb = stream_cb; 492 stream->s_config.userdata = userdata; 493 stream->num_of_bufs = num_bufs; 494 495 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer; 496 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t)); 497 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW; 498 if (num_burst == 0) { 499 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 500 } else { 501 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST; 502 stream->s_config.stream_info->num_of_burst = num_burst; 503 } 504 stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT; 505 stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH; 506 stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT; 507 stream->s_config.padding_info = cam_cap->padding_info; 508 509 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config); 510 if (MM_CAMERA_OK != rc) { 511 CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc); 512 return NULL; 513 } 514 515 return stream; 516 } 517 518 int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots) 519 { 520 int32_t rc = MM_CAMERA_OK; 521 mm_camera_channel_t *channel = NULL; 522 mm_camera_stream_t *s_main = NULL; 523 mm_camera_channel_attr_t attr; 524 525 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 526 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 527 attr.max_unmatched_frames = 3; 528 channel = mm_app_add_channel(test_obj, 529 MM_CHANNEL_TYPE_CAPTURE, 530 &attr, 531 mm_app_snapshot_notify_cb_raw, 532 test_obj); 533 if (NULL == channel) { 534 CDBG_ERROR("%s: add channel failed", __func__); 535 return -MM_CAMERA_E_GENERAL; 536 } 537 538 test_obj->buffer_format = DEFAULT_RAW_FORMAT; 539 s_main = mm_app_add_raw_stream(test_obj, 540 channel, 541 mm_app_snapshot_notify_cb_raw, 542 test_obj, 543 num_snapshots, 544 num_snapshots); 545 if (NULL == s_main) { 546 CDBG_ERROR("%s: add main snapshot stream failed\n", __func__); 547 mm_app_del_channel(test_obj, channel); 548 return rc; 549 } 550 551 rc = mm_app_start_channel(test_obj, channel); 552 if (MM_CAMERA_OK != rc) { 553 CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc); 554 mm_app_del_stream(test_obj, channel, s_main); 555 mm_app_del_channel(test_obj, channel); 556 return rc; 557 } 558 559 return rc; 560 } 561 562 int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj) 563 { 564 int rc = MM_CAMERA_OK; 565 mm_camera_channel_t *ch = NULL; 566 int i; 567 568 ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE); 569 570 rc = mm_app_stop_channel(test_obj, ch); 571 if (MM_CAMERA_OK != rc) { 572 CDBG_ERROR("%s:stop recording failed rc=%d\n", __func__, rc); 573 } 574 575 for ( i = 0 ; i < ch->num_streams ; i++ ) { 576 mm_app_del_stream(test_obj, ch, &ch->streams[i]); 577 } 578 579 mm_app_del_channel(test_obj, ch); 580 581 return rc; 582 } 583 584 int mm_app_start_capture(mm_camera_test_obj_t *test_obj, 585 uint8_t num_snapshots) 586 { 587 int32_t rc = MM_CAMERA_OK; 588 mm_camera_channel_t *channel = NULL; 589 mm_camera_stream_t *s_main = NULL; 590 mm_camera_stream_t *s_metadata = NULL; 591 mm_camera_channel_attr_t attr; 592 593 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 594 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 595 attr.max_unmatched_frames = 3; 596 channel = mm_app_add_channel(test_obj, 597 MM_CHANNEL_TYPE_CAPTURE, 598 &attr, 599 mm_app_snapshot_notify_cb, 600 test_obj); 601 if (NULL == channel) { 602 CDBG_ERROR("%s: add channel failed", __func__); 603 return -MM_CAMERA_E_GENERAL; 604 } 605 s_metadata = mm_app_add_metadata_stream(test_obj, 606 channel, 607 mm_app_snapshot_metadata_notify_cb, 608 (void *)test_obj, 609 CAPTURE_BUF_NUM); 610 if (NULL == s_metadata) { 611 CDBG_ERROR("%s: add metadata stream failed\n", __func__); 612 mm_app_del_channel(test_obj, channel); 613 return -MM_CAMERA_E_GENERAL; 614 } 615 616 s_main = mm_app_add_snapshot_stream(test_obj, 617 channel, 618 NULL, 619 NULL, 620 CAPTURE_BUF_NUM, 621 num_snapshots); 622 if (NULL == s_main) { 623 CDBG_ERROR("%s: add main snapshot stream failed\n", __func__); 624 mm_app_del_channel(test_obj, channel); 625 return rc; 626 } 627 628 rc = mm_app_start_channel(test_obj, channel); 629 if (MM_CAMERA_OK != rc) { 630 CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc); 631 mm_app_del_stream(test_obj, channel, s_main); 632 mm_app_del_stream(test_obj, channel, s_metadata); 633 mm_app_del_channel(test_obj, channel); 634 return rc; 635 } 636 637 return rc; 638 } 639 640 int mm_app_stop_capture(mm_camera_test_obj_t *test_obj) 641 { 642 int rc = MM_CAMERA_OK; 643 mm_camera_channel_t *ch = NULL; 644 645 ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE); 646 647 rc = mm_app_stop_and_del_channel(test_obj, ch); 648 if (MM_CAMERA_OK != rc) { 649 CDBG_ERROR("%s:stop capture channel failed rc=%d\n", __func__, rc); 650 } 651 652 return rc; 653 } 654 655 int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode) 656 { 657 CDBG_HIGH("\nEnter %s!!\n",__func__); 658 int rc = MM_CAMERA_OK; 659 int num_snapshot = 1; 660 int num_rcvd_snapshot = 0; 661 662 if (is_burst_mode) 663 num_snapshot = 6; 664 665 //stop preview before starting capture. 666 rc = mm_app_stop_preview(test_obj); 667 if (rc != MM_CAMERA_OK) { 668 CDBG_ERROR("%s: stop preview failed before capture!!, err=%d\n",__func__, rc); 669 return rc; 670 } 671 672 rc = mm_app_start_capture(test_obj, num_snapshot); 673 if (rc != MM_CAMERA_OK) { 674 CDBG_ERROR("%s: mm_app_start_capture(), err=%d\n", __func__,rc); 675 return rc; 676 } 677 while (num_rcvd_snapshot < num_snapshot) { 678 CDBG_HIGH("\nWaiting mm_camera_app_wait !!\n"); 679 mm_camera_app_wait(); 680 num_rcvd_snapshot++; 681 } 682 rc = mm_app_stop_capture(test_obj); 683 if (rc != MM_CAMERA_OK) { 684 CDBG_ERROR("%s: mm_app_stop_capture(), err=%d\n",__func__, rc); 685 return rc; 686 } 687 //start preview after capture. 688 rc = mm_app_start_preview(test_obj); 689 if (rc != MM_CAMERA_OK) { 690 CDBG_ERROR("%s: start preview failed after capture!!, err=%d\n",__func__,rc); 691 } 692 return rc; 693 } 694