1 /* Copyright (c) 2012-2015, 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 uint32_t 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 uint32_t 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; 188 metadata_buffer_t *pMetadata; 189 190 if (NULL == bufs || NULL == user_data) { 191 CDBG_ERROR("%s: bufs or user_data are not valid ", __func__); 192 return; 193 } 194 frame = bufs->bufs[0]; 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 204 if (NULL == channel) { 205 CDBG_ERROR("%s: Channel object is null", __func__); 206 return; 207 } 208 209 /* find meta stream */ 210 for (i = 0; i < channel->num_streams; i++) { 211 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) { 212 p_stream = &channel->streams[i]; 213 break; 214 } 215 } 216 217 if (NULL == p_stream) { 218 CDBG_ERROR("%s: cannot find metadata stream", __func__); 219 return; 220 } 221 222 /* find meta frame */ 223 for (i = 0; i < bufs->num_bufs; i++) { 224 if (bufs->bufs[i]->stream_id == p_stream->s_id) { 225 frame = bufs->bufs[i]; 226 break; 227 } 228 } 229 230 if (!pme->metadata) { 231 /* The app will free the metadata, we don't need to bother here */ 232 pme->metadata = malloc(sizeof(metadata_buffer_t)); 233 if (NULL == pme->metadata) { 234 CDBG_ERROR("%s: malloc failed", __func__); 235 return; 236 } 237 } 238 239 memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t)); 240 241 pMetadata = (metadata_buffer_t *)frame->buffer; 242 243 IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data, 244 CAM_INTF_META_AUTOFOCUS_DATA, pMetadata) { 245 if (focus_data->focus_state == CAM_AF_FOCUSED) { 246 CDBG_ERROR("%s: AutoFocus Done Call Back Received\n",__func__); 247 mm_camera_app_done(); 248 } else if (focus_data->focus_state == CAM_AF_NOT_FOCUSED) { 249 CDBG_ERROR("%s: AutoFocus failed\n",__func__); 250 mm_camera_app_done(); 251 } 252 } 253 254 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 255 bufs->ch_id, 256 frame)) { 257 CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__); 258 } 259 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info, 260 ION_IOC_INV_CACHES); 261 } 262 263 static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs, 264 void *user_data) 265 { 266 267 int rc; 268 uint32_t i = 0; 269 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 270 mm_camera_channel_t *channel = NULL; 271 mm_camera_stream_t *m_stream = NULL; 272 mm_camera_buf_def_t *m_frame = NULL; 273 274 CDBG("%s: BEGIN\n", __func__); 275 276 /* find channel */ 277 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) { 278 if (pme->channels[i].ch_id == bufs->ch_id) { 279 channel = &pme->channels[i]; 280 break; 281 } 282 } 283 if (NULL == channel) { 284 CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id); 285 rc = -1; 286 goto EXIT; 287 } 288 289 /* find snapshot stream */ 290 for (i = 0; i < channel->num_streams; i++) { 291 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) { 292 m_stream = &channel->streams[i]; 293 break; 294 } 295 } 296 if (NULL == m_stream) { 297 CDBG_ERROR("%s: cannot find snapshot stream", __func__); 298 rc = -1; 299 goto EXIT; 300 } 301 302 /* find snapshot frame */ 303 for (i = 0; i < bufs->num_bufs; i++) { 304 if (bufs->bufs[i]->stream_id == m_stream->s_id) { 305 m_frame = bufs->bufs[i]; 306 break; 307 } 308 } 309 if (NULL == m_frame) { 310 CDBG_ERROR("%s: main frame is NULL", __func__); 311 rc = -1; 312 goto EXIT; 313 } 314 315 mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx); 316 317 EXIT: 318 for (i=0; i<bufs->num_bufs; i++) { 319 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 320 bufs->ch_id, 321 bufs->bufs[i])) { 322 CDBG_ERROR("%s: Failed in Qbuf\n", __func__); 323 } 324 } 325 326 mm_camera_app_done(); 327 328 CDBG("%s: END\n", __func__); 329 } 330 331 static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs, 332 void *user_data) 333 { 334 335 int rc = 0; 336 uint32_t i = 0; 337 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 338 mm_camera_channel_t *channel = NULL; 339 mm_camera_stream_t *p_stream = NULL; 340 mm_camera_stream_t *m_stream = NULL; 341 mm_camera_buf_def_t *p_frame = NULL; 342 mm_camera_buf_def_t *m_frame = NULL; 343 344 CDBG("%s: BEGIN\n", __func__); 345 346 /* find channel */ 347 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) { 348 if (pme->channels[i].ch_id == bufs->ch_id) { 349 channel = &pme->channels[i]; 350 break; 351 } 352 } 353 if (NULL == channel) { 354 CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id); 355 rc = -1; 356 goto error; 357 } 358 359 /* find snapshot stream */ 360 for (i = 0; i < channel->num_streams; i++) { 361 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) { 362 m_stream = &channel->streams[i]; 363 break; 364 } 365 } 366 if (NULL == m_stream) { 367 CDBG_ERROR("%s: cannot find snapshot stream", __func__); 368 rc = -1; 369 goto error; 370 } 371 372 /* find snapshot frame */ 373 for (i = 0; i < bufs->num_bufs; i++) { 374 if (bufs->bufs[i]->stream_id == m_stream->s_id) { 375 m_frame = bufs->bufs[i]; 376 break; 377 } 378 } 379 if (NULL == m_frame) { 380 CDBG_ERROR("%s: main frame is NULL", __func__); 381 rc = -1; 382 goto error; 383 } 384 385 mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx); 386 387 /* find postview stream */ 388 for (i = 0; i < channel->num_streams; i++) { 389 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) { 390 p_stream = &channel->streams[i]; 391 break; 392 } 393 } 394 if (NULL != p_stream) { 395 /* find preview frame */ 396 for (i = 0; i < bufs->num_bufs; i++) { 397 if (bufs->bufs[i]->stream_id == p_stream->s_id) { 398 p_frame = bufs->bufs[i]; 399 break; 400 } 401 } 402 if (NULL != p_frame) { 403 mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx); 404 } 405 } 406 407 mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info, 408 ION_IOC_CLEAN_INV_CACHES); 409 410 pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len); 411 if ( NULL == pme->jpeg_buf.buf.buffer ) { 412 CDBG_ERROR("%s: error allocating jpeg output buffer", __func__); 413 goto error; 414 } 415 416 pme->jpeg_buf.buf.frame_len = m_frame->frame_len; 417 /* create a new jpeg encoding session */ 418 rc = createEncodingSession(pme, m_stream, m_frame); 419 if (0 != rc) { 420 CDBG_ERROR("%s: error creating jpeg session", __func__); 421 free(pme->jpeg_buf.buf.buffer); 422 goto error; 423 } 424 425 /* start jpeg encoding job */ 426 rc = encodeData(pme, bufs, m_stream); 427 if (0 != rc) { 428 CDBG_ERROR("%s: error creating jpeg session", __func__); 429 free(pme->jpeg_buf.buf.buffer); 430 goto error; 431 } 432 433 error: 434 /* buf done rcvd frames in error case */ 435 if ( 0 != rc ) { 436 for (i=0; i<bufs->num_bufs; i++) { 437 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 438 bufs->ch_id, 439 bufs->bufs[i])) { 440 CDBG_ERROR("%s: Failed in Qbuf\n", __func__); 441 } 442 mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info, 443 ION_IOC_INV_CACHES); 444 } 445 } 446 447 CDBG("%s: END\n", __func__); 448 } 449 450 mm_camera_channel_t * mm_app_add_snapshot_channel(mm_camera_test_obj_t *test_obj) 451 { 452 mm_camera_channel_t *channel = NULL; 453 mm_camera_stream_t *stream = NULL; 454 455 channel = mm_app_add_channel(test_obj, 456 MM_CHANNEL_TYPE_SNAPSHOT, 457 NULL, 458 NULL, 459 NULL); 460 if (NULL == channel) { 461 CDBG_ERROR("%s: add channel failed", __func__); 462 return NULL; 463 } 464 465 stream = mm_app_add_snapshot_stream(test_obj, 466 channel, 467 mm_app_snapshot_notify_cb, 468 (void *)test_obj, 469 1, 470 1); 471 if (NULL == stream) { 472 CDBG_ERROR("%s: add snapshot stream failed\n", __func__); 473 mm_app_del_channel(test_obj, channel); 474 return NULL; 475 } 476 477 return channel; 478 } 479 480 mm_camera_stream_t * mm_app_add_postview_stream(mm_camera_test_obj_t *test_obj, 481 mm_camera_channel_t *channel, 482 mm_camera_buf_notify_t stream_cb, 483 void *userdata, 484 uint8_t num_bufs, 485 uint8_t num_burst) 486 { 487 int rc = MM_CAMERA_OK; 488 mm_camera_stream_t *stream = NULL; 489 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer); 490 491 stream = mm_app_add_stream(test_obj, channel); 492 if (NULL == stream) { 493 CDBG_ERROR("%s: add stream failed\n", __func__); 494 return NULL; 495 } 496 497 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf; 498 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf; 499 stream->s_config.mem_vtbl.clean_invalidate_buf = 500 mm_app_stream_clean_invalidate_buf; 501 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf; 502 stream->s_config.mem_vtbl.user_data = (void *)stream; 503 stream->s_config.stream_cb = stream_cb; 504 stream->s_config.userdata = userdata; 505 stream->num_of_bufs = num_bufs; 506 507 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer; 508 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t)); 509 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW; 510 if (num_burst == 0) { 511 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 512 } else { 513 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST; 514 stream->s_config.stream_info->num_of_burst = num_burst; 515 } 516 stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT; 517 stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH; 518 stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT; 519 stream->s_config.padding_info = cam_cap->padding_info; 520 521 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config); 522 if (MM_CAMERA_OK != rc) { 523 CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc); 524 return NULL; 525 } 526 527 return stream; 528 } 529 530 int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots) 531 { 532 int32_t rc = MM_CAMERA_OK; 533 mm_camera_channel_t *channel = NULL; 534 mm_camera_stream_t *s_main = NULL; 535 mm_camera_channel_attr_t attr; 536 537 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 538 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 539 attr.max_unmatched_frames = 3; 540 channel = mm_app_add_channel(test_obj, 541 MM_CHANNEL_TYPE_CAPTURE, 542 &attr, 543 mm_app_snapshot_notify_cb_raw, 544 test_obj); 545 if (NULL == channel) { 546 CDBG_ERROR("%s: add channel failed", __func__); 547 return -MM_CAMERA_E_GENERAL; 548 } 549 550 test_obj->buffer_format = DEFAULT_RAW_FORMAT; 551 s_main = mm_app_add_raw_stream(test_obj, 552 channel, 553 mm_app_snapshot_notify_cb_raw, 554 test_obj, 555 num_snapshots, 556 num_snapshots); 557 if (NULL == s_main) { 558 CDBG_ERROR("%s: add main snapshot stream failed\n", __func__); 559 mm_app_del_channel(test_obj, channel); 560 return rc; 561 } 562 563 rc = mm_app_start_channel(test_obj, channel); 564 if (MM_CAMERA_OK != rc) { 565 CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc); 566 mm_app_del_stream(test_obj, channel, s_main); 567 mm_app_del_channel(test_obj, channel); 568 return rc; 569 } 570 571 return rc; 572 } 573 574 int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj) 575 { 576 int rc = MM_CAMERA_OK; 577 mm_camera_channel_t *ch = NULL; 578 int i; 579 580 ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE); 581 582 rc = mm_app_stop_channel(test_obj, ch); 583 if (MM_CAMERA_OK != rc) { 584 CDBG_ERROR("%s:stop recording failed rc=%d\n", __func__, rc); 585 } 586 587 for ( i = 0 ; i < ch->num_streams ; i++ ) { 588 mm_app_del_stream(test_obj, ch, &ch->streams[i]); 589 } 590 591 mm_app_del_channel(test_obj, ch); 592 593 return rc; 594 } 595 596 int mm_app_start_capture(mm_camera_test_obj_t *test_obj, 597 uint8_t num_snapshots) 598 { 599 int32_t rc = MM_CAMERA_OK; 600 mm_camera_channel_t *channel = NULL; 601 mm_camera_stream_t *s_main = NULL; 602 mm_camera_stream_t *s_metadata = NULL; 603 mm_camera_channel_attr_t attr; 604 605 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 606 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 607 attr.max_unmatched_frames = 3; 608 channel = mm_app_add_channel(test_obj, 609 MM_CHANNEL_TYPE_CAPTURE, 610 &attr, 611 mm_app_snapshot_notify_cb, 612 test_obj); 613 if (NULL == channel) { 614 CDBG_ERROR("%s: add channel failed", __func__); 615 return -MM_CAMERA_E_GENERAL; 616 } 617 s_metadata = mm_app_add_metadata_stream(test_obj, 618 channel, 619 mm_app_snapshot_metadata_notify_cb, 620 (void *)test_obj, 621 CAPTURE_BUF_NUM); 622 if (NULL == s_metadata) { 623 CDBG_ERROR("%s: add metadata stream failed\n", __func__); 624 mm_app_del_channel(test_obj, channel); 625 return -MM_CAMERA_E_GENERAL; 626 } 627 628 s_main = mm_app_add_snapshot_stream(test_obj, 629 channel, 630 NULL, 631 NULL, 632 CAPTURE_BUF_NUM, 633 num_snapshots); 634 if (NULL == s_main) { 635 CDBG_ERROR("%s: add main snapshot stream failed\n", __func__); 636 mm_app_del_channel(test_obj, channel); 637 return rc; 638 } 639 640 rc = mm_app_start_channel(test_obj, channel); 641 if (MM_CAMERA_OK != rc) { 642 CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc); 643 mm_app_del_stream(test_obj, channel, s_main); 644 mm_app_del_stream(test_obj, channel, s_metadata); 645 mm_app_del_channel(test_obj, channel); 646 return rc; 647 } 648 649 return rc; 650 } 651 652 int mm_app_stop_capture(mm_camera_test_obj_t *test_obj) 653 { 654 int rc = MM_CAMERA_OK; 655 mm_camera_channel_t *ch = NULL; 656 657 ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE); 658 659 rc = mm_app_stop_and_del_channel(test_obj, ch); 660 if (MM_CAMERA_OK != rc) { 661 CDBG_ERROR("%s:stop capture channel failed rc=%d\n", __func__, rc); 662 } 663 664 return rc; 665 } 666 667 int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode) 668 { 669 CDBG_HIGH("\nEnter %s!!\n",__func__); 670 int rc = MM_CAMERA_OK; 671 uint8_t num_snapshot = 1; 672 int num_rcvd_snapshot = 0; 673 674 if (is_burst_mode) 675 num_snapshot = 6; 676 677 //stop preview before starting capture. 678 rc = mm_app_stop_preview(test_obj); 679 if (rc != MM_CAMERA_OK) { 680 CDBG_ERROR("%s: stop preview failed before capture!!, err=%d\n",__func__, rc); 681 return rc; 682 } 683 684 rc = mm_app_start_capture(test_obj, num_snapshot); 685 if (rc != MM_CAMERA_OK) { 686 CDBG_ERROR("%s: mm_app_start_capture(), err=%d\n", __func__,rc); 687 return rc; 688 } 689 while (num_rcvd_snapshot < num_snapshot) { 690 CDBG_HIGH("\nWaiting mm_camera_app_wait !!\n"); 691 mm_camera_app_wait(); 692 num_rcvd_snapshot++; 693 } 694 rc = mm_app_stop_capture(test_obj); 695 if (rc != MM_CAMERA_OK) { 696 CDBG_ERROR("%s: mm_app_stop_capture(), err=%d\n",__func__, rc); 697 return rc; 698 } 699 //start preview after capture. 700 rc = mm_app_start_preview(test_obj); 701 if (rc != MM_CAMERA_OK) { 702 CDBG_ERROR("%s: start preview failed after capture!!, err=%d\n",__func__,rc); 703 } 704 return rc; 705 } 706