1/* Copyright (c) 2012-2016, 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// Camera dependencies 31#include "mm_qcamera_app.h" 32#include "mm_qcamera_dbg.h" 33 34/* This callback is received once the complete JPEG encoding is done */ 35static void jpeg_encode_cb(jpeg_job_status_t status, 36 uint32_t client_hdl, 37 uint32_t jobId, 38 mm_jpeg_output_t *p_buf, 39 void *userData) 40{ 41 uint32_t i = 0; 42 mm_camera_test_obj_t *pme = NULL; 43 LOGD(" BEGIN\n"); 44 45 pme = (mm_camera_test_obj_t *)userData; 46 if (pme->jpeg_hdl != client_hdl || 47 jobId != pme->current_job_id || 48 !pme->current_job_frames) { 49 LOGE(" NULL current job frames or not matching job ID (%d, %d)", 50 jobId, pme->current_job_id); 51 return; 52 } 53 54 /* dump jpeg img */ 55 LOGE(" job %d, status=%d", jobId, status); 56 if (status == JPEG_JOB_STATUS_DONE && p_buf != NULL) { 57 mm_app_dump_jpeg_frame(p_buf->buf_vaddr, p_buf->buf_filled_len, "jpeg", "jpg", jobId); 58 } 59 60 /* buf done current encoding frames */ 61 pme->current_job_id = 0; 62 for (i = 0; i < pme->current_job_frames->num_bufs; i++) { 63 if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->current_job_frames->camera_handle, 64 pme->current_job_frames->ch_id, 65 pme->current_job_frames->bufs[i])) { 66 LOGE(" Failed in Qbuf\n"); 67 } 68 mm_app_cache_ops((mm_camera_app_meminfo_t *) pme->current_job_frames->bufs[i]->mem_info, 69 ION_IOC_INV_CACHES); 70 } 71 72 free(pme->jpeg_buf.buf.buffer); 73 free(pme->current_job_frames); 74 pme->current_job_frames = NULL; 75 76 /* signal snapshot is done */ 77 mm_camera_app_done(); 78} 79 80int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame, 81 mm_camera_stream_t *m_stream) 82{ 83 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer); 84 85 int rc = -MM_CAMERA_E_GENERAL; 86 mm_jpeg_job_t job; 87 88 /* remember current frames being encoded */ 89 test_obj->current_job_frames = 90 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 91 if (!test_obj->current_job_frames) { 92 LOGE(" No memory for current_job_frames"); 93 return rc; 94 } 95 *(test_obj->current_job_frames) = *recvd_frame; 96 97 memset(&job, 0, sizeof(job)); 98 job.job_type = JPEG_JOB_TYPE_ENCODE; 99 job.encode_job.session_id = test_obj->current_jpeg_sess_id; 100 101 // TODO: Rotation should be set according to 102 // sensor&device orientation 103 job.encode_job.rotation = 0; 104 if (cam_cap->position == CAM_POSITION_BACK) { 105 job.encode_job.rotation = 270; 106 } 107 108 /* fill in main src img encode param */ 109 job.encode_job.main_dim.src_dim = m_stream->s_config.stream_info->dim; 110 job.encode_job.main_dim.dst_dim = m_stream->s_config.stream_info->dim; 111 job.encode_job.src_index = 0; 112 113 job.encode_job.thumb_dim.src_dim = m_stream->s_config.stream_info->dim; 114 job.encode_job.thumb_dim.dst_dim.width = DEFAULT_PREVIEW_WIDTH; 115 job.encode_job.thumb_dim.dst_dim.height = DEFAULT_PREVIEW_HEIGHT; 116 117 /* fill in sink img param */ 118 job.encode_job.dst_index = 0; 119 120 if (test_obj->metadata != NULL) { 121 job.encode_job.p_metadata = test_obj->metadata; 122 } else { 123 LOGE(" Metadata null, not set for jpeg encoding"); 124 } 125 126 rc = test_obj->jpeg_ops.start_job(&job, &test_obj->current_job_id); 127 if ( 0 != rc ) { 128 free(test_obj->current_job_frames); 129 test_obj->current_job_frames = NULL; 130 } 131 132 return rc; 133} 134 135int createEncodingSession(mm_camera_test_obj_t *test_obj, 136 mm_camera_stream_t *m_stream, 137 mm_camera_buf_def_t *m_frame) 138{ 139 mm_jpeg_encode_params_t encode_param; 140 141 memset(&encode_param, 0, sizeof(mm_jpeg_encode_params_t)); 142 encode_param.jpeg_cb = jpeg_encode_cb; 143 encode_param.userdata = (void*)test_obj; 144 encode_param.encode_thumbnail = 0; 145 encode_param.quality = 85; 146 encode_param.color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 147 encode_param.thumb_color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 148 149 /* fill in main src img encode param */ 150 encode_param.num_src_bufs = 1; 151 encode_param.src_main_buf[0].index = 0; 152 encode_param.src_main_buf[0].buf_size = m_frame->frame_len; 153 encode_param.src_main_buf[0].buf_vaddr = (uint8_t *)m_frame->buffer; 154 encode_param.src_main_buf[0].fd = m_frame->fd; 155 encode_param.src_main_buf[0].format = MM_JPEG_FMT_YUV; 156 encode_param.src_main_buf[0].offset = m_stream->offset; 157 158 /* fill in sink img param */ 159 encode_param.num_dst_bufs = 1; 160 encode_param.dest_buf[0].index = 0; 161 encode_param.dest_buf[0].buf_size = test_obj->jpeg_buf.buf.frame_len; 162 encode_param.dest_buf[0].buf_vaddr = (uint8_t *)test_obj->jpeg_buf.buf.buffer; 163 encode_param.dest_buf[0].fd = test_obj->jpeg_buf.buf.fd; 164 encode_param.dest_buf[0].format = MM_JPEG_FMT_YUV; 165 166 /* main dimension */ 167 encode_param.main_dim.src_dim = m_stream->s_config.stream_info->dim; 168 encode_param.main_dim.dst_dim = m_stream->s_config.stream_info->dim; 169 170 return test_obj->jpeg_ops.create_session(test_obj->jpeg_hdl, 171 &encode_param, 172 &test_obj->current_jpeg_sess_id); 173} 174 175/** mm_app_snapshot_metadata_notify_cb 176 * @bufs: Pointer to super buffer 177 * @user_data: Pointer to user data 178 * 179 * 180 **/ 181__unused 182static void mm_app_snapshot_metadata_notify_cb(mm_camera_super_buf_t *bufs, 183 void *user_data) 184{ 185 uint32_t i = 0; 186 mm_camera_channel_t *channel = NULL; 187 mm_camera_stream_t *p_stream = NULL; 188 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 189 mm_camera_buf_def_t *frame; 190 metadata_buffer_t *pMetadata; 191 192 if (NULL == bufs || NULL == user_data) { 193 LOGE(" bufs or user_data are not valid "); 194 return; 195 } 196 frame = bufs->bufs[0]; 197 198 /* find channel */ 199 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) { 200 if (pme->channels[i].ch_id == bufs->ch_id) { 201 channel = &pme->channels[i]; 202 break; 203 } 204 } 205 206 if (NULL == channel) { 207 LOGE(" Channel object is null"); 208 return; 209 } 210 211 /* find meta stream */ 212 for (i = 0; i < channel->num_streams; i++) { 213 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) { 214 p_stream = &channel->streams[i]; 215 break; 216 } 217 } 218 219 if (NULL == p_stream) { 220 LOGE(" cannot find metadata stream"); 221 return; 222 } 223 224 /* find meta frame */ 225 for (i = 0; i < bufs->num_bufs; i++) { 226 if (bufs->bufs[i]->stream_id == p_stream->s_id) { 227 frame = bufs->bufs[i]; 228 break; 229 } 230 } 231 232 if (!pme->metadata) { 233 /* The app will free the metadata, we don't need to bother here */ 234 pme->metadata = malloc(sizeof(metadata_buffer_t)); 235 if (NULL == pme->metadata) { 236 LOGE(" malloc failed"); 237 return; 238 } 239 } 240 241 memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t)); 242 243 pMetadata = (metadata_buffer_t *)frame->buffer; 244 245 IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data, 246 CAM_INTF_META_AUTOFOCUS_DATA, pMetadata) { 247 if (focus_data->focus_state == CAM_AF_STATE_FOCUSED_LOCKED) { 248 LOGE(" AutoFocus Done Call Back Received\n"); 249 mm_camera_app_done(); 250 } else if (focus_data->focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED) { 251 LOGE(" AutoFocus failed\n"); 252 mm_camera_app_done(); 253 } 254 } 255 256 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 257 bufs->ch_id, 258 frame)) { 259 LOGE(" Failed in Preview Qbuf\n"); 260 } 261 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info, 262 ION_IOC_INV_CACHES); 263} 264 265static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs, 266 void *user_data) 267{ 268 269 int rc; 270 uint32_t i = 0; 271 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 272 mm_camera_channel_t *channel = NULL; 273 mm_camera_stream_t *m_stream = NULL; 274 mm_camera_buf_def_t *m_frame = NULL; 275 276 LOGD(" BEGIN\n"); 277 278 /* find channel */ 279 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) { 280 if (pme->channels[i].ch_id == bufs->ch_id) { 281 channel = &pme->channels[i]; 282 break; 283 } 284 } 285 if (NULL == channel) { 286 LOGE(" Wrong channel id (%d)", bufs->ch_id); 287 rc = -1; 288 goto EXIT; 289 } 290 291 /* find snapshot stream */ 292 for (i = 0; i < channel->num_streams; i++) { 293 if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) { 294 m_stream = &channel->streams[i]; 295 break; 296 } 297 } 298 if (NULL == m_stream) { 299 LOGE(" cannot find snapshot stream"); 300 rc = -1; 301 goto EXIT; 302 } 303 304 /* find snapshot frame */ 305 for (i = 0; i < bufs->num_bufs; i++) { 306 if (bufs->bufs[i]->stream_id == m_stream->s_id) { 307 m_frame = bufs->bufs[i]; 308 break; 309 } 310 } 311 if (NULL == m_frame) { 312 LOGE(" main frame is NULL"); 313 rc = -1; 314 goto EXIT; 315 } 316 317 mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx); 318 319EXIT: 320 for (i=0; i<bufs->num_bufs; i++) { 321 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 322 bufs->ch_id, 323 bufs->bufs[i])) { 324 LOGE(" Failed in Qbuf\n"); 325 } 326 } 327 328 mm_camera_app_done(); 329 330 LOGD(" END\n"); 331} 332 333static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs, 334 void *user_data) 335{ 336 337 int rc = 0; 338 uint32_t i = 0; 339 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 340 mm_camera_channel_t *channel = NULL; 341 mm_camera_stream_t *p_stream = NULL; 342 mm_camera_stream_t *m_stream = NULL; 343 mm_camera_buf_def_t *p_frame = NULL; 344 mm_camera_buf_def_t *m_frame = NULL; 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 LOGE(" Wrong channel id (%d)", 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 LOGE(" cannot find snapshot stream"); 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 LOGE(" main frame is NULL"); 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 LOGE(" error allocating jpeg output buffer"); 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 LOGE(" error creating jpeg session"); 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 LOGE(" error creating jpeg session"); 429 free(pme->jpeg_buf.buf.buffer); 430 goto error; 431 } 432 433error: 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 LOGE(" Failed in Qbuf\n"); 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 LOGD(" END\n"); 448} 449 450mm_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 LOGE(" add channel failed"); 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 LOGE(" add snapshot stream failed\n"); 473 mm_app_del_channel(test_obj, channel); 474 return NULL; 475 } 476 477 return channel; 478} 479 480mm_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 LOGE(" add stream failed\n"); 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.stream_cb_sync = NULL; 505 stream->s_config.userdata = userdata; 506 stream->num_of_bufs = num_bufs; 507 508 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer; 509 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t)); 510 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW; 511 if (num_burst == 0) { 512 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 513 } else { 514 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST; 515 stream->s_config.stream_info->num_of_burst = num_burst; 516 } 517 stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT; 518 stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH; 519 stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT; 520 stream->s_config.padding_info = cam_cap->padding_info; 521 522 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config); 523 if (MM_CAMERA_OK != rc) { 524 LOGE("config postview stream err=%d\n", rc); 525 return NULL; 526 } 527 528 return stream; 529} 530 531int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots) 532{ 533 int32_t rc = MM_CAMERA_OK; 534 mm_camera_channel_t *channel = NULL; 535 mm_camera_stream_t *s_main = NULL; 536 mm_camera_channel_attr_t attr; 537 538 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 539 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 540 attr.max_unmatched_frames = 3; 541 channel = mm_app_add_channel(test_obj, 542 MM_CHANNEL_TYPE_CAPTURE, 543 &attr, 544 mm_app_snapshot_notify_cb_raw, 545 test_obj); 546 if (NULL == channel) { 547 LOGE(" add channel failed"); 548 return -MM_CAMERA_E_GENERAL; 549 } 550 551 test_obj->buffer_format = DEFAULT_RAW_FORMAT; 552 s_main = mm_app_add_raw_stream(test_obj, 553 channel, 554 mm_app_snapshot_notify_cb_raw, 555 test_obj, 556 num_snapshots, 557 num_snapshots); 558 if (NULL == s_main) { 559 LOGE(" add main snapshot stream failed\n"); 560 mm_app_del_channel(test_obj, channel); 561 return rc; 562 } 563 564 rc = mm_app_start_channel(test_obj, channel); 565 if (MM_CAMERA_OK != rc) { 566 LOGE("start zsl failed rc=%d\n", rc); 567 mm_app_del_stream(test_obj, channel, s_main); 568 mm_app_del_channel(test_obj, channel); 569 return rc; 570 } 571 572 return rc; 573} 574 575int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj) 576{ 577 int rc = MM_CAMERA_OK; 578 mm_camera_channel_t *ch = NULL; 579 int i; 580 cam_stream_size_info_t abc ; 581 memset (&abc , 0, sizeof (cam_stream_size_info_t)); 582 583 ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE); 584 585 rc = mm_app_stop_channel(test_obj, ch); 586 if (MM_CAMERA_OK != rc) { 587 LOGE("stop recording failed rc=%d\n", rc); 588 } 589 590 for ( i = 0 ; i < ch->num_streams ; i++ ) { 591 mm_app_del_stream(test_obj, ch, &ch->streams[i]); 592 } 593 rc = setmetainfoCommand(test_obj, &abc); 594 if (rc != MM_CAMERA_OK) { 595 LOGE(" meta info command failed\n"); 596 } 597 mm_app_del_channel(test_obj, ch); 598 599 return rc; 600} 601 602int mm_app_start_capture(mm_camera_test_obj_t *test_obj, 603 uint8_t num_snapshots) 604{ 605 int32_t rc = MM_CAMERA_OK; 606 mm_camera_channel_t *channel = NULL; 607 mm_camera_stream_t *s_main = NULL; 608 mm_camera_stream_t *s_post = NULL; 609 mm_camera_channel_attr_t attr; 610 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 611 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 612 attr.max_unmatched_frames = 3; 613 channel = mm_app_add_channel(test_obj, 614 MM_CHANNEL_TYPE_CAPTURE, 615 &attr, 616 mm_app_snapshot_notify_cb, 617 test_obj); 618 if (NULL == channel) { 619 LOGE(" add channel failed"); 620 return -MM_CAMERA_E_GENERAL; 621 } 622 623 s_main = mm_app_add_snapshot_stream(test_obj, 624 channel, 625 mm_app_snapshot_notify_cb, 626 (void *)test_obj, 627 CAPTURE_BUF_NUM, 628 num_snapshots); 629 if (NULL == s_main) { 630 LOGE(" add main snapshot stream failed\n"); 631 mm_app_del_channel(test_obj, channel); 632 return rc; 633 } 634 635 s_post = mm_app_add_postview_stream(test_obj, 636 channel, 637 NULL, 638 NULL, 639 CAPTURE_BUF_NUM, 640 num_snapshots); 641 if (NULL == s_main) { 642 LOGE(" add main postview stream failed\n"); 643 mm_app_del_channel(test_obj, channel); 644 return rc; 645 } 646 647 rc = mm_app_start_channel(test_obj, channel); 648 if (MM_CAMERA_OK != rc) { 649 LOGE("start zsl failed rc=%d\n", rc); 650 mm_app_del_stream(test_obj, channel, s_main); 651 mm_app_del_channel(test_obj, channel); 652 return rc; 653 } 654 655 return rc; 656} 657 658int mm_app_stop_capture(mm_camera_test_obj_t *test_obj) 659{ 660 int rc = MM_CAMERA_OK; 661 mm_camera_channel_t *ch = NULL; 662 663 ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE); 664 665 rc = mm_app_stop_and_del_channel(test_obj, ch); 666 if (MM_CAMERA_OK != rc) { 667 LOGE("stop capture channel failed rc=%d\n", rc); 668 } 669 670 return rc; 671} 672 673int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode) 674{ 675 LOGH("\nEnter %s!!\n"); 676 int rc = MM_CAMERA_OK; 677 uint8_t num_snapshot = 1; 678 int num_rcvd_snapshot = 0; 679 680 if (is_burst_mode) 681 num_snapshot = 6; 682 683 //stop preview before starting capture. 684 rc = mm_app_stop_preview(test_obj); 685 if (rc != MM_CAMERA_OK) { 686 LOGE(" stop preview failed before capture!!, err=%d\n", rc); 687 return rc; 688 } 689 690 rc = mm_app_start_capture(test_obj, num_snapshot); 691 if (rc != MM_CAMERA_OK) { 692 LOGE(" mm_app_start_capture(), err=%d\n", rc); 693 return rc; 694 } 695 while (num_rcvd_snapshot < num_snapshot) { 696 LOGH("\nWaiting mm_camera_app_wait !!\n"); 697 mm_camera_app_wait(); 698 num_rcvd_snapshot++; 699 } 700 rc = mm_app_stop_capture(test_obj); 701 if (rc != MM_CAMERA_OK) { 702 LOGE(" mm_app_stop_capture(), err=%d\n", rc); 703 return rc; 704 } 705 //start preview after capture. 706 rc = mm_app_start_preview(test_obj); 707 if (rc != MM_CAMERA_OK) { 708 LOGE(" start preview failed after capture!!, err=%d\n",rc); 709 } 710 return rc; 711} 712