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