QCamera3Channel.cpp revision 1ae761c167e28a6a40830d52576fe5bcbce0debb
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 "QCamera3Channel"
31//#define LOG_NDEBUG 0
32#include <fcntl.h>
33#include <stdlib.h>
34#include <cstdlib>
35#include <stdio.h>
36#include <string.h>
37#include <hardware/camera3.h>
38#include <system/camera_metadata.h>
39#include <gralloc_priv.h>
40#include <utils/Log.h>
41#include <utils/Errors.h>
42#include <cutils/properties.h>
43#include "QCamera3Channel.h"
44#include "QCamera3HWI.h"
45
46using namespace android;
47
48#define MIN_STREAMING_BUFFER_NUM 7+11
49
50namespace qcamera {
51static const char ExifAsciiPrefix[] =
52    { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };          // "ASCII\0\0\0"
53static const char ExifUndefinedPrefix[] =
54    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };   // "\0\0\0\0\0\0\0\0"
55
56#define EXIF_ASCII_PREFIX_SIZE           8   //(sizeof(ExifAsciiPrefix))
57#define FOCAL_LENGTH_DECIMAL_PRECISION   100
58
59/*===========================================================================
60 * FUNCTION   : QCamera3Channel
61 *
62 * DESCRIPTION: constrcutor of QCamera3Channel
63 *
64 * PARAMETERS :
65 *   @cam_handle : camera handle
66 *   @cam_ops    : ptr to camera ops table
67 *
68 * RETURN     : none
69 *==========================================================================*/
70QCamera3Channel::QCamera3Channel(uint32_t cam_handle,
71                               mm_camera_ops_t *cam_ops,
72                               channel_cb_routine cb_routine,
73                               cam_padding_info_t *paddingInfo,
74                               void *userData)
75{
76    m_camHandle = cam_handle;
77    m_camOps = cam_ops;
78    m_bIsActive = false;
79
80    m_handle = 0;
81    m_numStreams = 0;
82    memset(mStreams, 0, sizeof(mStreams));
83    mUserData = userData;
84
85    mStreamInfoBuf = NULL;
86    mChannelCB = cb_routine;
87    mPaddingInfo = paddingInfo;
88}
89
90/*===========================================================================
91 * FUNCTION   : QCamera3Channel
92 *
93 * DESCRIPTION: default constrcutor of QCamera3Channel
94 *
95 * PARAMETERS : none
96 *
97 * RETURN     : none
98 *==========================================================================*/
99QCamera3Channel::QCamera3Channel()
100{
101    m_camHandle = 0;
102    m_camOps = NULL;
103    m_bIsActive = false;
104
105    m_handle = 0;
106    m_numStreams = 0;
107    memset(mStreams, 0, sizeof(mStreams));
108    mUserData = NULL;
109
110    mStreamInfoBuf = NULL;
111    mChannelCB = NULL;
112    mPaddingInfo = NULL;
113}
114
115/*===========================================================================
116 * FUNCTION   : ~QCamera3Channel
117 *
118 * DESCRIPTION: destructor of QCamera3Channel
119 *
120 * PARAMETERS : none
121 *
122 * RETURN     : none
123 *==========================================================================*/
124QCamera3Channel::~QCamera3Channel()
125{
126    if (m_bIsActive)
127        stop();
128
129    for (int i = 0; i < m_numStreams; i++) {
130        if (mStreams[i] != NULL) {
131            delete mStreams[i];
132            mStreams[i] = 0;
133        }
134    }
135    if (m_handle) {
136        m_camOps->delete_channel(m_camHandle, m_handle);
137        ALOGE("%s: deleting channel %d", __func__, m_handle);
138        m_handle = 0;
139    }
140    m_numStreams = 0;
141}
142
143/*===========================================================================
144 * FUNCTION   : init
145 *
146 * DESCRIPTION: initialization of channel
147 *
148 * PARAMETERS :
149 *   @attr    : channel bundle attribute setting
150 *   @dataCB  : data notify callback
151 *   @userData: user data ptr
152 *
153 * RETURN     : int32_t type of status
154 *              NO_ERROR  -- success
155 *              none-zero failure code
156 *==========================================================================*/
157int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr,
158                             mm_camera_buf_notify_t dataCB)
159{
160    m_handle = m_camOps->add_channel(m_camHandle,
161                                      attr,
162                                      dataCB,
163                                      this);
164    if (m_handle == 0) {
165        ALOGE("%s: Add channel failed", __func__);
166        return UNKNOWN_ERROR;
167    }
168    return NO_ERROR;
169}
170
171/*===========================================================================
172 * FUNCTION   : addStream
173 *
174 * DESCRIPTION: add a stream into channel
175 *
176 * PARAMETERS :
177 *   @allocator      : stream related buffer allocator
178 *   @streamInfoBuf  : ptr to buf that constains stream info
179 *   @minStreamBufNum: number of stream buffers needed
180 *   @paddingInfo    : padding information
181 *   @stream_cb      : stream data notify callback
182 *   @userdata       : user data ptr
183 *
184 * RETURN     : int32_t type of status
185 *              NO_ERROR  -- success
186 *              none-zero failure code
187 *==========================================================================*/
188int32_t QCamera3Channel::addStream(cam_stream_type_t streamType,
189                                  cam_format_t streamFormat,
190                                  cam_dimension_t streamDim,
191                                  uint8_t minStreamBufNum)
192{
193    int32_t rc = NO_ERROR;
194
195    if (m_numStreams >= 1) {
196        ALOGE("%s: Only one stream per channel supported in v3 Hal", __func__);
197        return BAD_VALUE;
198    }
199
200    if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
201        ALOGE("%s: stream number (%d) exceeds max limit (%d)",
202              __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
203        return BAD_VALUE;
204    }
205    QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
206                                               m_handle,
207                                               m_camOps,
208                                               mPaddingInfo,
209                                               this);
210    if (pStream == NULL) {
211        ALOGE("%s: No mem for Stream", __func__);
212        return NO_MEMORY;
213    }
214
215    rc = pStream->init(streamType, streamFormat, streamDim, NULL, minStreamBufNum,
216                                                    streamCbRoutine, this);
217    if (rc == 0) {
218        mStreams[m_numStreams] = pStream;
219        m_numStreams++;
220    } else {
221        delete pStream;
222    }
223    return rc;
224}
225
226/*===========================================================================
227 * FUNCTION   : start
228 *
229 * DESCRIPTION: start channel, which will start all streams belong to this channel
230 *
231 * PARAMETERS :
232 *
233 * RETURN     : int32_t type of status
234 *              NO_ERROR  -- success
235 *              none-zero failure code
236 *==========================================================================*/
237int32_t QCamera3Channel::start()
238{
239    int32_t rc = NO_ERROR;
240
241    if (m_numStreams > 1) {
242        ALOGE("%s: bundle not supported", __func__);
243    } else if (m_numStreams == 0) {
244        return NO_INIT;
245    }
246
247    for (int i = 0; i < m_numStreams; i++) {
248        if (mStreams[i] != NULL) {
249            mStreams[i]->start();
250        }
251    }
252    rc = m_camOps->start_channel(m_camHandle, m_handle);
253
254    if (rc != NO_ERROR) {
255        for (int i = 0; i < m_numStreams; i++) {
256            if (mStreams[i] != NULL) {
257                mStreams[i]->stop();
258            }
259        }
260    } else {
261        m_bIsActive = true;
262    }
263
264    return rc;
265}
266
267/*===========================================================================
268 * FUNCTION   : stop
269 *
270 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
271 *
272 * PARAMETERS : none
273 *
274 * RETURN     : int32_t type of status
275 *              NO_ERROR  -- success
276 *              none-zero failure code
277 *==========================================================================*/
278int32_t QCamera3Channel::stop()
279{
280    int32_t rc = NO_ERROR;
281    if(!m_bIsActive) {
282        ALOGE("%s: Attempt to stop inactive channel",__func__);
283        return rc;
284    }
285
286    for (int i = 0; i < m_numStreams; i++) {
287        if (mStreams[i] != NULL) {
288            mStreams[i]->stop();
289        }
290    }
291
292    rc = m_camOps->stop_channel(m_camHandle, m_handle);
293
294    m_bIsActive = false;
295    return rc;
296}
297
298/*===========================================================================
299 * FUNCTION   : bufDone
300 *
301 * DESCRIPTION: return a stream buf back to kernel
302 *
303 * PARAMETERS :
304 *   @recvd_frame  : stream buf frame to be returned
305 *
306 * RETURN     : int32_t type of status
307 *              NO_ERROR  -- success
308 *              none-zero failure code
309 *==========================================================================*/
310int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame)
311{
312    int32_t rc = NO_ERROR;
313    for (int i = 0; i < recvd_frame->num_bufs; i++) {
314         if (recvd_frame->bufs[i] != NULL) {
315             for (int j = 0; j < m_numStreams; j++) {
316                 if (mStreams[j] != NULL &&
317                     mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
318                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
319                     break; // break loop j
320                 }
321             }
322         }
323    }
324
325    return rc;
326}
327
328/*===========================================================================
329 * FUNCTION   : getStreamTypeMask
330 *
331 * DESCRIPTION: Get bit mask of all stream types in this channel
332 *
333 * PARAMETERS : None
334 *
335 * RETURN     : Bit mask of all stream types in this channel
336 *==========================================================================*/
337uint32_t QCamera3Channel::getStreamTypeMask()
338{
339    uint32_t mask = 0;
340    for (int i = 0; i < m_numStreams; i++) {
341       mask |= (0x1 << mStreams[i]->getMyType());
342    }
343    return mask;
344}
345
346/*===========================================================================
347 * FUNCTION   : getStreamID
348 *
349 * DESCRIPTION: Get StreamID of requested stream type
350 *
351 * PARAMETERS : streamMask
352 *
353 * RETURN     : Stream ID
354 *==========================================================================*/
355uint32_t QCamera3Channel::getStreamID(uint32_t streamMask)
356{
357    uint32_t streamID = 0;
358    for (int i = 0; i < m_numStreams; i++) {
359        if (streamMask == (uint32_t )(0x1 << mStreams[i]->getMyType())) {
360            streamID = mStreams[i]->getMyServerID();
361            break;
362        }
363    }
364    return streamID;
365}
366
367/*===========================================================================
368 * FUNCTION   : getInternalFormatBuffer
369 *
370 * DESCRIPTION: return buffer in the internal format structure
371 *
372 * PARAMETERS :
373 *   @streamHandle : buffer handle
374 *
375 * RETURN     : stream object. NULL if not found
376 *==========================================================================*/
377mm_camera_buf_def_t* QCamera3RegularChannel::getInternalFormatBuffer(
378                                            buffer_handle_t * buffer)
379{
380    int32_t index;
381    if(buffer == NULL)
382        return NULL;
383    index = mMemory.getMatchBufIndex((void*)buffer);
384    if(index < 0) {
385        ALOGE("%s: Could not find object among registered buffers",__func__);
386        return NULL;
387    }
388    return mStreams[0]->getInternalFormatBuffer(index);
389}
390
391/*===========================================================================
392 * FUNCTION   : getStreamByHandle
393 *
394 * DESCRIPTION: return stream object by stream handle
395 *
396 * PARAMETERS :
397 *   @streamHandle : stream handle
398 *
399 * RETURN     : stream object. NULL if not found
400 *==========================================================================*/
401QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle)
402{
403    for (int i = 0; i < m_numStreams; i++) {
404        if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
405            return mStreams[i];
406        }
407    }
408    return NULL;
409}
410
411/*===========================================================================
412 * FUNCTION   : getStreamByIndex
413 *
414 * DESCRIPTION: return stream object by index
415 *
416 * PARAMETERS :
417 *   @streamHandle : stream handle
418 *
419 * RETURN     : stream object. NULL if not found
420 *==========================================================================*/
421QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index)
422{
423    if (index < m_numStreams) {
424        return mStreams[index];
425    }
426    return NULL;
427}
428
429/*===========================================================================
430 * FUNCTION   : streamCbRoutine
431 *
432 * DESCRIPTION: callback routine for stream
433 *
434 * PARAMETERS :
435 *   @streamHandle : stream handle
436 *
437 * RETURN     : stream object. NULL if not found
438 *==========================================================================*/
439void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
440                QCamera3Stream *stream, void *userdata)
441{
442    QCamera3Channel *channel = (QCamera3Channel *)userdata;
443    if (channel == NULL) {
444        ALOGE("%s: invalid channel pointer", __func__);
445        return;
446    }
447    channel->streamCbRoutine(super_frame, stream);
448}
449
450/*===========================================================================
451 * FUNCTION   : QCamera3RegularChannel
452 *
453 * DESCRIPTION: constructor of QCamera3RegularChannel
454 *
455 * PARAMETERS :
456 *   @cam_handle : camera handle
457 *   @cam_ops    : ptr to camera ops table
458 *   @cb_routine : callback routine to frame aggregator
459 *   @stream     : camera3_stream_t structure
460 *   @width      : stream width
461 *   @height     : stream height
462 *   @stream_type: Channel stream type
463 *
464 * RETURN     : none
465 *==========================================================================*/
466QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
467                    mm_camera_ops_t *cam_ops,
468                    channel_cb_routine cb_routine,
469                    cam_padding_info_t *paddingInfo,
470                    void *userData,
471                    camera3_stream_t *stream,
472                    uint32_t width, uint32_t height,
473                    cam_stream_type_t stream_type) :
474                        QCamera3Channel(cam_handle, cam_ops, cb_routine,
475                                paddingInfo, userData),
476                        mCamera3Stream(stream),
477                        mNumBufs(0),
478                        mWidth(width),
479                        mHeight(height),
480                        mStreamType(stream_type)
481{
482}
483
484/*===========================================================================
485 * FUNCTION   : QCamera3RegularChannel
486 *
487 * DESCRIPTION: constrcutor of QCamera3RegularChannel
488 *
489 * PARAMETERS :
490 *   @cam_handle : camera handle
491 *   @cam_ops    : ptr to camera ops table
492 *   @cb_routine : callback routine to frame aggregator
493 *   @stream     : camera3_stream_t structure
494 *   @stream_type: Channel stream type
495 *
496 * RETURN     : none
497 *==========================================================================*/
498QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
499                    mm_camera_ops_t *cam_ops,
500                    channel_cb_routine cb_routine,
501                    cam_padding_info_t *paddingInfo,
502                    void *userData,
503                    camera3_stream_t *stream,
504                    cam_stream_type_t stream_type) :
505                        QCamera3Channel(cam_handle, cam_ops, cb_routine,
506                                paddingInfo, userData),
507                        mCamera3Stream(stream),
508                        mNumBufs(0),
509                        mWidth(stream->width),
510                        mHeight(stream->height),
511                        mStreamType(stream_type)
512{
513}
514
515/*===========================================================================
516 * FUNCTION   : ~QCamera3RegularChannel
517 *
518 * DESCRIPTION: destructor of QCamera3RegularChannel
519 *
520 * PARAMETERS : none
521 *
522 * RETURN     : none
523 *==========================================================================*/
524QCamera3RegularChannel::~QCamera3RegularChannel()
525{
526}
527
528/*===========================================================================
529 * FUNCTION   : initialize
530 *
531 * DESCRIPTION: Initialize and add camera channel & stream
532 *
533 * PARAMETERS :
534 *
535 * RETURN     : int32_t type of status
536 *              NO_ERROR  -- success
537 *              none-zero failure code
538 *==========================================================================*/
539
540int32_t QCamera3RegularChannel::initialize()
541{
542    int32_t rc = NO_ERROR;
543    cam_format_t streamFormat;
544    cam_dimension_t streamDim;
545
546    if (NULL == mCamera3Stream) {
547        ALOGE("%s: Camera stream uninitialized", __func__);
548        return NO_INIT;
549    }
550
551    if (1 <= m_numStreams) {
552        // Only one stream per channel supported in v3 Hal
553        return NO_ERROR;
554    }
555
556    rc = init(NULL, NULL);
557    if (rc < 0) {
558        ALOGE("%s: init failed", __func__);
559        return rc;
560    }
561
562    mNumBufs = CAM_MAX_NUM_BUFS_PER_STREAM;
563
564    if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
565        if (mStreamType ==  CAM_STREAM_TYPE_VIDEO) {
566            streamFormat = CAM_FORMAT_YUV_420_NV12;
567        } else if (mStreamType == CAM_STREAM_TYPE_PREVIEW) {
568            streamFormat = CAM_FORMAT_YUV_420_NV21;
569        } else {
570            //TODO: Add a new flag in libgralloc for ZSL buffers, and its size needs
571            // to be properly aligned and padded.
572            streamFormat = CAM_FORMAT_YUV_420_NV21;
573        }
574    } else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
575         streamFormat = CAM_FORMAT_YUV_420_NV21;
576    } else {
577        //TODO: Fail for other types of streams for now
578        ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__);
579        return -EINVAL;
580    }
581
582    streamDim.width = mWidth;
583    streamDim.height = mHeight;
584
585    rc = QCamera3Channel::addStream(mStreamType,
586            streamFormat,
587            streamDim,
588            mNumBufs);
589
590    return rc;
591}
592
593/*===========================================================================
594* FUNCTION   : start
595*
596* DESCRIPTION: start a regular channel
597*
598* PARAMETERS :
599*
600* RETURN     : int32_t type of status
601*              NO_ERROR  -- success
602*              none-zero failure code
603*==========================================================================*/
604int32_t QCamera3RegularChannel::start()
605{
606    int32_t rc = NO_ERROR;
607
608    if (0 < mMemory.getCnt()) {
609        rc = QCamera3Channel::start();
610    }
611    return rc;
612}
613
614/*===========================================================================
615 * FUNCTION   : request
616 *
617 * DESCRIPTION: process a request from camera service. Stream on if ncessary.
618 *
619 * PARAMETERS :
620 *   @buffer  : buffer to be filled for this request
621 *
622 * RETURN     : 0 on a success start of capture
623 *              -EINVAL on invalid input
624 *              -ENODEV on serious error
625 *==========================================================================*/
626int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber)
627{
628    //FIX ME: Return buffer back in case of failures below.
629
630    int32_t rc = NO_ERROR;
631    int index;
632
633    if (NULL == buffer) {
634        ALOGE("%s: Invalid buffer in channel request", __func__);
635        return BAD_VALUE;
636    }
637
638    if(!m_bIsActive) {
639        rc = registerBuffer(buffer);
640        if (NO_ERROR != rc) {
641            ALOGE("%s: On-the-fly buffer registration failed %d",
642                    __func__, rc);
643            return rc;
644        }
645
646        rc = start();
647        if (NO_ERROR != rc) {
648            return rc;
649        }
650    } else {
651        CDBG("%s: Request on an existing stream",__func__);
652    }
653
654    index = mMemory.getMatchBufIndex((void*)buffer);
655    if(index < 0) {
656        rc = registerBuffer(buffer);
657        if (NO_ERROR != rc) {
658            ALOGE("%s: On-the-fly buffer registration failed %d",
659                    __func__, rc);
660            return rc;
661        }
662
663        index = mMemory.getMatchBufIndex((void*)buffer);
664        if (index < 0) {
665            ALOGE("%s: Could not find object among registered buffers",
666                    __func__);
667            return DEAD_OBJECT;
668        }
669    }
670
671    rc = mStreams[0]->bufDone(index);
672    if(rc != NO_ERROR) {
673        ALOGE("%s: Failed to Q new buffer to stream",__func__);
674        return rc;
675    }
676
677    rc = mMemory.markFrameNumber(index, frameNumber);
678    return rc;
679}
680
681/*===========================================================================
682 * FUNCTION   : registerBuffer
683 *
684 * DESCRIPTION: register streaming buffer to the channel object
685 *
686 * PARAMETERS :
687 *   @buffer     : buffer to be registered
688 *
689 * RETURN     : int32_t type of status
690 *              NO_ERROR  -- success
691 *              none-zero failure code
692 *==========================================================================*/
693int32_t QCamera3RegularChannel::registerBuffer(buffer_handle_t *buffer)
694{
695    int rc = 0;
696
697    if ((uint32_t)mMemory.getCnt() > (mNumBufs - 1)) {
698        ALOGE("%s: Trying to register more buffers than initially requested",
699                __func__);
700        return BAD_VALUE;
701    }
702
703    if (0 == m_numStreams) {
704        rc = initialize();
705        if (rc != NO_ERROR) {
706            ALOGE("%s: Couldn't initialize camera stream %d",
707                    __func__, rc);
708            return rc;
709        }
710    }
711
712    rc = mMemory.registerBuffer(buffer);
713    if (ALREADY_EXISTS == rc) {
714        return NO_ERROR;
715    } else if (NO_ERROR != rc) {
716        ALOGE("%s: Buffer %p couldn't be registered %d", __func__, buffer, rc);
717        return rc;
718    }
719
720    return rc;
721}
722
723void QCamera3RegularChannel::streamCbRoutine(
724                            mm_camera_super_buf_t *super_frame,
725                            QCamera3Stream *stream)
726{
727    //FIXME Q Buf back in case of error?
728    uint8_t frameIndex;
729    buffer_handle_t *resultBuffer;
730    int32_t resultFrameNumber;
731    camera3_stream_buffer_t result;
732
733    if(!super_frame) {
734         ALOGE("%s: Invalid Super buffer",__func__);
735         return;
736    }
737
738    if(super_frame->num_bufs != 1) {
739         ALOGE("%s: Multiple streams are not supported",__func__);
740         return;
741    }
742    if(super_frame->bufs[0] == NULL ) {
743         ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
744                  __func__);
745         return;
746    }
747
748    frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
749    if(frameIndex >= mNumBufs) {
750         ALOGE("%s: Error, Invalid index for buffer",__func__);
751         if(stream) {
752             stream->bufDone(frameIndex);
753         }
754         return;
755    }
756
757    ////Use below data to issue framework callback
758    resultBuffer = (buffer_handle_t *)mMemory.getBufferHandle(frameIndex);
759    resultFrameNumber = mMemory.getFrameNumber(frameIndex);
760
761    result.stream = mCamera3Stream;
762    result.buffer = resultBuffer;
763    result.status = CAMERA3_BUFFER_STATUS_OK;
764    result.acquire_fence = -1;
765    result.release_fence = -1;
766
767    mChannelCB(NULL, &result, resultFrameNumber, mUserData);
768    free(super_frame);
769    return;
770}
771
772QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/)
773{
774    return &mMemory;
775}
776
777void QCamera3RegularChannel::putStreamBufs()
778{
779    mMemory.unregisterBuffers();
780}
781
782int QCamera3RegularChannel::kMaxBuffers = 7;
783
784QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle,
785                    mm_camera_ops_t *cam_ops,
786                    channel_cb_routine cb_routine,
787                    cam_padding_info_t *paddingInfo,
788                    void *userData) :
789                        QCamera3Channel(cam_handle, cam_ops,
790                                cb_routine, paddingInfo, userData),
791                        mMemory(NULL)
792{
793}
794
795QCamera3MetadataChannel::~QCamera3MetadataChannel()
796{
797    if (m_bIsActive)
798        stop();
799
800    if (mMemory) {
801        mMemory->deallocate();
802        delete mMemory;
803        mMemory = NULL;
804    }
805}
806
807int32_t QCamera3MetadataChannel::initialize()
808{
809    int32_t rc;
810    cam_dimension_t streamDim;
811
812    if (mMemory || m_numStreams > 0) {
813        ALOGE("%s: metadata channel already initialized", __func__);
814        return -EINVAL;
815    }
816
817    rc = init(NULL, NULL);
818    if (rc < 0) {
819        ALOGE("%s: init failed", __func__);
820        return rc;
821    }
822
823    streamDim.width = sizeof(metadata_buffer_t),
824    streamDim.height = 1;
825    rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
826        streamDim, MIN_STREAMING_BUFFER_NUM);
827    if (rc < 0) {
828        ALOGE("%s: addStream failed", __func__);
829    }
830    return rc;
831}
832
833int32_t QCamera3MetadataChannel::request(buffer_handle_t * /*buffer*/,
834                                                uint32_t /*frameNumber*/)
835{
836    if (!m_bIsActive) {
837        return start();
838    }
839    else
840        return 0;
841}
842
843void QCamera3MetadataChannel::streamCbRoutine(
844                        mm_camera_super_buf_t *super_frame,
845                        QCamera3Stream * /*stream*/)
846{
847    uint32_t requestNumber = 0;
848    if (super_frame == NULL || super_frame->num_bufs != 1) {
849        ALOGE("%s: super_frame is not valid", __func__);
850        return;
851    }
852    mChannelCB(super_frame, NULL, requestNumber, mUserData);
853}
854
855QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len)
856{
857    int rc;
858    if (len < sizeof(metadata_buffer_t)) {
859        ALOGE("%s: Metadata buffer size less than structure %d vs %d",
860                __func__,
861                len,
862                sizeof(metadata_buffer_t));
863        return NULL;
864    }
865    mMemory = new QCamera3HeapMemory();
866    if (!mMemory) {
867        ALOGE("%s: unable to create metadata memory", __func__);
868        return NULL;
869    }
870    rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true);
871    if (rc < 0) {
872        ALOGE("%s: unable to allocate metadata memory", __func__);
873        delete mMemory;
874        mMemory = NULL;
875        return NULL;
876    }
877    memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t));
878    return mMemory;
879}
880
881void QCamera3MetadataChannel::putStreamBufs()
882{
883    mMemory->deallocate();
884    delete mMemory;
885    mMemory = NULL;
886}
887/*************************************************************************************/
888// RAW Channel related functions
889QCameraRawChannel::QCameraRawChannel(uint32_t cam_handle,
890                    mm_camera_ops_t *cam_ops,
891                    channel_cb_routine cb_routine,
892                    cam_padding_info_t *paddingInfo,
893                    void *userData,
894                    cam_dimension_t *raw_dim) :
895                        QCamera3Channel(cam_handle, cam_ops,
896                                cb_routine, paddingInfo, userData),
897                        mMemory(NULL)
898{
899
900  mWidth = raw_dim->width;
901  mHeight = raw_dim->height;
902  mMaxBuffers = 1;
903}
904
905QCameraRawChannel::~QCameraRawChannel()
906{
907    if (m_bIsActive)
908        stop();
909
910    if (mMemory) {
911        mMemory->deallocate();
912        delete mMemory;
913        mMemory = NULL;
914    }
915}
916
917int32_t QCameraRawChannel::initialize()
918{
919    int32_t rc;
920    cam_dimension_t streamDim;
921    cam_stream_type_t streamType;
922    cam_format_t streamFormat;
923
924    if (mMemory || m_numStreams > 0) {
925        ALOGE("%s: RAW channel already initialized", __func__);
926        return -EINVAL;
927    }
928
929    rc = init(NULL, NULL);
930    if (rc < 0) {
931        ALOGE("%s: init failed", __func__);
932        return rc;
933    }
934
935    streamDim.width = mWidth;
936    streamDim.height = mHeight;
937    streamType = CAM_STREAM_TYPE_RAW;
938    streamFormat = CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG;
939
940    CDBG_HIGH("%s: mWidth=%d, mHeight=%d", __func__, mWidth, mHeight);
941
942    rc = QCamera3Channel::addStream(streamType, streamFormat,
943        streamDim, mMaxBuffers);
944    if (rc < 0) {
945        ALOGE("%s: addStream failed", __func__);
946    }
947    return rc;
948}
949
950int32_t QCameraRawChannel::request(buffer_handle_t * /*buffer*/,
951                                                uint32_t /*frameNumber*/)
952{
953    int rc;
954    if (!m_bIsActive) {
955        return start();
956    }
957    else {
958        rc = mStreams[0]->bufDone(0);
959        if(rc != NO_ERROR) {
960            ALOGE("%s: Failed to Q RAW buffer",__func__);
961            return rc;
962        }
963        return 0;
964    }
965}
966
967int32_t QCameraRawChannel::registerBuffers(uint32_t /*num_buffers*/,
968                                        buffer_handle_t ** /*buffers*/)
969{
970    // no registerBuffers are supported for RAW channel
971    return -EINVAL;
972}
973
974void QCameraRawChannel::streamCbRoutine(
975                        mm_camera_super_buf_t *super_frame,
976                        QCamera3Stream * /*stream*/)
977{
978    if (super_frame == NULL || super_frame->num_bufs != 1) {
979        ALOGE("%s: RAW super_frame is not valid", __func__);
980        return;
981    }
982    // Dump the RAW data here and then hold the RAW frame
983    // untill next BLOB request comes
984    CDBG_HIGH("%s: Got the raw snapshot callback, going to dump it", __func__);
985    dumpRawSnapshot(super_frame->bufs[0]);
986    return;
987}
988
989QCamera3Memory* QCameraRawChannel::getStreamBufs(uint32_t len)
990{
991    int rc;
992    mMemory = new QCamera3HeapMemory();
993    if (!mMemory) {
994        ALOGE("%s: unable to create RAW memory", __func__);
995        return NULL;
996    }
997    CDBG_HIGH("%s: num_buffers=%d, len=%d", __func__, mMaxBuffers, len);
998    rc = mMemory->allocate(mMaxBuffers, len, false);
999    if (rc < 0) {
1000        ALOGE("%s: unable to allocate RAW memory", __func__);
1001        delete mMemory;
1002        mMemory = NULL;
1003        return NULL;
1004    }
1005    return mMemory;
1006}
1007
1008void QCameraRawChannel::putStreamBufs()
1009{
1010    mMemory->deallocate();
1011    delete mMemory;
1012    mMemory = NULL;
1013}
1014
1015void QCameraRawChannel::dumpRawSnapshot(mm_camera_buf_def_t *frame)
1016{
1017   QCamera3Stream *stream = getStreamByIndex(0);
1018   char buf[32];
1019   memset(buf, 0, sizeof(buf));
1020   cam_dimension_t dim;
1021   memset(&dim, 0, sizeof(dim));
1022   stream->getFrameDimension(dim);
1023
1024   cam_frame_len_offset_t offset;
1025   memset(&offset, 0, sizeof(cam_frame_len_offset_t));
1026   stream->getFrameOffset(offset);
1027   snprintf(buf, sizeof(buf), "/data/r_%d_%dx%d.raw",
1028            frame->frame_idx, offset.mp[0].stride, offset.mp[0].scanline);
1029
1030   int file_fd = open(buf, O_RDWR| O_CREAT, 0777);
1031   if (file_fd) {
1032      int written_len = write(file_fd, frame->buffer, frame->frame_len);
1033      ALOGE("%s: written number of bytes %d", __func__, written_len);
1034      close(file_fd);
1035   } else {
1036      ALOGE("%s: failed to open file to dump image", __func__);
1037   }
1038
1039}
1040/*************************************************************************************/
1041
1042/*===========================================================================
1043 * FUNCTION   : jpegEvtHandle
1044 *
1045 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events.
1046                Construct result payload and call mChannelCb to deliver buffer
1047                to framework.
1048 *
1049 * PARAMETERS :
1050 *   @status    : status of jpeg job
1051 *   @client_hdl: jpeg client handle
1052 *   @jobId     : jpeg job Id
1053 *   @p_ouput   : ptr to jpeg output result struct
1054 *   @userdata  : user data ptr
1055 *
1056 * RETURN     : none
1057 *==========================================================================*/
1058void QCamera3PicChannel::jpegEvtHandle(jpeg_job_status_t status,
1059                                              uint32_t /*client_hdl*/,
1060                                              uint32_t jobId,
1061                                              mm_jpeg_output_t *p_output,
1062                                              void *userdata)
1063{
1064    buffer_handle_t *resultBuffer, *jpegBufferHandle;
1065    int32_t resultFrameNumber;
1066    int resultStatus = CAMERA3_BUFFER_STATUS_OK;
1067    camera3_stream_buffer_t result;
1068    camera3_jpeg_blob_t jpegHeader;
1069    char* jpeg_eof = 0;
1070    int maxJpegSize;
1071    QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata;
1072    if (obj) {
1073
1074        //Release any cached metabuffer information
1075        if (obj->mMetaFrame != NULL && obj->m_pMetaChannel != NULL) {
1076            ((QCamera3MetadataChannel*)(obj->m_pMetaChannel))->bufDone(obj->mMetaFrame);
1077            obj->mMetaFrame = NULL;
1078            obj->m_pMetaChannel = NULL;
1079        } else {
1080            ALOGE("%s: Meta frame was NULL", __func__);
1081        }
1082        //Construct payload for process_capture_result. Call mChannelCb
1083
1084        qcamera_hal3_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId);
1085
1086        if ((job == NULL) || (status == JPEG_JOB_STATUS_ERROR)) {
1087            ALOGE("%s: Error in jobId: (%d) with status: %d", __func__, jobId, status);
1088            resultStatus = CAMERA3_BUFFER_STATUS_ERROR;
1089        }
1090
1091        //Construct jpeg transient header of type camera3_jpeg_blob_t
1092        //Append at the end of jpeg image of buf_filled_len size
1093
1094        jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
1095        jpegHeader.jpeg_size = p_output->buf_filled_len;
1096
1097
1098        char* jpeg_buf = (char *)p_output->buf_vaddr;
1099
1100        // Gralloc buffer may have additional padding for 4K page size
1101        // Follow size guidelines based on spec since framework relies
1102        // on that to reach end of buffer and with it the header
1103
1104        //Handle same as resultBuffer, but for readablity
1105        jpegBufferHandle =
1106            (buffer_handle_t *)obj->mMemory.getBufferHandle(obj->mCurrentBufIndex);
1107
1108        maxJpegSize = ((private_handle_t*)(*jpegBufferHandle))->width;
1109        if (maxJpegSize > obj->mMemory.getSize(obj->mCurrentBufIndex)) {
1110            maxJpegSize = obj->mMemory.getSize(obj->mCurrentBufIndex);
1111        }
1112
1113        jpeg_eof = &jpeg_buf[maxJpegSize-sizeof(jpegHeader)];
1114        memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader));
1115        obj->mMemory.cleanInvalidateCache(obj->mCurrentBufIndex);
1116
1117        ////Use below data to issue framework callback
1118        resultBuffer = (buffer_handle_t *)obj->mMemory.getBufferHandle(obj->mCurrentBufIndex);
1119        resultFrameNumber = obj->mMemory.getFrameNumber(obj->mCurrentBufIndex);
1120
1121        result.stream = obj->mCamera3Stream;
1122        result.buffer = resultBuffer;
1123        result.status = resultStatus;
1124        result.acquire_fence = -1;
1125        result.release_fence = -1;
1126
1127        CDBG("%s: Issue Callback", __func__);
1128        obj->mChannelCB(NULL, &result, resultFrameNumber, obj->mUserData);
1129
1130        // release internal data for jpeg job
1131        if (job != NULL) {
1132            obj->m_postprocessor.releaseJpegJobData(job);
1133            free(job);
1134        }
1135
1136
1137        return;
1138        // }
1139    } else {
1140        ALOGE("%s: Null userdata in jpeg callback", __func__);
1141    }
1142}
1143
1144QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle,
1145                    mm_camera_ops_t *cam_ops,
1146                    channel_cb_routine cb_routine,
1147                    cam_padding_info_t *paddingInfo,
1148                    void *userData,
1149                    camera3_stream_t *stream) :
1150                        QCamera3Channel(cam_handle, cam_ops, cb_routine,
1151                        paddingInfo, userData),
1152                        m_postprocessor(this),
1153                        mCamera3Stream(stream),
1154                        mNumBufs(0),
1155                        mCurrentBufIndex(-1),
1156                        mYuvMemory(NULL),
1157                        mMetaFrame(NULL)
1158{
1159    QCamera3HardwareInterface* hal_obj = (QCamera3HardwareInterface*)mUserData;
1160    m_max_pic_dim = hal_obj->calcMaxJpegDim();
1161    mYuvWidth = stream->width;
1162    mYuvHeight = stream->height;
1163    int32_t rc = m_postprocessor.init(&mMemory, jpegEvtHandle, this);
1164    if (rc != 0) {
1165        ALOGE("Init Postprocessor failed");
1166    }
1167}
1168
1169QCamera3PicChannel::~QCamera3PicChannel()
1170{
1171    m_postprocessor.stop();
1172    int32_t rc = m_postprocessor.deinit();
1173    if (rc != 0) {
1174        ALOGE("De-init Postprocessor failed");
1175    }
1176}
1177
1178int32_t QCamera3PicChannel::initialize()
1179{
1180    int32_t rc = NO_ERROR;
1181    cam_dimension_t streamDim;
1182    cam_stream_type_t streamType;
1183    cam_format_t streamFormat;
1184    mm_camera_channel_attr_t attr;
1185
1186    if (NULL == mCamera3Stream) {
1187        ALOGE("%s: Camera stream uninitialized", __func__);
1188        return NO_INIT;
1189    }
1190
1191    if (1 <= m_numStreams) {
1192        // Only one stream per channel supported in v3 Hal
1193        return NO_ERROR;
1194    }
1195
1196    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
1197    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
1198    attr.look_back = 1;
1199    attr.post_frame_skip = 1;
1200    attr.water_mark = 1;
1201    attr.max_unmatched_frames = 1;
1202
1203    rc = init(&attr, NULL);
1204    if (rc < 0) {
1205        ALOGE("%s: init failed", __func__);
1206        return rc;
1207    }
1208
1209    streamType = CAM_STREAM_TYPE_SNAPSHOT;
1210    streamFormat = CAM_FORMAT_YUV_420_NV21;
1211    streamDim.width = mYuvWidth;
1212    streamDim.height = mYuvHeight;
1213
1214    int num_buffers = 1;
1215    mNumBufs = CAM_MAX_NUM_BUFS_PER_STREAM;
1216    rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
1217            num_buffers);
1218
1219    return rc;
1220}
1221
1222int32_t QCamera3PicChannel::request(buffer_handle_t *buffer,
1223        uint32_t frameNumber,
1224        mm_camera_buf_def_t *pInputBuffer,
1225        metadata_buffer_t *metadata)
1226{
1227    //FIX ME: Return buffer back in case of failures below.
1228
1229    int32_t rc = NO_ERROR;
1230    int index;
1231    // Picture stream has already been started before any request comes in
1232    if (!m_bIsActive) {
1233        ALOGE("%s: Channel not started!!", __func__);
1234        return NO_INIT;
1235    }
1236
1237    if (pInputBuffer == NULL)
1238        mStreams[0]->bufDone(0);
1239
1240    index = mMemory.getMatchBufIndex((void*)buffer);
1241    if(index < 0) {
1242        rc = registerBuffer(buffer);
1243        if (NO_ERROR != rc) {
1244            ALOGE("%s: On-the-fly buffer registration failed %d",
1245                    __func__, rc);
1246            return rc;
1247        }
1248
1249        index = mMemory.getMatchBufIndex((void*)buffer);
1250        if (index < 0) {
1251            ALOGE("%s: Could not find object among registered buffers",__func__);
1252            return DEAD_OBJECT;
1253        }
1254    }
1255    rc = mMemory.markFrameNumber(index, frameNumber);
1256
1257    //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer
1258    mCurrentBufIndex = index;
1259
1260    // Start postprocessor
1261    m_postprocessor.start(this, metadata);
1262
1263    // Queue jpeg settings
1264    rc = queueJpegSetting(index, metadata);
1265
1266    if (pInputBuffer == NULL)
1267        mStreams[0]->bufDone(0);
1268    else {
1269        mm_camera_super_buf_t *src_frame = NULL;
1270        src_frame = (mm_camera_super_buf_t *)malloc(
1271                sizeof(mm_camera_super_buf_t));
1272        if (src_frame == NULL) {
1273            ALOGE("%s: No memory for src frame", __func__);
1274            return NO_MEMORY;
1275        }
1276        memset(src_frame, 0, sizeof(mm_camera_super_buf_t));
1277        src_frame->num_bufs = 1;
1278        src_frame->bufs[0] = pInputBuffer;
1279
1280        CDBG_HIGH("%s: Post-process started", __func__);
1281        CDBG_HIGH("%s: Issue call to reprocess", __func__);
1282
1283        m_postprocessor.processPPMetadata(metadata);
1284        m_postprocessor.processData(src_frame);
1285    }
1286    return rc;
1287}
1288
1289/*===========================================================================
1290 * FUNCTION   : dataNotifyCB
1291 *
1292 * DESCRIPTION: Channel Level callback used for super buffer data notify.
1293 *              This function is registered with mm-camera-interface to handle
1294 *              data notify
1295 *
1296 * PARAMETERS :
1297 *   @recvd_frame   : stream frame received
1298 *   userdata       : user data ptr
1299 *
1300 * RETURN     : none
1301 *==========================================================================*/
1302void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
1303                                 void *userdata)
1304{
1305    CDBG("%s: E\n", __func__);
1306    QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata;
1307
1308    if (channel == NULL) {
1309        ALOGE("%s: invalid channel pointer", __func__);
1310        return;
1311    }
1312
1313    if(channel->m_numStreams != 1) {
1314        ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__);
1315        return;
1316    }
1317
1318
1319    if(channel->mStreams[0] == NULL) {
1320        ALOGE("%s: Error: Invalid Stream object",__func__);
1321        return;
1322    }
1323
1324    channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]);
1325
1326    CDBG("%s: X\n", __func__);
1327    return;
1328}
1329
1330/*===========================================================================
1331 * FUNCTION   : registerBuffer
1332 *
1333 * DESCRIPTION: register streaming buffer to the channel object
1334 *
1335 * PARAMETERS :
1336 *   @buffer     : buffer to be registered
1337 *
1338 * RETURN     : int32_t type of status
1339 *              NO_ERROR  -- success
1340 *              none-zero failure code
1341 *==========================================================================*/
1342int32_t QCamera3PicChannel::registerBuffer(buffer_handle_t *buffer)
1343{
1344    int rc = 0;
1345
1346    if ((uint32_t)mMemory.getCnt() > (mNumBufs - 1)) {
1347        ALOGE("%s: Trying to register more buffers than initially requested",
1348                __func__);
1349        return BAD_VALUE;
1350    }
1351
1352    if (0 == m_numStreams) {
1353        rc = initialize();
1354        if (rc != NO_ERROR) {
1355            ALOGE("%s: Couldn't initialize camera stream %d",
1356                    __func__, rc);
1357            return rc;
1358        }
1359    }
1360    rc = mMemory.registerBuffer(buffer);
1361    if (ALREADY_EXISTS == rc) {
1362        return NO_ERROR;
1363    } else if (NO_ERROR != rc) {
1364        ALOGE("%s: Buffer %p couldn't be registered %d", __func__, buffer, rc);
1365        return rc;
1366    }
1367
1368    CDBG("%s: X",__func__);
1369
1370    return rc;
1371}
1372
1373void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
1374                            QCamera3Stream *stream)
1375{
1376    //TODO
1377    //Used only for getting YUV. Jpeg callback will be sent back from channel
1378    //directly to HWI. Refer to func jpegEvtHandle
1379
1380    //Got the yuv callback. Calling yuv callback handler in PostProc
1381    uint8_t frameIndex;
1382    mm_camera_super_buf_t* frame = NULL;
1383    if(!super_frame) {
1384         ALOGE("%s: Invalid Super buffer",__func__);
1385         return;
1386    }
1387
1388    if(super_frame->num_bufs != 1) {
1389         ALOGE("%s: Multiple streams are not supported",__func__);
1390         return;
1391    }
1392    if(super_frame->bufs[0] == NULL ) {
1393         ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
1394                  __func__);
1395         return;
1396    }
1397
1398    frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
1399    if(frameIndex >= mNumBufs) {
1400         ALOGE("%s: Error, Invalid index for buffer",__func__);
1401         if(stream) {
1402             stream->bufDone(frameIndex);
1403         }
1404         return;
1405    }
1406
1407    frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
1408    if (frame == NULL) {
1409       ALOGE("%s: Error allocating memory to save received_frame structure.",
1410                                                                    __func__);
1411       if(stream) {
1412           stream->bufDone(frameIndex);
1413       }
1414       return;
1415    }
1416    *frame = *super_frame;
1417    m_postprocessor.processData(frame);
1418    free(super_frame);
1419    return;
1420}
1421
1422QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
1423{
1424    int rc = 0;
1425
1426    mYuvMemory = new QCamera3HeapMemory();
1427    if (!mYuvMemory) {
1428        ALOGE("%s: unable to create metadata memory", __func__);
1429        return NULL;
1430    }
1431
1432    //Queue YUV buffers in the beginning mQueueAll = true
1433    rc = mYuvMemory->allocate(1, len, false);
1434    if (rc < 0) {
1435        ALOGE("%s: unable to allocate metadata memory", __func__);
1436        delete mYuvMemory;
1437        mYuvMemory = NULL;
1438        return NULL;
1439    }
1440    return mYuvMemory;
1441}
1442
1443void QCamera3PicChannel::putStreamBufs()
1444{
1445    mMemory.unregisterBuffers();
1446
1447    mYuvMemory->deallocate();
1448    delete mYuvMemory;
1449    mYuvMemory = NULL;
1450}
1451
1452int32_t QCamera3PicChannel::queueReprocMetadata(metadata_buffer_t *metadata)
1453{
1454    return m_postprocessor.processPPMetadata(metadata);
1455}
1456
1457int32_t QCamera3PicChannel::queueJpegSetting(int32_t index, metadata_buffer_t *metadata)
1458{
1459    jpeg_settings_t *settings =
1460            (jpeg_settings_t *)malloc(sizeof(jpeg_settings_t));
1461
1462    if (!settings) {
1463        ALOGE("%s: out of memory allocating jpeg_settings", __func__);
1464        return -ENOMEM;
1465    }
1466
1467    memset(settings, 0, sizeof(jpeg_settings_t));
1468
1469    settings->out_buf_index = index;
1470
1471    settings->jpeg_orientation = 0;
1472    if (IS_PARAM_AVAILABLE(CAM_INTF_META_JPEG_ORIENTATION, metadata)) {
1473        int32_t *orientation = (int32_t *)POINTER_OF_PARAM(
1474                CAM_INTF_META_JPEG_ORIENTATION, metadata);
1475        settings->jpeg_orientation = *orientation;
1476    }
1477
1478    settings->jpeg_quality = 85;
1479    if (IS_PARAM_AVAILABLE(CAM_INTF_META_JPEG_QUALITY, metadata)) {
1480        uint8_t *quality = (uint8_t *)POINTER_OF_PARAM(
1481                CAM_INTF_META_JPEG_QUALITY, metadata);
1482        settings->jpeg_quality = *quality;
1483    }
1484
1485    if (IS_PARAM_AVAILABLE(CAM_INTF_META_JPEG_THUMB_QUALITY, metadata)) {
1486        uint8_t *quality = (uint8_t *)POINTER_OF_PARAM(
1487                CAM_INTF_META_JPEG_THUMB_QUALITY, metadata);
1488        settings->jpeg_thumb_quality = *quality;
1489    }
1490
1491    if (IS_PARAM_AVAILABLE(CAM_INTF_META_JPEG_THUMB_SIZE, metadata)) {
1492        cam_dimension_t *dimension = (cam_dimension_t *)POINTER_OF_PARAM(
1493                CAM_INTF_META_JPEG_THUMB_SIZE, metadata);
1494        settings->thumbnail_size = *dimension;
1495    }
1496
1497    settings->gps_timestamp_valid = 0;
1498    if (IS_PARAM_AVAILABLE(CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata)) {
1499        int64_t *timestamp = (int64_t *)POINTER_OF_PARAM(
1500                CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata);
1501        settings->gps_timestamp = *timestamp;
1502        settings->gps_timestamp_valid = 1;
1503    }
1504
1505    settings->gps_coordinates_valid = 0;
1506    if (IS_PARAM_AVAILABLE(CAM_INTF_META_JPEG_GPS_COORDINATES, metadata)) {
1507        double *coordinates = (double *)POINTER_OF_PARAM(
1508                CAM_INTF_META_JPEG_GPS_COORDINATES, metadata);
1509        memcpy(settings->gps_coordinates, coordinates, 3*sizeof(double));
1510        settings->gps_coordinates_valid = 1;
1511    }
1512
1513    if (IS_PARAM_AVAILABLE(CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata)) {
1514        char *proc_methods = (char *)POINTER_OF_PARAM(
1515                CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata);
1516        memset(settings->gps_processing_method, 0,
1517                sizeof(settings->gps_processing_method));
1518        strncpy(settings->gps_processing_method, proc_methods,
1519                sizeof(settings->gps_processing_method));
1520    }
1521
1522    return m_postprocessor.processJpegSettingData(settings);
1523}
1524
1525/*===========================================================================
1526 * FUNCTION   : getRational
1527 *
1528 * DESCRIPTION: compose rational struct
1529 *
1530 * PARAMETERS :
1531 *   @rat     : ptr to struct to store rational info
1532 *   @num     :num of the rational
1533 *   @denom   : denom of the rational
1534 *
1535 * RETURN     : int32_t type of status
1536 *              NO_ERROR  -- success
1537 *              none-zero failure code
1538 *==========================================================================*/
1539int32_t getRational(rat_t *rat, int num, int denom)
1540{
1541    if (NULL == rat) {
1542        ALOGE("%s: NULL rat input", __func__);
1543        return BAD_VALUE;
1544    }
1545    rat->num = num;
1546    rat->denom = denom;
1547    return NO_ERROR;
1548}
1549
1550/*===========================================================================
1551 * FUNCTION   : parseGPSCoordinate
1552 *
1553 * DESCRIPTION: parse GPS coordinate string
1554 *
1555 * PARAMETERS :
1556 *   @coord_str : [input] coordinate string
1557 *   @coord     : [output]  ptr to struct to store coordinate
1558 *
1559 * RETURN     : int32_t type of status
1560 *              NO_ERROR  -- success
1561 *              none-zero failure code
1562 *==========================================================================*/
1563int parseGPSCoordinate(const char *coord_str, rat_t* coord)
1564{
1565    if(coord == NULL) {
1566        ALOGE("%s: error, invalid argument coord == NULL", __func__);
1567        return BAD_VALUE;
1568    }
1569    float degF = atof(coord_str);
1570    if (degF < 0) {
1571        degF = -degF;
1572    }
1573    float minF = (degF - (int) degF) * 60;
1574    float secF = (minF - (int) minF) * 60;
1575
1576    getRational(&coord[0], (int)degF, 1);
1577    getRational(&coord[1], (int)minF, 1);
1578    getRational(&coord[2], (int)(secF * 10000), 10000);
1579    return NO_ERROR;
1580}
1581
1582/*===========================================================================
1583 * FUNCTION   : getExifDateTime
1584 *
1585 * DESCRIPTION: query exif date time
1586 *
1587 * PARAMETERS :
1588 *   @dateTime   : string to store exif date time
1589 *   @subsecTime : string to store exif subsec time
1590 *   @count      : length of the dateTime string
1591 *   @subsecCount: length of the subsecTime string
1592 *
1593 * RETURN     : int32_t type of status
1594 *              NO_ERROR  -- success
1595 *              none-zero failure code
1596 *==========================================================================*/
1597int32_t getExifDateTime(char *dateTime, char *subsecTime,
1598        uint32_t &count, uint32_t &subsecCount)
1599{
1600    //get time and date from system
1601    struct timeval tv;
1602    struct tm *timeinfo;
1603
1604    gettimeofday(&tv, NULL);
1605    timeinfo = localtime(&tv.tv_sec);
1606    //Write datetime according to EXIF Spec
1607    //"YYYY:MM:DD HH:MM:SS" (20 chars including \0)
1608    snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d",
1609             timeinfo->tm_year + 1900, timeinfo->tm_mon + 1,
1610             timeinfo->tm_mday, timeinfo->tm_hour,
1611             timeinfo->tm_min, timeinfo->tm_sec);
1612    count = 20;
1613
1614    //Write subsec according to EXIF Sepc
1615    snprintf(subsecTime, 7, "%06ld", tv.tv_usec);
1616    subsecCount = 7;
1617    return NO_ERROR;
1618}
1619
1620/*===========================================================================
1621 * FUNCTION   : getExifFocalLength
1622 *
1623 * DESCRIPTION: get exif focal lenght
1624 *
1625 * PARAMETERS :
1626 *   @focalLength : ptr to rational strcut to store focal lenght
1627 *
1628 * RETURN     : int32_t type of status
1629 *              NO_ERROR  -- success
1630 *              none-zero failure code
1631 *==========================================================================*/
1632int32_t getExifFocalLength(rat_t *focalLength, float value)
1633{
1634    int focalLengthValue =
1635        (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION);
1636    return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION);
1637}
1638
1639/*===========================================================================
1640  * FUNCTION   : getExifExpTimeInfo
1641  *
1642  * DESCRIPTION: get exif exposure time information
1643  *
1644  * PARAMETERS :
1645  *   @expoTimeInfo     : expousure time value
1646  * RETURN     : nt32_t type of status
1647  *              NO_ERROR  -- success
1648  *              none-zero failure code
1649  *==========================================================================*/
1650int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value)
1651{
1652
1653    int cal_exposureTime;
1654    if (value != 0)
1655        cal_exposureTime = value;
1656    else
1657        cal_exposureTime = 60;
1658
1659    return getRational(expoTimeInfo, 1, cal_exposureTime);
1660}
1661
1662/*===========================================================================
1663 * FUNCTION   : getExifGpsProcessingMethod
1664 *
1665 * DESCRIPTION: get GPS processing method
1666 *
1667 * PARAMETERS :
1668 *   @gpsProcessingMethod : string to store GPS process method
1669 *   @count               : lenght of the string
1670 *
1671 * RETURN     : int32_t type of status
1672 *              NO_ERROR  -- success
1673 *              none-zero failure code
1674 *==========================================================================*/
1675int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod,
1676                                   uint32_t &count, char* value)
1677{
1678    if(value != NULL) {
1679        memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
1680        count = EXIF_ASCII_PREFIX_SIZE;
1681        strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value));
1682        count += strlen(value);
1683        gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char
1684        return NO_ERROR;
1685    } else {
1686        return BAD_VALUE;
1687    }
1688}
1689
1690/*===========================================================================
1691 * FUNCTION   : getExifLatitude
1692 *
1693 * DESCRIPTION: get exif latitude
1694 *
1695 * PARAMETERS :
1696 *   @latitude : ptr to rational struct to store latitude info
1697 *   @ladRef   : charater to indicate latitude reference
1698 *
1699 * RETURN     : int32_t type of status
1700 *              NO_ERROR  -- success
1701 *              none-zero failure code
1702 *==========================================================================*/
1703int32_t getExifLatitude(rat_t *latitude,
1704                                           char *latRef, double value)
1705{
1706    char str[30];
1707    snprintf(str, sizeof(str), "%f", value);
1708    if(str != NULL) {
1709        parseGPSCoordinate(str, latitude);
1710
1711        //set Latitude Ref
1712        float latitudeValue = strtof(str, 0);
1713        if(latitudeValue < 0.0f) {
1714            latRef[0] = 'S';
1715        } else {
1716            latRef[0] = 'N';
1717        }
1718        latRef[1] = '\0';
1719        return NO_ERROR;
1720    }else{
1721        return BAD_VALUE;
1722    }
1723}
1724
1725/*===========================================================================
1726 * FUNCTION   : getExifLongitude
1727 *
1728 * DESCRIPTION: get exif longitude
1729 *
1730 * PARAMETERS :
1731 *   @longitude : ptr to rational struct to store longitude info
1732 *   @lonRef    : charater to indicate longitude reference
1733 *
1734 * RETURN     : int32_t type of status
1735 *              NO_ERROR  -- success
1736 *              none-zero failure code
1737 *==========================================================================*/
1738int32_t getExifLongitude(rat_t *longitude,
1739                                            char *lonRef, double value)
1740{
1741    char str[30];
1742    snprintf(str, sizeof(str), "%f", value);
1743    if(str != NULL) {
1744        parseGPSCoordinate(str, longitude);
1745
1746        //set Longitude Ref
1747        float longitudeValue = strtof(str, 0);
1748        if(longitudeValue < 0.0f) {
1749            lonRef[0] = 'W';
1750        } else {
1751            lonRef[0] = 'E';
1752        }
1753        lonRef[1] = '\0';
1754        return NO_ERROR;
1755    }else{
1756        return BAD_VALUE;
1757    }
1758}
1759
1760/*===========================================================================
1761 * FUNCTION   : getExifAltitude
1762 *
1763 * DESCRIPTION: get exif altitude
1764 *
1765 * PARAMETERS :
1766 *   @altitude : ptr to rational struct to store altitude info
1767 *   @altRef   : charater to indicate altitude reference
1768 *
1769 * RETURN     : int32_t type of status
1770 *              NO_ERROR  -- success
1771 *              none-zero failure code
1772 *==========================================================================*/
1773int32_t getExifAltitude(rat_t *altitude,
1774                                           char *altRef, double value)
1775{
1776    char str[30];
1777    snprintf(str, sizeof(str), "%f", value);
1778    if(str != NULL) {
1779        double value = atof(str);
1780        *altRef = 0;
1781        if(value < 0){
1782            *altRef = 1;
1783            value = -value;
1784        }
1785        return getRational(altitude, value*1000, 1000);
1786    }else{
1787        return BAD_VALUE;
1788    }
1789}
1790
1791/*===========================================================================
1792 * FUNCTION   : getExifGpsDateTimeStamp
1793 *
1794 * DESCRIPTION: get exif GPS date time stamp
1795 *
1796 * PARAMETERS :
1797 *   @gpsDateStamp : GPS date time stamp string
1798 *   @bufLen       : length of the string
1799 *   @gpsTimeStamp : ptr to rational struct to store time stamp info
1800 *
1801 * RETURN     : int32_t type of status
1802 *              NO_ERROR  -- success
1803 *              none-zero failure code
1804 *==========================================================================*/
1805int32_t getExifGpsDateTimeStamp(char *gpsDateStamp,
1806                                           uint32_t bufLen,
1807                                           rat_t *gpsTimeStamp, int64_t value)
1808{
1809    char str[30];
1810    snprintf(str, sizeof(str), "%lld", value);
1811    if(str != NULL) {
1812        time_t unixTime = (time_t)atol(str);
1813        struct tm *UTCTimestamp = gmtime(&unixTime);
1814
1815        strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp);
1816
1817        getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1);
1818        getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1);
1819        getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1);
1820
1821        return NO_ERROR;
1822    } else {
1823        return BAD_VALUE;
1824    }
1825}
1826
1827int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp,
1828                             cam_rational_type_t step)
1829{
1830    exposure_val->num = exposure_comp * step.numerator;
1831    exposure_val->denom = step.denominator;
1832    return 0;
1833}
1834/*===========================================================================
1835 * FUNCTION   : getExifData
1836 *
1837 * DESCRIPTION: get exif data to be passed into jpeg encoding
1838 *
1839 * PARAMETERS : none
1840 *
1841 * RETURN     : exif data from user setting and GPS
1842 *==========================================================================*/
1843QCamera3Exif *QCamera3PicChannel::getExifData(metadata_buffer_t *metadata,
1844        jpeg_settings_t *jpeg_settings)
1845{
1846    QCamera3Exif *exif = new QCamera3Exif();
1847    if (exif == NULL) {
1848        ALOGE("%s: No memory for QCamera3Exif", __func__);
1849        return NULL;
1850    }
1851
1852    int32_t rc = NO_ERROR;
1853    uint32_t count = 0;
1854
1855    // add exif entries
1856    {
1857        char dateTime[20];
1858        char subsecTime[7];
1859        uint32_t subsecCount;
1860        memset(dateTime, 0, sizeof(dateTime));
1861        memset(subsecTime, 0, sizeof(subsecTime));
1862        count = 20;
1863        subsecCount = 7;
1864        rc = getExifDateTime(dateTime, subsecTime, count, subsecCount);
1865        if(rc == NO_ERROR) {
1866            exif->addEntry(EXIFTAGID_DATE_TIME,
1867                    EXIF_ASCII,
1868                    count,
1869                    (void *)dateTime);
1870            exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
1871                    EXIF_ASCII,
1872                    count,
1873                    (void *)dateTime);
1874            exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED,
1875                    EXIF_ASCII,
1876                    count,
1877                    (void *)dateTime);
1878            exif->addEntry(EXIFTAGID_SUBSEC_TIME,
1879                    EXIF_ASCII,
1880                    subsecCount,
1881                    (void *)subsecTime);
1882            exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL,
1883                    EXIF_ASCII,
1884                    subsecCount,
1885                    (void *)subsecTime);
1886            exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED,
1887                    EXIF_ASCII,
1888                    subsecCount,
1889                    (void *)subsecTime);
1890        } else {
1891            ALOGE("%s: getExifDateTime failed", __func__);
1892        }
1893    }
1894
1895    if (IS_PARAM_AVAILABLE(CAM_INTF_META_LENS_FOCAL_LENGTH, metadata)) {
1896        float focal_length = *(float *)POINTER_OF_PARAM(
1897                CAM_INTF_META_LENS_FOCAL_LENGTH, metadata);
1898        rat_t focalLength;
1899        rc = getExifFocalLength(&focalLength, focal_length);
1900        if (rc == NO_ERROR) {
1901            exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
1902                    EXIF_RATIONAL,
1903                    1,
1904                    (void *)&(focalLength));
1905        } else {
1906            ALOGE("%s: getExifFocalLength failed", __func__);
1907        }
1908    }
1909
1910    if (IS_PARAM_AVAILABLE(CAM_INTF_META_SENSOR_SENSITIVITY, metadata)) {
1911        int16_t isoSpeed = *(int32_t *)POINTER_OF_PARAM(
1912                CAM_INTF_META_SENSOR_SENSITIVITY, metadata);
1913        exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
1914                   EXIF_SHORT,
1915                   1,
1916                   (void *)&(isoSpeed));
1917    }
1918
1919    if (IS_PARAM_AVAILABLE(CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata)) {
1920        int64_t sensor_exposure_time = *(int64_t *)POINTER_OF_PARAM(
1921                CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata);
1922        rat_t sensorExpTime;
1923        rc = getExifExpTimeInfo(&sensorExpTime, sensor_exposure_time);
1924        if (rc == NO_ERROR){
1925            exif->addEntry(EXIFTAGID_EXPOSURE_TIME,
1926                    EXIF_RATIONAL,
1927                    1,
1928                    (void *)&(sensorExpTime));
1929        } else {
1930            ALOGE("%s: getExifExpTimeInfo failed", __func__);
1931        }
1932    }
1933
1934    if (strlen(jpeg_settings->gps_processing_method) > 0) {
1935        char gpsProcessingMethod[
1936                    EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
1937        count = 0;
1938        rc = getExifGpsProcessingMethod(gpsProcessingMethod,
1939                count, jpeg_settings->gps_processing_method);
1940        if(rc == NO_ERROR) {
1941            exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
1942                    EXIF_ASCII,
1943                    count,
1944                    (void *)gpsProcessingMethod);
1945        } else {
1946            ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
1947        }
1948    }
1949
1950    if (jpeg_settings->gps_coordinates_valid) {
1951
1952        //latitude
1953        rat_t latitude[3];
1954        char latRef[2];
1955        rc = getExifLatitude(latitude, latRef,
1956                jpeg_settings->gps_coordinates[0]);
1957        if(rc == NO_ERROR) {
1958            exif->addEntry(EXIFTAGID_GPS_LATITUDE,
1959                           EXIF_RATIONAL,
1960                           3,
1961                           (void *)latitude);
1962            exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
1963                           EXIF_ASCII,
1964                           2,
1965                           (void *)latRef);
1966        } else {
1967            ALOGE("%s: getExifLatitude failed", __func__);
1968        }
1969
1970        //longitude
1971        rat_t longitude[3];
1972        char lonRef[2];
1973        rc = getExifLongitude(longitude, lonRef,
1974                jpeg_settings->gps_coordinates[1]);
1975        if(rc == NO_ERROR) {
1976            exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
1977                           EXIF_RATIONAL,
1978                           3,
1979                           (void *)longitude);
1980
1981            exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
1982                           EXIF_ASCII,
1983                           2,
1984                           (void *)lonRef);
1985        } else {
1986            ALOGE("%s: getExifLongitude failed", __func__);
1987        }
1988
1989        //altitude
1990        rat_t altitude;
1991        char altRef;
1992        rc = getExifAltitude(&altitude, &altRef,
1993                jpeg_settings->gps_coordinates[2]);
1994        if(rc == NO_ERROR) {
1995            exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
1996                           EXIF_RATIONAL,
1997                           1,
1998                           (void *)&(altitude));
1999
2000            exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
2001                           EXIF_BYTE,
2002                           1,
2003                           (void *)&altRef);
2004        } else {
2005            ALOGE("%s: getExifAltitude failed", __func__);
2006        }
2007    }
2008
2009    if (jpeg_settings->gps_timestamp_valid) {
2010
2011        char gpsDateStamp[20];
2012        rat_t gpsTimeStamp[3];
2013        rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp,
2014                jpeg_settings->gps_timestamp);
2015        if(rc == NO_ERROR) {
2016            exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
2017                           EXIF_ASCII,
2018                           strlen(gpsDateStamp) + 1,
2019                           (void *)gpsDateStamp);
2020
2021            exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
2022                           EXIF_RATIONAL,
2023                           3,
2024                           (void *)gpsTimeStamp);
2025        } else {
2026            ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
2027        }
2028    }
2029
2030    if (IS_PARAM_AVAILABLE(CAM_INTF_PARM_EXPOSURE_COMPENSATION, metadata) &&
2031            IS_PARAM_AVAILABLE(CAM_INTF_PARM_EV_STEP, metadata)) {
2032        int32_t exposure_comp = *(int32_t *)POINTER_OF_PARAM(
2033                CAM_INTF_PARM_EXPOSURE_COMPENSATION, metadata);
2034        cam_rational_type_t comp_step = *(cam_rational_type_t *)POINTER_OF_PARAM(
2035                CAM_INTF_PARM_EV_STEP, metadata);
2036        srat_t exposure_val;
2037        rc = getExifExposureValue(&exposure_val, exposure_comp, comp_step);
2038        if(rc == NO_ERROR) {
2039            exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE,
2040                       EXIF_SRATIONAL,
2041                       1,
2042                       (void *)(&exposure_val));
2043        } else {
2044            ALOGE("%s: getExifExposureValue failed ", __func__);
2045        }
2046    }
2047
2048    char value[PROPERTY_VALUE_MAX];
2049    if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
2050        exif->addEntry(EXIFTAGID_MAKE,
2051                       EXIF_ASCII,
2052                       strlen(value) + 1,
2053                       (void *)value);
2054    } else {
2055        ALOGE("%s: getExifMaker failed", __func__);
2056    }
2057
2058    if (property_get("ro.product.model", value, "QCAM-AA") > 0) {
2059        exif->addEntry(EXIFTAGID_MODEL,
2060                       EXIF_ASCII,
2061                       strlen(value) + 1,
2062                       (void *)value);
2063    } else {
2064        ALOGE("%s: getExifModel failed", __func__);
2065    }
2066
2067    return exif;
2068}
2069
2070int QCamera3PicChannel::kMaxBuffers = 1;
2071
2072void QCamera3PicChannel::overrideYuvSize(uint32_t width, uint32_t height)
2073{
2074   mYuvWidth = width;
2075   mYuvHeight = height;
2076}
2077
2078/*===========================================================================
2079 * FUNCTION   : QCamera3ReprocessChannel
2080 *
2081 * DESCRIPTION: constructor of QCamera3ReprocessChannel
2082 *
2083 * PARAMETERS :
2084 *   @cam_handle : camera handle
2085 *   @cam_ops    : ptr to camera ops table
2086 *   @pp_mask    : post-proccess feature mask
2087 *
2088 * RETURN     : none
2089 *==========================================================================*/
2090QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle,
2091                                                 mm_camera_ops_t *cam_ops,
2092                                                 channel_cb_routine cb_routine,
2093                                                 cam_padding_info_t *paddingInfo,
2094                                                 void *userData, void *ch_hdl) :
2095    QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData),
2096    picChHandle(ch_hdl),
2097    m_pSrcChannel(NULL),
2098    m_pMetaChannel(NULL),
2099    mMemory(NULL)
2100{
2101    memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
2102}
2103
2104
2105/*===========================================================================
2106 * FUNCTION   : QCamera3ReprocessChannel
2107 *
2108 * DESCRIPTION: constructor of QCamera3ReprocessChannel
2109 *
2110 * PARAMETERS :
2111 *   @cam_handle : camera handle
2112 *   @cam_ops    : ptr to camera ops table
2113 *   @pp_mask    : post-proccess feature mask
2114 *
2115 * RETURN     : none
2116 *==========================================================================*/
2117int32_t QCamera3ReprocessChannel::initialize()
2118{
2119    int32_t rc = NO_ERROR;
2120    mm_camera_channel_attr_t attr;
2121
2122    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
2123    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
2124    attr.max_unmatched_frames = 1;
2125
2126    rc = init(&attr, NULL);
2127    if (rc < 0) {
2128        ALOGE("%s: init failed", __func__);
2129    }
2130    return rc;
2131}
2132
2133
2134/*===========================================================================
2135 * FUNCTION   : QCamera3ReprocessChannel
2136 *
2137 * DESCRIPTION: constructor of QCamera3ReprocessChannel
2138 *
2139 * PARAMETERS :
2140 *   @cam_handle : camera handle
2141 *   @cam_ops    : ptr to camera ops table
2142 *   @pp_mask    : post-proccess feature mask
2143 *
2144 * RETURN     : none
2145 *==========================================================================*/
2146void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
2147                                  QCamera3Stream *stream)
2148{
2149    //Got the pproc data callback. Now send to jpeg encoding
2150    uint8_t frameIndex;
2151    mm_camera_super_buf_t* frame = NULL;
2152    QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle;
2153
2154    if(!super_frame) {
2155         ALOGE("%s: Invalid Super buffer",__func__);
2156         return;
2157    }
2158
2159    if(super_frame->num_bufs != 1) {
2160         ALOGE("%s: Multiple streams are not supported",__func__);
2161         return;
2162    }
2163    if(super_frame->bufs[0] == NULL ) {
2164         ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
2165                  __func__);
2166         return;
2167    }
2168
2169    frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
2170    frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
2171    if (frame == NULL) {
2172       ALOGE("%s: Error allocating memory to save received_frame structure.",
2173                                                                    __func__);
2174       if(stream) {
2175           stream->bufDone(frameIndex);
2176       }
2177       return;
2178    }
2179    *frame = *super_frame;
2180    obj->m_postprocessor.processPPData(frame);
2181    free(super_frame);
2182    return;
2183}
2184
2185/*===========================================================================
2186 * FUNCTION   : QCamera3ReprocessChannel
2187 *
2188 * DESCRIPTION: default constructor of QCamera3ReprocessChannel
2189 *
2190 * PARAMETERS : none
2191 *
2192 * RETURN     : none
2193 *==========================================================================*/
2194QCamera3ReprocessChannel::QCamera3ReprocessChannel() :
2195    m_pSrcChannel(NULL),
2196    m_pMetaChannel(NULL)
2197{
2198}
2199
2200/*===========================================================================
2201 * FUNCTION   : getStreamBufs
2202 *
2203 * DESCRIPTION: register the buffers of the reprocess channel
2204 *
2205 * PARAMETERS : none
2206 *
2207 * RETURN     : QCamera3Memory *
2208 *==========================================================================*/
2209QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len)
2210{
2211   int rc = 0;
2212
2213    mMemory = new QCamera3HeapMemory();
2214    if (!mMemory) {
2215        ALOGE("%s: unable to create reproc memory", __func__);
2216        return NULL;
2217    }
2218
2219    //Queue YUV buffers in the beginning mQueueAll = true
2220    rc = mMemory->allocate(2, len, true);
2221    if (rc < 0) {
2222        ALOGE("%s: unable to allocate reproc memory", __func__);
2223        delete mMemory;
2224        mMemory = NULL;
2225        return NULL;
2226    }
2227    return mMemory;
2228}
2229
2230/*===========================================================================
2231 * FUNCTION   : getStreamBufs
2232 *
2233 * DESCRIPTION: register the buffers of the reprocess channel
2234 *
2235 * PARAMETERS : none
2236 *
2237 * RETURN     :
2238 *==========================================================================*/
2239void QCamera3ReprocessChannel::putStreamBufs()
2240{
2241    mMemory->deallocate();
2242    delete mMemory;
2243    mMemory = NULL;
2244}
2245
2246/*===========================================================================
2247 * FUNCTION   : ~QCamera3ReprocessChannel
2248 *
2249 * DESCRIPTION: destructor of QCamera3ReprocessChannel
2250 *
2251 * PARAMETERS : none
2252 *
2253 * RETURN     : none
2254 *==========================================================================*/
2255QCamera3ReprocessChannel::~QCamera3ReprocessChannel()
2256{
2257}
2258
2259/*===========================================================================
2260 * FUNCTION   : getStreamBySrcHandle
2261 *
2262 * DESCRIPTION: find reprocess stream by its source stream handle
2263 *
2264 * PARAMETERS :
2265 *   @srcHandle : source stream handle
2266 *
2267 * RETURN     : ptr to reprocess stream if found. NULL if not found
2268 *==========================================================================*/
2269QCamera3Stream * QCamera3ReprocessChannel::getStreamBySrcHandle(uint32_t srcHandle)
2270{
2271    QCamera3Stream *pStream = NULL;
2272
2273    for (int i = 0; i < m_numStreams; i++) {
2274        if (mSrcStreamHandles[i] == srcHandle) {
2275            pStream = mStreams[i];
2276            break;
2277        }
2278    }
2279    return pStream;
2280}
2281
2282/*===========================================================================
2283 * FUNCTION   : getSrcStreamBySrcHandle
2284 *
2285 * DESCRIPTION: find source stream by source stream handle
2286 *
2287 * PARAMETERS :
2288 *   @srcHandle : source stream handle
2289 *
2290 * RETURN     : ptr to reprocess stream if found. NULL if not found
2291 *==========================================================================*/
2292QCamera3Stream * QCamera3ReprocessChannel::getSrcStreamBySrcHandle(uint32_t srcHandle)
2293{
2294    QCamera3Stream *pStream = NULL;
2295
2296    for (int i = 0; i < m_numStreams; i++) {
2297        if (mSrcStreamHandles[i] == srcHandle) {
2298            pStream = m_pSrcChannel->getStreamByIndex(i);
2299            break;
2300        }
2301    }
2302    return pStream;
2303}
2304
2305/*===========================================================================
2306 * FUNCTION   : doReprocess
2307 *
2308 * DESCRIPTION: request to do a reprocess on the frame
2309 *
2310 * PARAMETERS :
2311 *   @frame   : frame to be performed a reprocess
2312 *
2313 * RETURN     : int32_t type of status
2314 *              NO_ERROR  -- success
2315 *              none-zero failure code
2316 *==========================================================================*/
2317int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
2318                                              mm_camera_super_buf_t *meta_frame)
2319{
2320    int32_t rc = 0;
2321    if (m_numStreams < 1) {
2322        ALOGE("%s: No reprocess stream is created", __func__);
2323        return -1;
2324    }
2325    if (m_pSrcChannel == NULL) {
2326        ALOGE("%s: No source channel for reprocess", __func__);
2327        return -1;
2328    }
2329    for (int i = 0; i < frame->num_bufs; i++) {
2330        QCamera3Stream *pStream = getStreamBySrcHandle(frame->bufs[i]->stream_id);
2331        if (pStream != NULL) {
2332            cam_stream_parm_buffer_t param;
2333            memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
2334            param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
2335            param.reprocess.buf_index = frame->bufs[i]->buf_idx;
2336            param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
2337            param.reprocess.frame_pp_config.uv_upsample =
2338                    frame->bufs[i]->is_uv_subsampled;
2339            if (meta_frame != NULL) {
2340               param.reprocess.meta_present = 1;
2341               param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID();
2342               param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx;
2343            }
2344            rc = pStream->setParameter(param);
2345            if (rc != NO_ERROR) {
2346                ALOGE("%s: stream setParameter for reprocess failed", __func__);
2347                break;
2348            }
2349        }
2350    }
2351    return rc;
2352}
2353
2354int32_t QCamera3ReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame,
2355        metadata_buffer_t *metadata)
2356{
2357    int32_t rc = 0;
2358    if (m_numStreams < 1) {
2359        ALOGE("%s: No reprocess stream is created", __func__);
2360        return -1;
2361    }
2362    if (m_pSrcChannel == NULL) {
2363        ALOGE("%s: No source channel for reprocess", __func__);
2364        return -1;
2365    }
2366
2367    uint32_t buf_idx = 0;
2368    for (int i = 0; i < frame->num_bufs; i++) {
2369        QCamera3Stream *pStream = getStreamBySrcHandle(frame->bufs[i]->stream_id);
2370        QCamera3Stream *pSrcStream = getSrcStreamBySrcHandle(frame->bufs[i]->stream_id);
2371        if (pStream != NULL && pSrcStream != NULL) {
2372
2373            rc = mStreams[i]->mapBuf(
2374                    CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
2375                    buf_idx, -1,
2376                    frame->bufs[i]->fd, frame->bufs[i]->frame_len);
2377
2378            if (rc == NO_ERROR) {
2379                cam_stream_parm_buffer_t param;
2380                memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
2381                param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
2382                param.reprocess.buf_index = frame->bufs[i]->buf_idx;
2383
2384                param.reprocess.meta_present = 1;
2385                char* private_data = (char *)POINTER_OF_PARAM(
2386                        CAM_INTF_META_PRIVATE_DATA, metadata);
2387                memcpy(param.reprocess.private_data, private_data,
2388                        MAX_METADATA_PRIVATE_PAYLOAD_SIZE);
2389
2390                // Find crop info for reprocess stream
2391                cam_crop_data_t *crop_data = (cam_crop_data_t *)
2392                        POINTER_OF_PARAM(CAM_INTF_META_CROP_DATA, metadata);
2393                for (int j = 0; j < crop_data->num_of_streams; j++) {
2394                    if (crop_data->crop_info[j].stream_id ==
2395                           pSrcStream->getMyServerID()) {
2396                        param.reprocess.crop_rect  =
2397                                crop_data->crop_info[j].crop;
2398                        break;
2399                    }
2400                }
2401                rc = pStream->setParameter(param);
2402                if (rc != NO_ERROR) {
2403                    ALOGE("%s: stream setParameter for reprocess failed", __func__);
2404                    break;
2405                }
2406            }
2407        }
2408    }
2409    return rc;
2410}
2411
2412
2413/*===========================================================================
2414 * FUNCTION   : doReprocess
2415 *
2416 * DESCRIPTION: request to do a reprocess on the frame
2417 *
2418 * PARAMETERS :
2419 *   @buf_fd     : fd to the input buffer that needs reprocess
2420 *   @buf_lenght : length of the input buffer
2421 *   @ret_val    : result of reprocess.
2422 *                 Example: Could be faceID in case of register face image.
2423 *
2424 * RETURN     : int32_t type of status
2425 *              NO_ERROR  -- success
2426 *              none-zero failure code
2427 *==========================================================================*/
2428int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd,
2429                                              uint32_t buf_length,
2430                                              int32_t &ret_val,
2431                                              mm_camera_super_buf_t *meta_frame)
2432{
2433    int32_t rc = 0;
2434    if (m_numStreams < 1) {
2435        ALOGE("%s: No reprocess stream is created", __func__);
2436        return -1;
2437    }
2438    if (meta_frame == NULL) {
2439        ALOGE("%s: Did not get corresponding metadata in time", __func__);
2440        return -1;
2441    }
2442
2443    uint32_t buf_idx = 0;
2444    for (int i = 0; i < m_numStreams; i++) {
2445        rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
2446                                 buf_idx, -1,
2447                                 buf_fd, buf_length);
2448
2449        if (rc == NO_ERROR) {
2450            cam_stream_parm_buffer_t param;
2451            memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
2452            param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
2453            param.reprocess.buf_index = buf_idx;
2454            param.reprocess.meta_present = 1;
2455            param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID();
2456            param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx;
2457            rc = mStreams[i]->setParameter(param);
2458            if (rc == NO_ERROR) {
2459                ret_val = param.reprocess.ret_val;
2460            }
2461            mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
2462                                  buf_idx, -1);
2463        }
2464    }
2465    return rc;
2466}
2467
2468/*===========================================================================
2469 * FUNCTION   : addReprocStreamsFromSource
2470 *
2471 * DESCRIPTION: add reprocess streams from input source channel
2472 *
2473 * PARAMETERS :
2474 *   @config         : pp feature configuration
2475 *   @pSrcChannel    : ptr to input source channel that needs reprocess
2476 *   @pMetaChannel   : ptr to metadata channel to get corresp. metadata
2477 *   @offline        : configure for offline reprocessing
2478 *
2479 * RETURN     : int32_t type of status
2480 *              NO_ERROR  -- success
2481 *              none-zero failure code
2482 *==========================================================================*/
2483int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &pp_config,
2484                                                             QCamera3Channel *pSrcChannel,
2485                                                             QCamera3Channel *pMetaChannel)
2486{
2487    int32_t rc = 0;
2488    QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0);
2489    if (pSrcStream == NULL) {
2490       ALOGE("%s: source channel doesn't have a stream", __func__);
2491       return BAD_VALUE;
2492    }
2493    cam_stream_reproc_config_t reprocess_config;
2494    cam_dimension_t streamDim;
2495    cam_stream_type_t streamType;
2496    cam_format_t streamFormat;
2497    cam_frame_len_offset_t frameOffset;
2498    int num_buffers = 2;
2499
2500    streamType = CAM_STREAM_TYPE_OFFLINE_PROC;
2501    pSrcStream->getFormat(streamFormat);
2502    pSrcStream->getFrameDimension(streamDim);
2503    pSrcStream->getFrameOffset(frameOffset);
2504    reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
2505
2506    reprocess_config.offline.input_fmt = streamFormat;
2507    reprocess_config.offline.input_dim = streamDim;
2508    reprocess_config.offline.input_buf_planes.plane_info = frameOffset;
2509    reprocess_config.offline.num_of_bufs = num_buffers;
2510    reprocess_config.offline.input_type = pSrcStream->getMyType();
2511
2512
2513    reprocess_config.pp_feature_config = pp_config;
2514    mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle();
2515
2516    // pp feature config
2517    if (pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
2518        if (pp_config.rotation == ROTATE_90 ||
2519            pp_config.rotation == ROTATE_270) {
2520            // rotated by 90 or 270, need to switch width and height
2521            int32_t temp = streamDim.height;
2522            streamDim.height = streamDim.width;
2523            streamDim.width = temp;
2524        }
2525    }
2526
2527    QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
2528                                               m_handle,
2529                                               m_camOps,
2530                                               mPaddingInfo,
2531                                               (QCamera3Channel*)this);
2532    if (pStream == NULL) {
2533        ALOGE("%s: No mem for Stream", __func__);
2534        return NO_MEMORY;
2535    }
2536
2537    rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config,
2538                       num_buffers,QCamera3Channel::streamCbRoutine, this);
2539
2540
2541    if (rc == 0) {
2542        mStreams[m_numStreams] = pStream;
2543        m_numStreams++;
2544    } else {
2545        ALOGE("%s: failed to create reprocess stream", __func__);
2546        delete pStream;
2547    }
2548
2549    if (rc == NO_ERROR) {
2550        m_pSrcChannel = pSrcChannel;
2551        m_pMetaChannel = pMetaChannel;
2552    }
2553    if(m_camOps->request_super_buf(m_camHandle,m_handle,1,0) < 0) {
2554        ALOGE("%s: Request for super buffer failed",__func__);
2555    }
2556    return rc;
2557}
2558
2559
2560}; // namespace qcamera
2561