QCamera3PostProc.cpp revision 66cadfdce2ea19f4707bf2a595b58bd36fbfdf3b
1/* Copyright (c) 2012-2013, The Linux Foundataion. 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#define LOG_TAG "QCamera3PostProc" 31 32#include <stdlib.h> 33#include <utils/Errors.h> 34 35#include "QCamera3PostProc.h" 36#include "QCamera3HWI.h" 37#include "QCamera3Channel.h" 38#include "QCamera3Stream.h" 39 40namespace qcamera { 41 42/*=========================================================================== 43 * FUNCTION : QCamera3PostProcessor 44 * 45 * DESCRIPTION: constructor of QCamera3PostProcessor. 46 * 47 * PARAMETERS : 48 * @cam_ctrl : ptr to HWI object 49 * 50 * RETURN : None 51 *==========================================================================*/ 52QCamera3PostProcessor::QCamera3PostProcessor(QCamera3PicChannel* ch_ctrl) 53 : m_parent(ch_ctrl), 54 mJpegCB(NULL), 55 mJpegUserData(NULL), 56 mJpegClientHandle(0), 57 mJpegSessionId(0), 58 m_pJpegExifObj(NULL), 59 m_bThumbnailNeeded(TRUE), 60 m_inputPPQ(releasePPInputData, this), 61 m_ongoingPPQ(releaseOngoingPPData, this), 62 m_inputJpegQ(releaseJpegData, this), 63 m_ongoingJpegQ(releaseJpegData, this), 64 m_inputRawQ(releasePPInputData, this) 65{ 66 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 67} 68 69/*=========================================================================== 70 * FUNCTION : ~QCamera3PostProcessor 71 * 72 * DESCRIPTION: deconstructor of QCamera3PostProcessor. 73 * 74 * PARAMETERS : None 75 * 76 * RETURN : None 77 *==========================================================================*/ 78QCamera3PostProcessor::~QCamera3PostProcessor() 79{ 80 if (m_pJpegExifObj != NULL) { 81 delete m_pJpegExifObj; 82 m_pJpegExifObj = NULL; 83 } 84} 85 86/*=========================================================================== 87 * FUNCTION : init 88 * 89 * DESCRIPTION: initialization of postprocessor 90 * 91 * PARAMETERS : 92 * @jpeg_cb : callback to handle jpeg event from mm-camera-interface 93 * @user_data : user data ptr for jpeg callback 94 * 95 * RETURN : int32_t type of status 96 * NO_ERROR -- success 97 * none-zero failure code 98 *==========================================================================*/ 99int32_t QCamera3PostProcessor::init(jpeg_encode_callback_t jpeg_cb, void *user_data) 100{ 101 mJpegCB = jpeg_cb; 102 mJpegUserData = user_data; 103 104 mJpegClientHandle = jpeg_open(&mJpegHandle); 105 if(!mJpegClientHandle) { 106 ALOGE("%s : jpeg_open did not work", __func__); 107 return UNKNOWN_ERROR; 108 } 109 110 m_dataProcTh.launch(dataProcessRoutine, this); 111 112 return NO_ERROR; 113} 114 115/*=========================================================================== 116 * FUNCTION : deinit 117 * 118 * DESCRIPTION: de-initialization of postprocessor 119 * 120 * PARAMETERS : None 121 * 122 * RETURN : int32_t type of status 123 * NO_ERROR -- success 124 * none-zero failure code 125 *==========================================================================*/ 126int32_t QCamera3PostProcessor::deinit() 127{ 128 m_dataProcTh.exit(); 129 130 if(mJpegClientHandle > 0) { 131 int rc = mJpegHandle.close(mJpegClientHandle); 132 ALOGE("%s: Jpeg closed, rc = %d, mJpegClientHandle = %x", 133 __func__, rc, mJpegClientHandle); 134 mJpegClientHandle = 0; 135 memset(&mJpegHandle, 0, sizeof(mJpegHandle)); 136 } 137 138 return NO_ERROR; 139} 140 141/*=========================================================================== 142 * FUNCTION : start 143 * 144 * DESCRIPTION: start postprocessor. Data process thread and data notify thread 145 * will be launched. 146 * 147 * PARAMETERS : 148 * @pSrcChannel : source channel obj ptr that possibly needs reprocess 149 * 150 * RETURN : int32_t type of status 151 * NO_ERROR -- success 152 * none-zero failure code 153 * 154 * NOTE : if any reprocess is needed, a reprocess channel/stream 155 * will be started. 156 *==========================================================================*/ 157int32_t QCamera3PostProcessor::start(QCamera3Memory* mMemory) 158{ 159 int32_t rc = NO_ERROR; 160 mJpegMem = mMemory; 161 m_dataProcTh.sendCmd(CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE); 162 163 return rc; 164} 165 166/*=========================================================================== 167 * FUNCTION : stop 168 * 169 * DESCRIPTION: stop postprocessor. Data process and notify thread will be stopped. 170 * 171 * PARAMETERS : None 172 * 173 * RETURN : int32_t type of status 174 * NO_ERROR -- success 175 * none-zero failure code 176 * 177 * NOTE : reprocess channel will be stopped and deleted if there is any 178 *==========================================================================*/ 179int32_t QCamera3PostProcessor::stop() 180{ 181 m_dataProcTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, TRUE); 182 183 return NO_ERROR; 184} 185 186/*=========================================================================== 187 * FUNCTION : getJpegEncodingConfig 188 * 189 * DESCRIPTION: function to prepare encoding job information 190 * 191 * PARAMETERS : 192 * @encode_parm : param to be filled with encoding configuration 193 * 194 * RETURN : int32_t type of status 195 * NO_ERROR -- success 196 * none-zero failure code 197 *==========================================================================*/ 198int32_t QCamera3PostProcessor::getJpegEncodingConfig(mm_jpeg_encode_params_t& encode_parm, 199 QCamera3Stream *main_stream, 200 QCamera3Stream *thumb_stream) 201{ 202 ALOGV("%s : E", __func__); 203 int32_t ret = NO_ERROR; 204 205 encode_parm.jpeg_cb = mJpegCB; 206 encode_parm.userdata = mJpegUserData; 207 208 m_bThumbnailNeeded = TRUE; // need encode thumbnail by default 209 cam_dimension_t thumbnailSize; 210 memset(&thumbnailSize, 0, sizeof(cam_dimension_t)); 211 m_parent->getThumbnailSize(thumbnailSize); 212 if (thumbnailSize.width == 0 && thumbnailSize.height == 0) { 213 // (0,0) means no thumbnail 214 m_bThumbnailNeeded = FALSE; 215 } 216 encode_parm.encode_thumbnail = m_bThumbnailNeeded; 217 218 // get color format 219 cam_format_t img_fmt = CAM_FORMAT_YUV_420_NV12; //default value 220 main_stream->getFormat(img_fmt); 221 encode_parm.color_format = getColorfmtFromImgFmt(img_fmt); 222 223 // get jpeg quality 224 encode_parm.quality = m_parent->getJpegQuality(); 225 if (encode_parm.quality <= 0) { 226 encode_parm.quality = 85; 227 } 228 229 // get exif data 230 if (m_pJpegExifObj != NULL) { 231 delete m_pJpegExifObj; 232 m_pJpegExifObj = NULL; 233 } 234 m_pJpegExifObj = m_parent->getExifData(); 235 if (m_pJpegExifObj != NULL) { 236 encode_parm.exif_info.exif_data = m_pJpegExifObj->getEntries(); 237 encode_parm.exif_info.numOfEntries = m_pJpegExifObj->getNumOfEntries(); 238 } 239 240 cam_frame_len_offset_t main_offset; 241 memset(&main_offset, 0, sizeof(cam_frame_len_offset_t)); 242 main_stream->getFrameOffset(main_offset); 243 244 // src buf config 245 //Pass input main image buffer info to encoder. 246 QCamera3Memory *pStreamMem = main_stream->getStreamBufs(); 247 if (pStreamMem == NULL) { 248 ALOGE("%s: cannot get stream bufs from main stream", __func__); 249 ret = BAD_VALUE; 250 goto on_error; 251 } 252 encode_parm.num_src_bufs = pStreamMem->getCnt(); 253 for (uint32_t i = 0; i < encode_parm.num_src_bufs; i++) { 254 if (pStreamMem != NULL) { 255 encode_parm.src_main_buf[i].index = i; 256 encode_parm.src_main_buf[i].buf_size = pStreamMem->getSize(i); 257 encode_parm.src_main_buf[i].buf_vaddr = (uint8_t *)pStreamMem->getPtr(i); 258 encode_parm.src_main_buf[i].fd = pStreamMem->getFd(i); 259 encode_parm.src_main_buf[i].format = MM_JPEG_FMT_YUV; 260 encode_parm.src_main_buf[i].offset = main_offset; 261 } 262 } 263 264 //Pass input thumbnail buffer info to encoder. 265 //Note: In this version thumb_stream = main_stream 266 if (m_bThumbnailNeeded == TRUE) { 267 if (thumb_stream == NULL) { 268 thumb_stream = main_stream; 269 } 270 pStreamMem = thumb_stream->getStreamBufs(); 271 if (pStreamMem == NULL) { 272 ALOGE("%s: cannot get stream bufs from thumb stream", __func__); 273 ret = BAD_VALUE; 274 goto on_error; 275 } 276 cam_frame_len_offset_t thumb_offset; 277 memset(&thumb_offset, 0, sizeof(cam_frame_len_offset_t)); 278 thumb_stream->getFrameOffset(thumb_offset); 279 for (int i = 0; i < pStreamMem->getCnt(); i++) { 280 if (pStreamMem != NULL) { 281 encode_parm.src_thumb_buf[i].index = i; 282 encode_parm.src_thumb_buf[i].buf_size = pStreamMem->getSize(i); 283 encode_parm.src_thumb_buf[i].buf_vaddr = (uint8_t *)pStreamMem->getPtr(i); 284 encode_parm.src_thumb_buf[i].fd = pStreamMem->getFd(i); 285 encode_parm.src_thumb_buf[i].format = MM_JPEG_FMT_YUV; 286 encode_parm.src_thumb_buf[i].offset = thumb_offset; 287 } 288 } 289 } 290 291 //Pass output jpeg buffer info to encoder. 292 //mJpegMem is allocated by framework. 293 encode_parm.num_dst_bufs = 1; 294 encode_parm.dest_buf[0].index = 0; 295 encode_parm.dest_buf[0].buf_size = mJpegMem->getSize(0); 296 encode_parm.dest_buf[0].buf_vaddr = (uint8_t *)mJpegMem->getPtr(0); 297 encode_parm.dest_buf[0].fd = mJpegMem->getFd(0); 298 encode_parm.dest_buf[0].format = MM_JPEG_FMT_YUV; 299 encode_parm.dest_buf[0].offset = main_offset; 300 301 ALOGV("%s : X", __func__); 302 return NO_ERROR; 303 304on_error: 305 if (m_pJpegExifObj != NULL) { 306 delete m_pJpegExifObj; 307 m_pJpegExifObj = NULL; 308 } 309 ALOGV("%s : X with error %d", __func__, ret); 310 return ret; 311} 312 313/*=========================================================================== 314 * FUNCTION : processData 315 * 316 * DESCRIPTION: enqueue data into dataProc thread 317 * 318 * PARAMETERS : 319 * @frame : process frame received from mm-camera-interface 320 * 321 * RETURN : int32_t type of status 322 * NO_ERROR -- success 323 * none-zero failure code 324 * 325 * NOTE : depends on if offline reprocess is needed, received frame will 326 * be sent to either input queue of postprocess or jpeg encoding 327 *==========================================================================*/ 328int32_t QCamera3PostProcessor::processData(mm_camera_super_buf_t *frame) 329{ 330 ALOGD("%s: no need offline reprocess, sending to jpeg encoding", __func__); 331 qcamera_jpeg_data_t *jpeg_job = 332 (qcamera_jpeg_data_t *)malloc(sizeof(qcamera_jpeg_data_t)); 333 if (jpeg_job == NULL) { 334 ALOGE("%s: No memory for jpeg job", __func__); 335 return NO_MEMORY; 336 } 337 338 memset(jpeg_job, 0, sizeof(qcamera_jpeg_data_t)); 339 jpeg_job->src_frame = frame; 340 341 // enqueu to jpeg input queue 342 m_inputJpegQ.enqueue((void *)jpeg_job); 343 m_dataProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 344 345 return NO_ERROR; 346} 347 348/*=========================================================================== 349 * FUNCTION : processRawData 350 * 351 * DESCRIPTION: enqueue raw data into dataProc thread 352 * 353 * PARAMETERS : 354 * @frame : process frame received from mm-camera-interface 355 * 356 * RETURN : int32_t type of status 357 * NO_ERROR -- success 358 * none-zero failure code 359 *==========================================================================*/ 360int32_t QCamera3PostProcessor::processRawData(mm_camera_super_buf_t *frame) 361{ 362 // enqueu to raw input queue 363 m_inputRawQ.enqueue((void *)frame); 364 m_dataProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 365 return NO_ERROR; 366} 367 368/*=========================================================================== 369 * FUNCTION : processPPData 370 * 371 * DESCRIPTION: process received frame after reprocess. 372 * 373 * PARAMETERS : 374 * @frame : received frame from reprocess channel. 375 * 376 * RETURN : int32_t type of status 377 * NO_ERROR -- success 378 * none-zero failure code 379 * 380 * NOTE : The frame after reprocess need to send to jpeg encoding. 381 *==========================================================================*/ 382int32_t QCamera3PostProcessor::processPPData(mm_camera_super_buf_t *frame) 383{ 384 qcamera_pp_data_t *job = (qcamera_pp_data_t *)m_ongoingPPQ.dequeue(); 385 386 if (job == NULL || job->src_frame == NULL) { 387 ALOGE("%s: Cannot find reprocess job", __func__); 388 return BAD_VALUE; 389 } 390 391 qcamera_jpeg_data_t *jpeg_job = 392 (qcamera_jpeg_data_t *)malloc(sizeof(qcamera_jpeg_data_t)); 393 if (jpeg_job == NULL) { 394 ALOGE("%s: No memory for jpeg job", __func__); 395 return NO_MEMORY; 396 } 397 398 memset(jpeg_job, 0, sizeof(qcamera_jpeg_data_t)); 399 jpeg_job->src_frame = frame; 400 jpeg_job->src_reproc_frame = job->src_frame; 401 402 // free pp job buf 403 free(job); 404 405 // enqueu reprocessed frame to jpeg input queue 406 m_inputJpegQ.enqueue((void *)jpeg_job); 407 408 // wait up data proc thread 409 m_dataProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 410 411 return NO_ERROR; 412} 413 414/*=========================================================================== 415 * FUNCTION : findJpegJobByJobId 416 * 417 * DESCRIPTION: find a jpeg job from ongoing Jpeg queue by its job ID 418 * 419 * PARAMETERS : 420 * @jobId : job Id of the job 421 * 422 * RETURN : ptr to a jpeg job struct. NULL if not found. 423 * 424 * NOTE : Currently only one job is sending to mm-jpeg-interface for jpeg 425 * encoding. Therefore simply dequeue from the ongoing Jpeg Queue 426 * will serve the purpose to find the jpeg job. 427 *==========================================================================*/ 428qcamera_jpeg_data_t *QCamera3PostProcessor::findJpegJobByJobId(uint32_t jobId) 429{ 430 qcamera_jpeg_data_t * job = NULL; 431 if (jobId == 0) { 432 ALOGE("%s: not a valid jpeg jobId", __func__); 433 return NULL; 434 } 435 436 // currely only one jpeg job ongoing, so simply dequeue the head 437 job = (qcamera_jpeg_data_t *)m_ongoingJpegQ.dequeue(); 438 return job; 439} 440 441/*=========================================================================== 442 * FUNCTION : releasePPInputData 443 * 444 * DESCRIPTION: callback function to release post process input data node 445 * 446 * PARAMETERS : 447 * @data : ptr to post process input data 448 * @user_data : user data ptr (QCamera3Reprocessor) 449 * 450 * RETURN : None 451 *==========================================================================*/ 452void QCamera3PostProcessor::releasePPInputData(void *data, void *user_data) 453{ 454 QCamera3PostProcessor *pme = (QCamera3PostProcessor *)user_data; 455 if (NULL != pme) { 456 pme->releaseSuperBuf((mm_camera_super_buf_t *)data); 457 } 458} 459 460/*=========================================================================== 461 * FUNCTION : releaseJpegData 462 * 463 * DESCRIPTION: callback function to release jpeg job node 464 * 465 * PARAMETERS : 466 * @data : ptr to ongoing jpeg job data 467 * @user_data : user data ptr (QCamera3Reprocessor) 468 * 469 * RETURN : None 470 *==========================================================================*/ 471void QCamera3PostProcessor::releaseJpegData(void *data, void *user_data) 472{ 473 QCamera3PostProcessor *pme = (QCamera3PostProcessor *)user_data; 474 if (NULL != pme) { 475 pme->releaseJpegJobData((qcamera_jpeg_data_t *)data); 476 } 477} 478 479/*=========================================================================== 480 * FUNCTION : releaseOngoingPPData 481 * 482 * DESCRIPTION: callback function to release ongoing postprocess job node 483 * 484 * PARAMETERS : 485 * @data : ptr to onging postprocess job 486 * @user_data : user data ptr (QCamera3Reprocessor) 487 * 488 * RETURN : None 489 *==========================================================================*/ 490void QCamera3PostProcessor::releaseOngoingPPData(void *data, void *user_data) 491{ 492 QCamera3PostProcessor *pme = (QCamera3PostProcessor *)user_data; 493 if (NULL != pme) { 494 qcamera_pp_data_t *pp_job = (qcamera_pp_data_t *)data; 495 if (NULL != pp_job->src_frame) { 496 pme->releaseSuperBuf(pp_job->src_frame); 497 free(pp_job->src_frame); 498 pp_job->src_frame = NULL; 499 } 500 } 501} 502 503/*=========================================================================== 504 * FUNCTION : releaseSuperBuf 505 * 506 * DESCRIPTION: function to release a superbuf frame by returning back to kernel 507 * 508 * PARAMETERS : 509 * @super_buf : ptr to the superbuf frame 510 * 511 * RETURN : None 512 *==========================================================================*/ 513void QCamera3PostProcessor::releaseSuperBuf(mm_camera_super_buf_t *super_buf) 514{ 515 if (NULL != super_buf) { 516 if (m_parent != NULL) { 517 m_parent->bufDone(super_buf); 518 } 519 } 520} 521 522/*=========================================================================== 523 * FUNCTION : releaseJpegJobData 524 * 525 * DESCRIPTION: function to release internal resources in jpeg job struct 526 * 527 * PARAMETERS : 528 * @job : ptr to jpeg job struct 529 * 530 * RETURN : None 531 * 532 * NOTE : original source frame need to be queued back to kernel for 533 * future use. Output buf of jpeg job need to be released since 534 * it's allocated for each job. Exif object need to be deleted. 535 *==========================================================================*/ 536void QCamera3PostProcessor::releaseJpegJobData(qcamera_jpeg_data_t *job) 537{ 538 ALOGV("%s: E", __func__); 539 if (NULL != job) { 540 if (NULL != job->src_reproc_frame) { 541 releaseSuperBuf(job->src_reproc_frame); 542 free(job->src_reproc_frame); 543 job->src_reproc_frame = NULL; 544 } 545 546 if (NULL != job->src_frame) { 547 releaseSuperBuf(job->src_frame); 548 free(job->src_frame); 549 job->src_frame = NULL; 550 } 551 mJpegMem = NULL; 552 } 553 ALOGV("%s: X", __func__); 554} 555 556/*=========================================================================== 557 * FUNCTION : getColorfmtFromImgFmt 558 * 559 * DESCRIPTION: function to return jpeg color format based on its image format 560 * 561 * PARAMETERS : 562 * @img_fmt : image format 563 * 564 * RETURN : jpeg color format that can be understandable by omx lib 565 *==========================================================================*/ 566mm_jpeg_color_format QCamera3PostProcessor::getColorfmtFromImgFmt(cam_format_t img_fmt) 567{ 568 switch (img_fmt) { 569 case CAM_FORMAT_YUV_420_NV21: 570 return MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 571 case CAM_FORMAT_YUV_420_NV21_ADRENO: 572 return MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 573 case CAM_FORMAT_YUV_420_NV12: 574 return MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V2; 575 case CAM_FORMAT_YUV_420_YV12: 576 return MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V2; 577 case CAM_FORMAT_YUV_422_NV61: 578 return MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V1; 579 case CAM_FORMAT_YUV_422_NV16: 580 return MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V1; 581 default: 582 return MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 583 } 584} 585 586/*=========================================================================== 587 * FUNCTION : getJpegImgTypeFromImgFmt 588 * 589 * DESCRIPTION: function to return jpeg encode image type based on its image format 590 * 591 * PARAMETERS : 592 * @img_fmt : image format 593 * 594 * RETURN : return jpeg source image format (YUV or Bitstream) 595 *==========================================================================*/ 596mm_jpeg_format_t QCamera3PostProcessor::getJpegImgTypeFromImgFmt(cam_format_t img_fmt) 597{ 598 switch (img_fmt) { 599 case CAM_FORMAT_YUV_420_NV21: 600 case CAM_FORMAT_YUV_420_NV21_ADRENO: 601 case CAM_FORMAT_YUV_420_NV12: 602 case CAM_FORMAT_YUV_420_YV12: 603 case CAM_FORMAT_YUV_422_NV61: 604 case CAM_FORMAT_YUV_422_NV16: 605 return MM_JPEG_FMT_YUV; 606 default: 607 return MM_JPEG_FMT_YUV; 608 } 609} 610 611/*=========================================================================== 612 * FUNCTION : encodeData 613 * 614 * DESCRIPTION: function to prepare encoding job information and send to 615 * mm-jpeg-interface to do the encoding job 616 * 617 * PARAMETERS : 618 * @jpeg_job_data : ptr to a struct saving job related information 619 * @needNewSess : flag to indicate if a new jpeg encoding session need 620 * to be created. After creation, this flag will be toggled 621 * 622 * RETURN : int32_t type of status 623 * NO_ERROR -- success 624 * none-zero failure code 625 *==========================================================================*/ 626int32_t QCamera3PostProcessor::encodeData(qcamera_jpeg_data_t *jpeg_job_data, 627 uint8_t &needNewSess) 628{ 629 ALOGV("%s : E", __func__); 630 int32_t ret = NO_ERROR; 631 mm_jpeg_job_t jpg_job; 632 uint32_t jobId = 0; 633 QCamera3Stream *main_stream = NULL; 634 mm_camera_buf_def_t *main_frame = NULL; 635 QCamera3Stream *thumb_stream = NULL; 636 mm_camera_buf_def_t *thumb_frame = NULL; 637 mm_camera_super_buf_t *recvd_frame = jpeg_job_data->src_frame; 638 639 // find channel 640 QCamera3Channel *pChannel = m_parent; 641 // check reprocess channel if not found 642 if (pChannel == NULL) { 643 ALOGE("%s: No corresponding channel (ch_id = %d) exist, return here", 644 __func__, recvd_frame->ch_id); 645 return BAD_VALUE; 646 } 647 648 // find snapshot frame and thumnail frame 649 //Note: In this version we will receive only snapshot frame. 650 for (int i = 0; i < recvd_frame->num_bufs; i++) { 651 QCamera3Stream *pStream = 652 pChannel->getStreamByHandle(recvd_frame->bufs[i]->stream_id); 653 if (pStream != NULL) { 654 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 655 pStream->isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC)) { 656 main_stream = pStream; 657 main_frame = recvd_frame->bufs[i]; 658 } else if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) || 659 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW)) { 660 thumb_stream = pStream; 661 thumb_frame = recvd_frame->bufs[i]; 662 } 663 } 664 } 665 666 if(NULL == main_frame){ 667 ALOGE("%s : Main frame is NULL", __func__); 668 return BAD_VALUE; 669 } 670 671 QCamera3Memory *memObj = (QCamera3Memory *)main_frame->mem_info; 672 if (NULL == memObj) { 673 ALOGE("%s : Memeory Obj of main frame is NULL", __func__); 674 return NO_MEMORY; 675 } 676 677 // clean and invalidate cache ops through mem obj of the frame 678 memObj->cleanInvalidateCache(main_frame->buf_idx); 679 680 if (thumb_frame != NULL) { 681 QCamera3Memory *thumb_memObj = (QCamera3Memory *)thumb_frame->mem_info; 682 if (NULL != thumb_memObj) { 683 // clean and invalidate cache ops through mem obj of the frame 684 thumb_memObj->cleanInvalidateCache(thumb_frame->buf_idx); 685 } 686 } 687 688 if (mJpegClientHandle <= 0) { 689 ALOGE("%s: Error: bug here, mJpegClientHandle is 0", __func__); 690 return UNKNOWN_ERROR; 691 } 692 693 if (needNewSess) { 694 // create jpeg encoding session 695 mm_jpeg_encode_params_t encodeParam; 696 memset(&encodeParam, 0, sizeof(mm_jpeg_encode_params_t)); 697 698 getJpegEncodingConfig(encodeParam, main_stream, thumb_stream); 699 ret = mJpegHandle.create_session(mJpegClientHandle, &encodeParam, &mJpegSessionId); 700 if (ret != NO_ERROR) { 701 ALOGE("%s: error creating a new jpeg encoding session", __func__); 702 return ret; 703 } 704 needNewSess = FALSE; 705 } 706 707 // Fill in new job 708 memset(&jpg_job, 0, sizeof(mm_jpeg_job_t)); 709 jpg_job.job_type = JPEG_JOB_TYPE_ENCODE; 710 jpg_job.encode_job.session_id = mJpegSessionId; 711 jpg_job.encode_job.src_index = main_frame->buf_idx; 712 jpg_job.encode_job.dst_index = 0; 713 714 cam_rect_t crop; 715 memset(&crop, 0, sizeof(cam_rect_t)); 716 //TBD_later - Zoom event removed in stream 717 //main_stream->getCropInfo(crop); 718 719 cam_dimension_t src_dim; 720 memset(&src_dim, 0, sizeof(cam_dimension_t)); 721 main_stream->getFrameDimension(src_dim); 722 723 // main dim 724 jpg_job.encode_job.main_dim.src_dim = src_dim; 725 jpg_job.encode_job.main_dim.dst_dim = src_dim; 726 jpg_job.encode_job.main_dim.crop = crop; 727 728 // thumbnail dim 729 if (m_bThumbnailNeeded == TRUE) { 730 if (thumb_stream == NULL) { 731 // need jpeg thumbnail, but no postview/preview stream exists 732 // we use the main stream/frame to encode thumbnail 733 thumb_stream = main_stream; 734 thumb_frame = main_frame; 735 } 736 memset(&crop, 0, sizeof(cam_rect_t)); 737 //TBD_later - Zoom event removed in stream 738 //thumb_stream->getCropInfo(crop); 739 memset(&src_dim, 0, sizeof(cam_dimension_t)); 740 thumb_stream->getFrameDimension(src_dim); 741 jpg_job.encode_job.thumb_dim.src_dim = src_dim; 742 m_parent->getThumbnailSize(jpg_job.encode_job.thumb_dim.dst_dim); 743 jpg_job.encode_job.thumb_dim.crop = crop; 744 jpg_job.encode_job.thumb_index = thumb_frame->buf_idx; 745 } 746 747 // set rotation only when no online rotation or offline pp rotation is done before 748 749 if (!m_parent->needOnlineRotation()) { 750 jpg_job.encode_job.rotation = m_parent->getJpegRotation(); 751 } 752 ALOGV("%s: jpeg rotation is set to %d", __func__, jpg_job.encode_job.rotation); 753 754 // Find meta data frame. Meta data frame contains additional exif info 755 // which will be extracted and filled in by encoder. 756 //Note: In this version meta data will be null 757 //as we don't support bundling of snapshot and metadata streams. 758 759 mm_camera_buf_def_t *meta_frame = NULL; 760 for (int i = 0; i < jpeg_job_data->src_frame->num_bufs; i++) { 761 // look through input superbuf 762 if (jpeg_job_data->src_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_METADATA) { 763 meta_frame = jpeg_job_data->src_frame->bufs[i]; 764 break; 765 } 766 } 767 if (meta_frame == NULL && jpeg_job_data->src_reproc_frame != NULL) { 768 // look through reprocess source superbuf 769 for (int i = 0; i < jpeg_job_data->src_reproc_frame->num_bufs; i++) { 770 if (jpeg_job_data->src_reproc_frame->bufs[i]->stream_type == CAM_STREAM_TYPE_METADATA) { 771 meta_frame = jpeg_job_data->src_reproc_frame->bufs[i]; 772 break; 773 } 774 } 775 } 776 if (meta_frame != NULL) { 777 // fill in meta data frame ptr 778 jpg_job.encode_job.p_metadata = (cam_metadata_info_t *)meta_frame->buffer; 779 } 780 781 //Start jpeg encoding 782 ret = mJpegHandle.start_job(&jpg_job, &jobId); 783 if (ret == NO_ERROR) { 784 // remember job info 785 jpeg_job_data->jobId = jobId; 786 } 787 788 ALOGD("%s : X", __func__); 789 return ret; 790} 791 792/*=========================================================================== 793 * FUNCTION : dataProcessRoutine 794 * 795 * DESCRIPTION: data process routine that handles input data either from input 796 * Jpeg Queue to do jpeg encoding, or from input PP Queue to do 797 * reprocess. 798 * 799 * PARAMETERS : 800 * @data : user data ptr (QCamera3PostProcessor) 801 * 802 * RETURN : None 803 *==========================================================================*/ 804void *QCamera3PostProcessor::dataProcessRoutine(void *data) 805{ 806 int running = 1; 807 int ret; 808 uint8_t is_active = FALSE; 809 uint8_t needNewSess = TRUE; 810 QCamera3PostProcessor *pme = (QCamera3PostProcessor *)data; 811 QCameraCmdThread *cmdThread = &pme->m_dataProcTh; 812 813 ALOGD("%s: E", __func__); 814 do { 815 do { 816 ret = cam_sem_wait(&cmdThread->cmd_sem); 817 if (ret != 0 && errno != EINVAL) { 818 ALOGE("%s: cam_sem_wait error (%s)", 819 __func__, strerror(errno)); 820 return NULL; 821 } 822 } while (ret != 0); 823 824 // we got notified about new cmd avail in cmd queue 825 camera_cmd_type_t cmd = cmdThread->getCmd(); 826 switch (cmd) { 827 case CAMERA_CMD_TYPE_START_DATA_PROC: 828 ALOGD("%s: start data proc", __func__); 829 is_active = TRUE; 830 needNewSess = TRUE; 831 break; 832 case CAMERA_CMD_TYPE_STOP_DATA_PROC: 833 { 834 ALOGD("%s: stop data proc", __func__); 835 is_active = FALSE; 836 837 // cancel all ongoing jpeg jobs 838 qcamera_jpeg_data_t *jpeg_job = 839 (qcamera_jpeg_data_t *)pme->m_ongoingJpegQ.dequeue(); 840 while (jpeg_job != NULL) { 841 pme->mJpegHandle.abort_job(jpeg_job->jobId); 842 843 pme->releaseJpegJobData(jpeg_job); 844 free(jpeg_job); 845 846 jpeg_job = (qcamera_jpeg_data_t *)pme->m_ongoingJpegQ.dequeue(); 847 } 848 849 // destroy jpeg encoding session 850 if ( 0 < pme->mJpegSessionId ) { 851 pme->mJpegHandle.destroy_session(pme->mJpegSessionId); 852 pme->mJpegSessionId = 0; 853 } 854 855 // free jpeg exif obj 856 if (pme->m_pJpegExifObj != NULL) { 857 delete pme->m_pJpegExifObj; 858 pme->m_pJpegExifObj = NULL; 859 } 860 needNewSess = TRUE; 861 862 // flush ongoing postproc Queue 863 pme->m_ongoingPPQ.flush(); 864 865 // flush input jpeg Queue 866 pme->m_inputJpegQ.flush(); 867 868 // flush input Postproc Queue 869 pme->m_inputPPQ.flush(); 870 871 // flush input raw Queue 872 pme->m_inputRawQ.flush(); 873 874 // signal cmd is completed 875 cam_sem_post(&cmdThread->sync_sem); 876 } 877 break; 878 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 879 { 880 ALOGD("%s: Do next job, active is %d", __func__, is_active); 881 if (is_active == TRUE) { 882 // check if there is any ongoing jpeg jobs 883 if (pme->m_ongoingJpegQ.isEmpty()) { 884 // no ongoing jpeg job, we are fine to send jpeg encoding job 885 qcamera_jpeg_data_t *jpeg_job = 886 (qcamera_jpeg_data_t *)pme->m_inputJpegQ.dequeue(); 887 888 if (NULL != jpeg_job) { 889 //TBD_later - play shutter sound 890 //pme->m_parent->playShutter(); 891 892 // add into ongoing jpeg job Q 893 pme->m_ongoingJpegQ.enqueue((void *)jpeg_job); 894 ret = pme->encodeData(jpeg_job, needNewSess); 895 if (NO_ERROR != ret) { 896 // dequeue the last one 897 pme->m_ongoingJpegQ.dequeue(false); 898 899 pme->releaseJpegJobData(jpeg_job); 900 free(jpeg_job); 901 } 902 } 903 } 904 905 mm_camera_super_buf_t *pp_frame = 906 (mm_camera_super_buf_t *)pme->m_inputPPQ.dequeue(); 907 if (NULL != pp_frame) { 908 qcamera_pp_data_t *pp_job = 909 (qcamera_pp_data_t *)malloc(sizeof(qcamera_pp_data_t)); 910 if (pp_job != NULL) { 911 memset(pp_job, 0, sizeof(qcamera_pp_data_t)); 912 } else { 913 ALOGE("%s: no mem for qcamera_pp_data_t", __func__); 914 ret = -1; 915 } 916 917 if (0 != ret) { 918 // free pp_job 919 if (pp_job != NULL) { 920 free(pp_job); 921 } 922 // free frame 923 if (pp_frame != NULL) { 924 pme->releaseSuperBuf(pp_frame); 925 free(pp_frame); 926 } 927 } 928 } 929 } else { 930 // not active, simply return buf and do no op 931 mm_camera_super_buf_t *super_buf = 932 (mm_camera_super_buf_t *)pme->m_inputJpegQ.dequeue(); 933 if (NULL != super_buf) { 934 pme->releaseSuperBuf(super_buf); 935 free(super_buf); 936 } 937 super_buf = (mm_camera_super_buf_t *)pme->m_inputRawQ.dequeue(); 938 if (NULL != super_buf) { 939 pme->releaseSuperBuf(super_buf); 940 free(super_buf); 941 } 942 super_buf = (mm_camera_super_buf_t *)pme->m_inputPPQ.dequeue(); 943 if (NULL != super_buf) { 944 pme->releaseSuperBuf(super_buf); 945 free(super_buf); 946 } 947 } 948 } 949 break; 950 case CAMERA_CMD_TYPE_EXIT: 951 running = 0; 952 break; 953 default: 954 break; 955 } 956 } while (running); 957 ALOGD("%s: X", __func__); 958 return NULL; 959} 960 961/*=========================================================================== 962 * FUNCTION : getJpegPaddingReq 963 * 964 * DESCRIPTION: function to add an entry to exif data 965 * 966 * PARAMETERS : 967 * @padding_info : jpeg specific padding requirement 968 * 969 * RETURN : int32_t type of status 970 * NO_ERROR -- success 971 * none-zero failure code 972 *==========================================================================*/ 973int32_t QCamera3PostProcessor::getJpegPaddingReq(cam_padding_info_t &padding_info) 974{ 975 // TODO: hardcode for now, needs to query from mm-jpeg-interface 976 padding_info.width_padding = CAM_PAD_NONE; 977 padding_info.height_padding = CAM_PAD_TO_16; 978 padding_info.plane_padding = CAM_PAD_TO_WORD; 979 return NO_ERROR; 980} 981 982/*=========================================================================== 983 * FUNCTION : QCamera3Exif 984 * 985 * DESCRIPTION: constructor of QCamera3Exif 986 * 987 * PARAMETERS : None 988 * 989 * RETURN : None 990 *==========================================================================*/ 991QCamera3Exif::QCamera3Exif() 992 : m_nNumEntries(0) 993{ 994 memset(m_Entries, 0, sizeof(m_Entries)); 995} 996 997/*=========================================================================== 998 * FUNCTION : ~QCamera3Exif 999 * 1000 * DESCRIPTION: deconstructor of QCamera3Exif. Will release internal memory ptr. 1001 * 1002 * PARAMETERS : None 1003 * 1004 * RETURN : None 1005 *==========================================================================*/ 1006QCamera3Exif::~QCamera3Exif() 1007{ 1008 for (uint32_t i = 0; i < m_nNumEntries; i++) { 1009 switch (m_Entries[i].tag_entry.type) { 1010 case EXIF_BYTE: 1011 { 1012 if (m_Entries[i].tag_entry.count > 1 && 1013 m_Entries[i].tag_entry.data._bytes != NULL) { 1014 free(m_Entries[i].tag_entry.data._bytes); 1015 m_Entries[i].tag_entry.data._bytes = NULL; 1016 } 1017 } 1018 break; 1019 case EXIF_ASCII: 1020 { 1021 if (m_Entries[i].tag_entry.data._ascii != NULL) { 1022 free(m_Entries[i].tag_entry.data._ascii); 1023 m_Entries[i].tag_entry.data._ascii = NULL; 1024 } 1025 } 1026 break; 1027 case EXIF_SHORT: 1028 { 1029 if (m_Entries[i].tag_entry.count > 1 && 1030 m_Entries[i].tag_entry.data._shorts != NULL) { 1031 free(m_Entries[i].tag_entry.data._shorts); 1032 m_Entries[i].tag_entry.data._shorts = NULL; 1033 } 1034 } 1035 break; 1036 case EXIF_LONG: 1037 { 1038 if (m_Entries[i].tag_entry.count > 1 && 1039 m_Entries[i].tag_entry.data._longs != NULL) { 1040 free(m_Entries[i].tag_entry.data._longs); 1041 m_Entries[i].tag_entry.data._longs = NULL; 1042 } 1043 } 1044 break; 1045 case EXIF_RATIONAL: 1046 { 1047 if (m_Entries[i].tag_entry.count > 1 && 1048 m_Entries[i].tag_entry.data._rats != NULL) { 1049 free(m_Entries[i].tag_entry.data._rats); 1050 m_Entries[i].tag_entry.data._rats = NULL; 1051 } 1052 } 1053 break; 1054 case EXIF_UNDEFINED: 1055 { 1056 if (m_Entries[i].tag_entry.data._undefined != NULL) { 1057 free(m_Entries[i].tag_entry.data._undefined); 1058 m_Entries[i].tag_entry.data._undefined = NULL; 1059 } 1060 } 1061 break; 1062 case EXIF_SLONG: 1063 { 1064 if (m_Entries[i].tag_entry.count > 1 && 1065 m_Entries[i].tag_entry.data._slongs != NULL) { 1066 free(m_Entries[i].tag_entry.data._slongs); 1067 m_Entries[i].tag_entry.data._slongs = NULL; 1068 } 1069 } 1070 break; 1071 case EXIF_SRATIONAL: 1072 { 1073 if (m_Entries[i].tag_entry.count > 1 && 1074 m_Entries[i].tag_entry.data._srats != NULL) { 1075 free(m_Entries[i].tag_entry.data._srats); 1076 m_Entries[i].tag_entry.data._srats = NULL; 1077 } 1078 } 1079 break; 1080 default: 1081 ALOGE("%s: Error, Unknown type",__func__); 1082 break; 1083 } 1084 } 1085} 1086 1087/*=========================================================================== 1088 * FUNCTION : addEntry 1089 * 1090 * DESCRIPTION: function to add an entry to exif data 1091 * 1092 * PARAMETERS : 1093 * @tagid : exif tag ID 1094 * @type : data type 1095 * @count : number of data in uint of its type 1096 * @data : input data ptr 1097 * 1098 * RETURN : int32_t type of status 1099 * NO_ERROR -- success 1100 * none-zero failure code 1101 *==========================================================================*/ 1102int32_t QCamera3Exif::addEntry(exif_tag_id_t tagid, 1103 exif_tag_type_t type, 1104 uint32_t count, 1105 void *data) 1106{ 1107 int32_t rc = NO_ERROR; 1108 if(m_nNumEntries >= MAX_EXIF_TABLE_ENTRIES) { 1109 ALOGE("%s: Number of entries exceeded limit", __func__); 1110 return NO_MEMORY; 1111 } 1112 1113 m_Entries[m_nNumEntries].tag_id = tagid; 1114 m_Entries[m_nNumEntries].tag_entry.type = type; 1115 m_Entries[m_nNumEntries].tag_entry.count = count; 1116 m_Entries[m_nNumEntries].tag_entry.copy = 1; 1117 switch (type) { 1118 case EXIF_BYTE: 1119 { 1120 if (count > 1) { 1121 uint8_t *values = (uint8_t *)malloc(count); 1122 if (values == NULL) { 1123 ALOGE("%s: No memory for byte array", __func__); 1124 rc = NO_MEMORY; 1125 } else { 1126 memcpy(values, data, count); 1127 m_Entries[m_nNumEntries].tag_entry.data._bytes = values; 1128 } 1129 } else { 1130 m_Entries[m_nNumEntries].tag_entry.data._byte = 1131 *(uint8_t *)data; 1132 } 1133 } 1134 break; 1135 case EXIF_ASCII: 1136 { 1137 char *str = NULL; 1138 str = (char *)malloc(count + 1); 1139 if (str == NULL) { 1140 ALOGE("%s: No memory for ascii string", __func__); 1141 rc = NO_MEMORY; 1142 } else { 1143 memset(str, 0, count + 1); 1144 memcpy(str, data, count); 1145 m_Entries[m_nNumEntries].tag_entry.data._ascii = str; 1146 } 1147 } 1148 break; 1149 case EXIF_SHORT: 1150 { 1151 if (count > 1) { 1152 uint16_t *values = 1153 (uint16_t *)malloc(count * sizeof(uint16_t)); 1154 if (values == NULL) { 1155 ALOGE("%s: No memory for short array", __func__); 1156 rc = NO_MEMORY; 1157 } else { 1158 memcpy(values, data, count * sizeof(uint16_t)); 1159 m_Entries[m_nNumEntries].tag_entry.data._shorts =values; 1160 } 1161 } else { 1162 m_Entries[m_nNumEntries].tag_entry.data._short = 1163 *(uint16_t *)data; 1164 } 1165 } 1166 break; 1167 case EXIF_LONG: 1168 { 1169 if (count > 1) { 1170 uint32_t *values = 1171 (uint32_t *)malloc(count * sizeof(uint32_t)); 1172 if (values == NULL) { 1173 ALOGE("%s: No memory for long array", __func__); 1174 rc = NO_MEMORY; 1175 } else { 1176 memcpy(values, data, count * sizeof(uint32_t)); 1177 m_Entries[m_nNumEntries].tag_entry.data._longs = values; 1178 } 1179 } else { 1180 m_Entries[m_nNumEntries].tag_entry.data._long = 1181 *(uint32_t *)data; 1182 } 1183 } 1184 break; 1185 case EXIF_RATIONAL: 1186 { 1187 if (count > 1) { 1188 rat_t *values = (rat_t *)malloc(count * sizeof(rat_t)); 1189 if (values == NULL) { 1190 ALOGE("%s: No memory for rational array", __func__); 1191 rc = NO_MEMORY; 1192 } else { 1193 memcpy(values, data, count * sizeof(rat_t)); 1194 m_Entries[m_nNumEntries].tag_entry.data._rats = values; 1195 } 1196 } else { 1197 m_Entries[m_nNumEntries].tag_entry.data._rat = 1198 *(rat_t *)data; 1199 } 1200 } 1201 break; 1202 case EXIF_UNDEFINED: 1203 { 1204 uint8_t *values = (uint8_t *)malloc(count); 1205 if (values == NULL) { 1206 ALOGE("%s: No memory for undefined array", __func__); 1207 rc = NO_MEMORY; 1208 } else { 1209 memcpy(values, data, count); 1210 m_Entries[m_nNumEntries].tag_entry.data._undefined = values; 1211 } 1212 } 1213 break; 1214 case EXIF_SLONG: 1215 { 1216 if (count > 1) { 1217 int32_t *values = 1218 (int32_t *)malloc(count * sizeof(int32_t)); 1219 if (values == NULL) { 1220 ALOGE("%s: No memory for signed long array", __func__); 1221 rc = NO_MEMORY; 1222 } else { 1223 memcpy(values, data, count * sizeof(int32_t)); 1224 m_Entries[m_nNumEntries].tag_entry.data._slongs =values; 1225 } 1226 } else { 1227 m_Entries[m_nNumEntries].tag_entry.data._slong = 1228 *(int32_t *)data; 1229 } 1230 } 1231 break; 1232 case EXIF_SRATIONAL: 1233 { 1234 if (count > 1) { 1235 srat_t *values = (srat_t *)malloc(count * sizeof(srat_t)); 1236 if (values == NULL) { 1237 ALOGE("%s: No memory for sign rational array",__func__); 1238 rc = NO_MEMORY; 1239 } else { 1240 memcpy(values, data, count * sizeof(srat_t)); 1241 m_Entries[m_nNumEntries].tag_entry.data._srats = values; 1242 } 1243 } else { 1244 m_Entries[m_nNumEntries].tag_entry.data._srat = 1245 *(srat_t *)data; 1246 } 1247 } 1248 break; 1249 default: 1250 ALOGE("%s: Error, Unknown type",__func__); 1251 break; 1252 } 1253 1254 // Increase number of entries 1255 m_nNumEntries++; 1256 return rc; 1257} 1258 1259}; // namespace qcamera 1260