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