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