QCamera3Channel.cpp revision f2fc1625456303cb52ec068d25308229e4322d4c
1/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6*     * Redistributions of source code must retain the above copyright
7*       notice, this list of conditions and the following disclaimer.
8*     * Redistributions in binary form must reproduce the above
9*       copyright notice, this list of conditions and the following
10*       disclaimer in the documentation and/or other materials provided
11*       with the distribution.
12*     * Neither the name of The Linux Foundation nor the names of its
13*       contributors may be used to endorse or promote products derived
14*       from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29
30#define LOG_TAG "QCamera3Channel"
31
32#include <stdlib.h>
33#include <cstdlib>
34#include <stdio.h>
35#include <string.h>
36#include <hardware/camera3.h>
37#include <system/camera_metadata.h>
38#include <gralloc_priv.h>
39#include <utils/Log.h>
40#include <utils/Errors.h>
41#include "QCamera3Channel.h"
42
43using namespace android;
44
45#define MIN_STREAMING_BUFFER_NUM 3
46
47namespace qcamera {
48static const char ExifAsciiPrefix[] =
49    { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };          // "ASCII\0\0\0"
50static const char ExifUndefinedPrefix[] =
51    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };   // "\0\0\0\0\0\0\0\0"
52
53#define GPS_PROCESSING_METHOD_SIZE       101
54#define EXIF_ASCII_PREFIX_SIZE           8   //(sizeof(ExifAsciiPrefix))
55#define FOCAL_LENGTH_DECIMAL_PRECISION   100
56
57/*===========================================================================
58 * FUNCTION   : QCamera3Channel
59 *
60 * DESCRIPTION: constrcutor of QCamera3Channel
61 *
62 * PARAMETERS :
63 *   @cam_handle : camera handle
64 *   @cam_ops    : ptr to camera ops table
65 *
66 * RETURN     : none
67 *==========================================================================*/
68QCamera3Channel::QCamera3Channel(uint32_t cam_handle,
69                               mm_camera_ops_t *cam_ops,
70                               channel_cb_routine cb_routine,
71                               cam_padding_info_t *paddingInfo,
72                               void *userData)
73{
74    m_camHandle = cam_handle;
75    m_camOps = cam_ops;
76    mChannelCB = cb_routine;
77    mPaddingInfo = paddingInfo;
78    mUserData = userData;
79    m_bIsActive = false;
80
81    m_handle = 0;
82    m_numStreams = 0;
83    memset(mStreams, 0, sizeof(mStreams));
84}
85
86/*===========================================================================
87 * FUNCTION   : QCamera3Channel
88 *
89 * DESCRIPTION: default constrcutor of QCamera3Channel
90 *
91 * PARAMETERS : none
92 *
93 * RETURN     : none
94 *==========================================================================*/
95QCamera3Channel::QCamera3Channel()
96{
97    m_camHandle = 0;
98    m_camOps = NULL;
99    mPaddingInfo = NULL;
100    mUserData = NULL;
101    m_bIsActive = false;
102
103    m_handle = 0;
104    m_numStreams = 0;
105    memset(mStreams, 0, sizeof(mStreams));
106}
107
108/*===========================================================================
109 * FUNCTION   : ~QCamera3Channel
110 *
111 * DESCRIPTION: destructor of QCamera3Channel
112 *
113 * PARAMETERS : none
114 *
115 * RETURN     : none
116 *==========================================================================*/
117QCamera3Channel::~QCamera3Channel()
118{
119    if (m_bIsActive)
120        stop();
121
122    for (int i = 0; i < m_numStreams; i++) {
123        if (mStreams[i] != NULL) {
124            delete mStreams[i];
125            mStreams[i] = 0;
126        }
127    }
128    m_numStreams = 0;
129    m_camOps->delete_channel(m_camHandle, m_handle);
130    m_handle = 0;
131}
132
133/*===========================================================================
134 * FUNCTION   : init
135 *
136 * DESCRIPTION: initialization of channel
137 *
138 * PARAMETERS :
139 *   @attr    : channel bundle attribute setting
140 *   @dataCB  : data notify callback
141 *   @userData: user data ptr
142 *
143 * RETURN     : int32_t type of status
144 *              NO_ERROR  -- success
145 *              none-zero failure code
146 *==========================================================================*/
147int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr,
148                             mm_camera_buf_notify_t dataCB)
149{
150    m_handle = m_camOps->add_channel(m_camHandle,
151                                      attr,
152                                      dataCB,
153                                      this);
154    if (m_handle == 0) {
155        ALOGE("%s: Add channel failed", __func__);
156        return UNKNOWN_ERROR;
157    }
158    return NO_ERROR;
159}
160
161/*===========================================================================
162 * FUNCTION   : addStream
163 *
164 * DESCRIPTION: add a stream into channel
165 *
166 * PARAMETERS :
167 *   @allocator      : stream related buffer allocator
168 *   @streamInfoBuf  : ptr to buf that constains stream info
169 *   @minStreamBufNum: number of stream buffers needed
170 *   @paddingInfo    : padding information
171 *   @stream_cb      : stream data notify callback
172 *   @userdata       : user data ptr
173 *
174 * RETURN     : int32_t type of status
175 *              NO_ERROR  -- success
176 *              none-zero failure code
177 *==========================================================================*/
178int32_t QCamera3Channel::addStream(cam_stream_type_t streamType,
179                                  cam_format_t streamFormat,
180                                  cam_dimension_t streamDim,
181                                  uint8_t minStreamBufNum)
182{
183    int32_t rc = NO_ERROR;
184
185    if (m_numStreams >= 1) {
186        ALOGE("%s: Only one stream per channel supported in v3 Hal", __func__);
187        return BAD_VALUE;
188    }
189
190    if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
191        ALOGE("%s: stream number (%d) exceeds max limit (%d)",
192              __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
193        return BAD_VALUE;
194    }
195    QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
196                                               m_handle,
197                                               m_camOps,
198                                               mPaddingInfo,
199                                               this);
200    if (pStream == NULL) {
201        ALOGE("%s: No mem for Stream", __func__);
202        return NO_MEMORY;
203    }
204
205    rc = pStream->init(streamType, streamFormat, streamDim, minStreamBufNum,
206                                                    streamCbRoutine, this);
207    if (rc == 0) {
208        mStreams[m_numStreams] = pStream;
209        m_numStreams++;
210    } else {
211        delete pStream;
212    }
213    return rc;
214}
215
216/*===========================================================================
217 * FUNCTION   : start
218 *
219 * DESCRIPTION: start channel, which will start all streams belong to this channel
220 *
221 * PARAMETERS :
222 *
223 * RETURN     : int32_t type of status
224 *              NO_ERROR  -- success
225 *              none-zero failure code
226 *==========================================================================*/
227int32_t QCamera3Channel::start()
228{
229    int32_t rc = NO_ERROR;
230
231    if (m_numStreams > 1) {
232        ALOGE("%s: bundle not supported", __func__);
233    }
234
235    for (int i = 0; i < m_numStreams; i++) {
236        if (mStreams[i] != NULL) {
237            mStreams[i]->start();
238        }
239    }
240    rc = m_camOps->start_channel(m_camHandle, m_handle);
241
242    if (rc != NO_ERROR) {
243        for (int i = 0; i < m_numStreams; i++) {
244            if (mStreams[i] != NULL) {
245                mStreams[i]->stop();
246            }
247        }
248    } else {
249        m_bIsActive = true;
250    }
251
252    return rc;
253}
254
255/*===========================================================================
256 * FUNCTION   : stop
257 *
258 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
259 *
260 * PARAMETERS : none
261 *
262 * RETURN     : int32_t type of status
263 *              NO_ERROR  -- success
264 *              none-zero failure code
265 *==========================================================================*/
266int32_t QCamera3Channel::stop()
267{
268    int32_t rc = NO_ERROR;
269    rc = m_camOps->stop_channel(m_camHandle, m_handle);
270
271    for (int i = 0; i < m_numStreams; i++) {
272        if (mStreams[i] != NULL) {
273            mStreams[i]->stop();
274        }
275    }
276
277    m_bIsActive = false;
278    return rc;
279}
280
281/*===========================================================================
282 * FUNCTION   : bufDone
283 *
284 * DESCRIPTION: return a stream buf back to kernel
285 *
286 * PARAMETERS :
287 *   @recvd_frame  : stream buf frame to be returned
288 *
289 * RETURN     : int32_t type of status
290 *              NO_ERROR  -- success
291 *              none-zero failure code
292 *==========================================================================*/
293int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame)
294{
295    int32_t rc = NO_ERROR;
296    for (int i = 0; i < recvd_frame->num_bufs; i++) {
297         if (recvd_frame->bufs[i] != NULL) {
298             for (int j = 0; j < m_numStreams; j++) {
299                 if (mStreams[j] != NULL &&
300                     mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
301                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
302                     break; // break loop j
303                 }
304             }
305         }
306    }
307
308    return rc;
309}
310
311/*===========================================================================
312 * FUNCTION   : getStreamByHandle
313 *
314 * DESCRIPTION: return stream object by stream handle
315 *
316 * PARAMETERS :
317 *   @streamHandle : stream handle
318 *
319 * RETURN     : stream object. NULL if not found
320 *==========================================================================*/
321QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle)
322{
323    for (int i = 0; i < m_numStreams; i++) {
324        if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
325            return mStreams[i];
326        }
327    }
328    return NULL;
329}
330
331/*===========================================================================
332 * FUNCTION   : getStreamByHandle
333 *
334 * DESCRIPTION: return stream object by stream handle
335 *
336 * PARAMETERS :
337 *   @streamHandle : stream handle
338 *
339 * RETURN     : stream object. NULL if not found
340 *==========================================================================*/
341QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index)
342{
343    if (index < m_numStreams) {
344        return mStreams[index];
345    }
346    return NULL;
347}
348
349/*===========================================================================
350 * FUNCTION   : streamCbRoutine
351 *
352 * DESCRIPTION: callback routine for stream
353 *
354 * PARAMETERS :
355 *   @streamHandle : stream handle
356 *
357 * RETURN     : stream object. NULL if not found
358 *==========================================================================*/
359void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
360                QCamera3Stream *stream, void *userdata)
361{
362    QCamera3Channel *channel = (QCamera3Channel *)userdata;
363    if (channel == NULL) {
364        ALOGE("%s: invalid channel pointer", __func__);
365        return;
366    }
367    channel->streamCbRoutine(super_frame, stream);
368}
369
370/*===========================================================================
371 * FUNCTION   : QCamera3RegularChannel
372 *
373 * DESCRIPTION: constrcutor of QCamera3RegularChannel
374 *
375 * PARAMETERS :
376 *   @cam_handle : camera handle
377 *   @cam_ops    : ptr to camera ops table
378 *   @cb_routine : callback routine to frame aggregator
379 *   @stream     : camera3_stream_t structure
380 *
381 * RETURN     : none
382 *==========================================================================*/
383QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
384                    mm_camera_ops_t *cam_ops,
385                    channel_cb_routine cb_routine,
386                    cam_padding_info_t *paddingInfo,
387                    void *userData,
388                    camera3_stream_t *stream) :
389                        QCamera3Channel(cam_handle, cam_ops, cb_routine,
390                                                paddingInfo, userData),
391                        mCamera3Stream(stream),
392                        mNumBufs(0),
393                        mCamera3Buffers(NULL),
394                        mMemory(NULL)
395{
396}
397
398/*===========================================================================
399 * FUNCTION   : ~QCamera3RegularChannel
400 *
401 * DESCRIPTION: destructor of QCamera3RegularChannel
402 *
403 * PARAMETERS : none
404 *
405 * RETURN     : none
406 *==========================================================================*/
407QCamera3RegularChannel::~QCamera3RegularChannel()
408{
409    if (mCamera3Buffers) {
410        delete[] mCamera3Buffers;
411    }
412}
413
414int32_t QCamera3RegularChannel::initialize()
415{
416  //TO DO
417  return 0;
418}
419
420/*===========================================================================
421 * FUNCTION   : request
422 *
423 * DESCRIPTION: process a request from camera service. Stream on if ncessary.
424 *
425 * PARAMETERS :
426 *   @buffer  : buffer to be filled for this request
427 *
428 * RETURN     : 0 on a success start of capture
429 *              -EINVAL on invalid input
430 *              -ENODEV on serious error
431 *==========================================================================*/
432int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber)
433{
434    //FIX ME: Return buffer back in case of failures below.
435
436    int32_t rc = NO_ERROR;
437    int index;
438    if(!m_bIsActive) {
439        ALOGD("%s: First request on this channel starting stream",__func__);
440        start();
441        if(rc != NO_ERROR) {
442            ALOGE("%s: Failed to start the stream on the request",__func__);
443            return rc;
444        }
445    } else {
446        ALOGV("%s: Request on an existing stream",__func__);
447    }
448
449    if(!mMemory) {
450        ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__);
451        return NO_MEMORY;
452    }
453
454    index = mMemory->getMatchBufIndex((void*)buffer);
455    if(index < 0) {
456        ALOGE("%s: Could not find object among registered buffers",__func__);
457        return DEAD_OBJECT;
458    }
459
460    rc = mStreams[0]->bufDone(index);
461    if(rc != NO_ERROR) {
462        ALOGE("%s: Failed to Q new buffer to stream",__func__);
463        return rc;
464    }
465
466    rc = mMemory->markFrameNumber(index, frameNumber);
467    return rc;
468}
469
470/*===========================================================================
471 * FUNCTION   : registerBuffers
472 *
473 * DESCRIPTION: register streaming buffers to the channel object
474 *
475 * PARAMETERS :
476 *   @num_buffers : number of buffers to be registered
477 *   @buffers     : buffer to be registered
478 *
479 * RETURN     : 0 on a success start of capture
480 *              -EINVAL on invalid input
481 *              -ENOMEM on failure to register the buffer
482 *              -ENODEV on serious error
483 *==========================================================================*/
484int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
485{
486    int rc = 0;
487    struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]);
488    cam_stream_type_t streamType;
489    cam_format_t streamFormat;
490    cam_dimension_t streamDim;
491
492    rc = init(NULL, NULL);
493    if (rc < 0) {
494        ALOGE("%s: init failed", __func__);
495        return rc;
496    }
497
498    if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
499        if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
500            streamType = CAM_STREAM_TYPE_VIDEO;
501            streamFormat = CAM_FORMAT_YUV_420_NV12;
502        } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_HW_TEXTURE) {
503            streamType = CAM_STREAM_TYPE_PREVIEW;
504            streamFormat = CAM_FORMAT_YUV_420_NV21;
505        } else {
506            ALOGE("%s: priv_handle->flags 0x%x not supported",
507                    __func__, priv_handle->flags);
508            return -EINVAL;
509        }
510    } else {
511        //TODO: Fail for other types of streams for now
512        ALOGE("%s: format is not IMPLEMENTATION_DEFINED", __func__);
513        return -EINVAL;
514    }
515
516    /* Bookkeep buffer set because they go out of scope after register call */
517    mNumBufs = num_buffers;
518    mCamera3Buffers = new buffer_handle_t*[num_buffers];
519    if (mCamera3Buffers == NULL) {
520        ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
521        return -ENOMEM;
522    }
523    for (size_t i = 0; i < num_buffers; i++)
524        mCamera3Buffers[i] = buffers[i];
525
526    streamDim.width = mCamera3Stream->width;
527    streamDim.height = mCamera3Stream->height;
528    rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
529        num_buffers);
530    return rc;
531}
532
533void QCamera3RegularChannel::streamCbRoutine(
534                            mm_camera_super_buf_t *super_frame,
535                            QCamera3Stream *stream)
536{
537    //FIXME Q Buf back in case of error?
538    uint8_t frameIndex;
539    buffer_handle_t *resultBuffer;
540    int32_t resultFrameNumber;
541    camera3_stream_buffer_t result;
542
543    if(!super_frame) {
544         ALOGE("%s: Invalid Super buffer",__func__);
545         return;
546    }
547
548    if(super_frame->num_bufs != 1) {
549         ALOGE("%s: Multiple streams are not supported",__func__);
550         return;
551    }
552    if(super_frame->bufs[0] == NULL ) {
553         ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
554                  __func__);
555         return;
556    }
557
558    frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
559    if(frameIndex >= mNumBufs) {
560         ALOGE("%s: Error, Invalid index for buffer",__func__);
561         if(stream) {
562             stream->bufDone(frameIndex);
563         }
564         return;
565    }
566
567    ////Use below data to issue framework callback
568    resultBuffer = mCamera3Buffers[frameIndex];
569    resultFrameNumber = mMemory->getFrameNumber(frameIndex);
570
571    result.stream = mCamera3Stream;
572    result.buffer = resultBuffer;
573    result.status = CAMERA3_BUFFER_STATUS_OK;
574    result.acquire_fence = -1;
575    result.release_fence = -1;
576
577    mChannelCB(NULL, &result, resultFrameNumber, mUserData);
578    return;
579}
580
581QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t len)
582{
583    if (mNumBufs == 0 || mCamera3Buffers == NULL) {
584        ALOGE("%s: buffers not registered yet", __func__);
585        return NULL;
586    }
587
588    mMemory = new QCamera3GrallocMemory();
589    if (mMemory == NULL) {
590        return NULL;
591    }
592
593    if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
594        delete mMemory;
595        mMemory = NULL;
596        return NULL;
597    }
598    return mMemory;
599}
600
601void QCamera3RegularChannel::putStreamBufs()
602{
603    mMemory->unregisterBuffers();
604    delete mMemory;
605    mMemory = NULL;
606}
607
608int QCamera3RegularChannel::kMaxBuffers = 7;
609
610QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle,
611                    mm_camera_ops_t *cam_ops,
612                    channel_cb_routine cb_routine,
613                    cam_padding_info_t *paddingInfo,
614                    void *userData) :
615                        QCamera3Channel(cam_handle, cam_ops,
616                                cb_routine, paddingInfo, userData),
617                        mMemory(NULL)
618{
619#ifdef FAKE_FRAME_NUMBERS
620    startingFrameNumber=0;
621#endif
622}
623
624QCamera3MetadataChannel::~QCamera3MetadataChannel()
625{
626    if (m_bIsActive)
627        stop();
628
629    if (mMemory) {
630        mMemory->deallocate();
631        delete mMemory;
632        mMemory = NULL;
633    }
634}
635
636int32_t QCamera3MetadataChannel::initialize()
637{
638    int32_t rc;
639    cam_dimension_t streamDim;
640
641    if (mMemory || m_numStreams > 0) {
642        ALOGE("%s: metadata channel already initialized", __func__);
643        return -EINVAL;
644    }
645
646    rc = init(NULL, NULL);
647    if (rc < 0) {
648        ALOGE("%s: init failed", __func__);
649        return rc;
650    }
651
652    streamDim.width = sizeof(metadata_buffer_t),
653    streamDim.height = 1;
654    rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
655        streamDim, MIN_STREAMING_BUFFER_NUM);
656    if (rc < 0) {
657        ALOGE("%s: addStream failed", __func__);
658    }
659    return rc;
660}
661
662int32_t QCamera3MetadataChannel::request(buffer_handle_t *buffer, uint32_t frameNumber)
663{
664    if (!m_bIsActive) {
665#ifdef FAKE_FRAME_NUMBERS
666        startingFrameNumber=frameNumber;
667#endif
668        return start();
669    }
670    else
671        return 0;
672}
673
674int32_t QCamera3MetadataChannel::registerBuffers(uint32_t /*num_buffers*/,
675                                        buffer_handle_t ** /*buffers*/)
676{
677    // no registerBuffers are supported for metadata channel
678    return -EINVAL;
679}
680
681void QCamera3MetadataChannel::streamCbRoutine(
682                        mm_camera_super_buf_t *super_frame,
683                        QCamera3Stream *stream)
684{
685    uint32_t requestNumber = 0;
686    if (super_frame == NULL || super_frame->num_bufs != 1) {
687        ALOGE("%s: super_frame is not valid", __func__);
688        return;
689    }
690#ifdef FAKE_FRAME_NUMBERS
691    requestNumber = startingFrameNumber++;
692#endif
693    mChannelCB(super_frame, NULL, requestNumber, mUserData);
694
695    //Return the buffer
696    stream->bufDone(super_frame->bufs[0]->buf_idx);
697}
698
699QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len)
700{
701    int rc;
702    if (len != sizeof(metadata_buffer_t)) {
703        ALOGE("%s: size doesn't match %d vs %d", __func__,
704                len, sizeof(metadata_buffer_t));
705        return NULL;
706    }
707    mMemory = new QCamera3HeapMemory();
708    if (!mMemory) {
709        ALOGE("%s: unable to create metadata memory", __func__);
710        return NULL;
711    }
712    rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true);
713    if (rc < 0) {
714        ALOGE("%s: unable to allocate metadata memory", __func__);
715        delete mMemory;
716        mMemory = NULL;
717        return NULL;
718    }
719    memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t));
720    return mMemory;
721}
722
723void QCamera3MetadataChannel::putStreamBufs()
724{
725    mMemory->deallocate();
726    delete mMemory;
727    mMemory = NULL;
728}
729
730/*===========================================================================
731 * FUNCTION   : jpegEvtHandle
732 *
733 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events.
734                Construct result payload and call mChannelCb to deliver buffer
735                to framework.
736 *
737 * PARAMETERS :
738 *   @status    : status of jpeg job
739 *   @client_hdl: jpeg client handle
740 *   @jobId     : jpeg job Id
741 *   @p_ouput   : ptr to jpeg output result struct
742 *   @userdata  : user data ptr
743 *
744 * RETURN     : none
745 *==========================================================================*/
746void QCamera3PicChannel::jpegEvtHandle(jpeg_job_status_t status,
747                                              uint32_t /*client_hdl*/,
748                                              uint32_t jobId,
749                                              mm_jpeg_output_t *p_output,
750                                              void *userdata)
751{
752    buffer_handle_t *resultBuffer;
753    int32_t resultFrameNumber;
754    int resultStatus = CAMERA3_BUFFER_STATUS_OK;
755    camera3_stream_buffer_t result;
756    camera3_jpeg_blob_t jpegHeader;
757    char* jpeg_eof = 0;
758    QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata;
759    if (obj) {
760        //Construct payload for process_capture_result. Call mChannelCb
761
762        qcamera_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId);
763
764        if ((job == NULL) || (status == JPEG_JOB_STATUS_ERROR)) {
765            ALOGE("%s: Error in jobId: (%d) with status: %d", __func__, jobId, status);
766            resultStatus = CAMERA3_BUFFER_STATUS_ERROR;
767        }
768
769        //Construct jpeg transient header of type camera3_jpeg_blob_t
770        //Append at the end of jpeg image of buf_filled_len size
771
772        jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
773        jpegHeader.jpeg_size = p_output->buf_filled_len;
774
775
776        char* jpeg_buf = (char *)p_output->buf_vaddr;
777
778        jpeg_eof = &jpeg_buf[p_output->buf_filled_len];
779        memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader));
780
781        ////Use below data to issue framework callback
782
783        resultBuffer = obj->mCamera3Buffers[0];
784        resultFrameNumber = obj->mMemory->getFrameNumber(0);
785
786        result.stream = obj->mCamera3Stream;
787        result.buffer = resultBuffer;
788        result.status = resultStatus;
789        result.acquire_fence = -1;
790        result.release_fence = -1;
791
792        ALOGE("%s: Issue Callback", __func__);
793        obj->mChannelCB(NULL, &result, resultFrameNumber, obj->mUserData);
794
795        // release internal data for jpeg job
796        if (job != NULL) {
797            obj->m_postprocessor.releaseJpegJobData(job);
798            free(job);
799        }
800        return;
801        // }
802    } else {
803        ALOGE("%s: Null userdata in jpeg callback", __func__);
804    }
805}
806
807QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle,
808                    mm_camera_ops_t *cam_ops,
809                    channel_cb_routine cb_routine,
810                    cam_padding_info_t *paddingInfo,
811                    void *userData,
812                    camera3_stream_t *stream) :
813                        QCamera3Channel(cam_handle, cam_ops, cb_routine,
814                        paddingInfo, userData),
815                        mCamera3Stream(stream),
816                        m_postprocessor(this),
817                        mCamera3Buffers(NULL),
818                        mMemory(NULL),
819                        mYuvMemory(NULL)
820{
821    int32_t rc = m_postprocessor.init(jpegEvtHandle, this);
822    if (rc != 0) {
823        ALOGE("Init Postprocessor failed");
824    }
825}
826
827QCamera3PicChannel::~QCamera3PicChannel()
828{
829    int32_t rc = m_postprocessor.deinit();
830    if (rc != 0) {
831        ALOGE("De-init Postprocessor failed");
832    }
833    if (mCamera3Buffers) {
834        delete[] mCamera3Buffers;
835    }
836}
837
838int32_t QCamera3PicChannel::initialize()
839{
840    int32_t rc = NO_ERROR;
841    cam_dimension_t streamDim;
842    cam_stream_type_t streamType;
843    cam_format_t streamFormat;
844    mm_camera_channel_attr_t attr;
845
846    memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
847    attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
848    attr.look_back = 1;
849    attr.post_frame_skip = 1;
850    attr.water_mark = 1;
851    attr.max_unmatched_frames = 1;
852
853    rc = init(&attr, QCamera3PicChannel::dataNotifyCB);
854    if (rc < 0) {
855        ALOGE("%s: init failed", __func__);
856        return rc;
857    }
858
859    streamType = CAM_STREAM_TYPE_SNAPSHOT;
860    streamFormat = CAM_FORMAT_YUV_420_NV21;
861    streamDim.width = mCamera3Stream->width;
862    streamDim.height = mCamera3Stream->height;
863    int num_buffers = QCamera3PicChannel::kMaxBuffers + 1;
864
865    rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
866            num_buffers);
867
868
869    return rc;
870}
871
872int32_t QCamera3PicChannel::request(buffer_handle_t *buffer, uint32_t frameNumber, jpeg_settings_t* jpegSettings)
873{
874    //FIX ME: Return buffer back in case of failures below.
875
876    int32_t rc = NO_ERROR;
877    int index;
878    mJpegSettings = jpegSettings;
879    if(!m_bIsActive) {
880        ALOGD("%s: First request on this channel starting stream",__func__);
881        //Stream on for main image. YUV buffer is queued to the kernel at the end of this call.
882        rc = start();
883    } else {
884        ALOGE("%s: Request on an existing stream",__func__);
885    }
886
887    if(rc != NO_ERROR) {
888        ALOGE("%s: Failed to start the stream on the request",__func__);
889        return rc;
890    }
891
892
893    if(!mMemory) {
894        ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__);
895        return NO_MEMORY;
896    }
897
898    index = mMemory->getMatchBufIndex((void*)buffer);
899    if(index < 0) {
900        ALOGE("%s: Could not find object among registered buffers",__func__);
901        return DEAD_OBJECT;
902    }
903
904    rc = mMemory->markFrameNumber(index, frameNumber);
905
906    //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer
907    m_postprocessor.start(mMemory);
908    if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) {
909        ALOGE("%s: Request for super buffer failed",__func__);
910    }
911
912    return rc;
913}
914
915/*===========================================================================
916 * FUNCTION   : dataNotifyCB
917 *
918 * DESCRIPTION: Channel Level callback used for super buffer data notify.
919 *              This function is registered with mm-camera-interface to handle
920 *              data notify
921 *
922 * PARAMETERS :
923 *   @recvd_frame   : stream frame received
924 *   userdata       : user data ptr
925 *
926 * RETURN     : none
927 *==========================================================================*/
928void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
929                                 void *userdata)
930{
931    ALOGE("%s: E\n", __func__);
932    QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata;
933
934    if (channel == NULL) {
935        ALOGE("%s: invalid channel pointer", __func__);
936        return;
937    }
938
939    if(channel->m_numStreams != 1) {
940        ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__);
941        return;
942    }
943
944
945    if(channel->mStreams[0] == NULL) {
946        ALOGE("%s: Error: Invalid Stream object",__func__);
947        return;
948    }
949
950    channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]);
951    ALOGE("%s: X\n", __func__);
952
953    return;
954}
955
956
957int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers,
958                        buffer_handle_t **buffers)
959{
960    int rc = 0;
961    struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]);
962    cam_stream_type_t streamType;
963    cam_format_t streamFormat;
964    cam_dimension_t streamDim;
965
966    ALOGE("%s: E",__func__);
967
968    if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) {
969        streamType = CAM_STREAM_TYPE_SNAPSHOT;
970        streamFormat = CAM_FORMAT_YUV_420_NV21;
971    } else {
972        //TODO: Fail for other types of streams for now
973        ALOGE("%s: format is not BLOB", __func__);
974        return -EINVAL;
975    }
976    /* Bookkeep buffer set because they go out of scope after register call */
977    mNumBufs = num_buffers;
978    mCamera3Buffers = new buffer_handle_t*[num_buffers];
979    if (mCamera3Buffers == NULL) {
980        ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
981        return -ENOMEM;
982    }
983    for (size_t i = 0; i < num_buffers; i++)
984        mCamera3Buffers[i] = buffers[i];
985
986    return rc;
987}
988
989void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
990                            QCamera3Stream *stream)
991{
992    //TODO
993    //Used only for getting YUV. Jpeg callback will be sent back from channel directly to HWI.
994    //Refer to func jpegEvtHandle
995
996    //Got the yuv callback. Calling yuv callback handler in PostProc
997    uint8_t frameIndex;
998    mm_camera_super_buf_t* frame = NULL;
999
1000    if(!super_frame) {
1001         ALOGE("%s: Invalid Super buffer",__func__);
1002         return;
1003    }
1004
1005    if(super_frame->num_bufs != 1) {
1006         ALOGE("%s: Multiple streams are not supported",__func__);
1007         return;
1008    }
1009    if(super_frame->bufs[0] == NULL ) {
1010         ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
1011                  __func__);
1012         return;
1013    }
1014
1015    frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
1016    if(frameIndex >= mNumBufs) {
1017         ALOGE("%s: Error, Invalid index for buffer",__func__);
1018         if(stream) {
1019             stream->bufDone(frameIndex);
1020         }
1021         return;
1022    }
1023
1024    frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
1025    if (frame == NULL) {
1026       ALOGE("%s: Error allocating memory to save received_frame structure.", __func__);
1027       if(stream) {
1028           stream->bufDone(frameIndex);
1029       }
1030       return;
1031    }
1032    *frame = *super_frame;
1033
1034    m_postprocessor.processData(frame);
1035    return;
1036}
1037
1038QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
1039{
1040    int rc = 0;
1041
1042    if (mNumBufs == 0 || mCamera3Buffers == NULL) {
1043        ALOGE("%s: buffers not registered yet", __func__);
1044        return NULL;
1045    }
1046
1047    mMemory = new QCamera3GrallocMemory();
1048    if (mMemory == NULL) {
1049        return NULL;
1050    }
1051
1052    //Registering Jpeg output buffer
1053    if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
1054        delete mMemory;
1055        mMemory = NULL;
1056        return NULL;
1057    }
1058
1059    mYuvMemory = new QCamera3HeapMemory();
1060    if (!mYuvMemory) {
1061        ALOGE("%s: unable to create metadata memory", __func__);
1062        return NULL;
1063    }
1064
1065    //Queue YUV buffers in the beginning mQueueAll = true
1066    rc = mYuvMemory->allocate(QCamera3PicChannel::kMaxBuffers + 1, len, true);
1067    if (rc < 0) {
1068        ALOGE("%s: unable to allocate metadata memory", __func__);
1069        delete mYuvMemory;
1070        mYuvMemory = NULL;
1071        return NULL;
1072    }
1073    return mYuvMemory;
1074}
1075
1076void QCamera3PicChannel::putStreamBufs()
1077{
1078    mMemory->unregisterBuffers();
1079    delete mMemory;
1080    mMemory = NULL;
1081
1082    mYuvMemory->deallocate();
1083    delete mYuvMemory;
1084    mYuvMemory = NULL;
1085}
1086
1087/*===========================================================================
1088 * FUNCTION   : needRotationReprocess
1089 *
1090 * DESCRIPTION: if online rotation needs to be done by cpp
1091 *
1092 * PARAMETERS : none
1093 *
1094 * RETURN     : true: needed
1095 *              false: no need
1096 *==========================================================================*/
1097bool QCamera3PicChannel::needOnlineRotation()
1098{
1099    //TBD_Later
1100    //if ((gCamCapability[mCameraId]->qcom_supported_feature_mask & CAM_QCOM_FEATURE_ROTATION) > 0 &&
1101       if (mJpegSettings->jpeg_orientation > 0) {
1102        // current rotation is not zero, and pp has the capability to process rotation
1103        ALOGD("%s: need do online rotation", __func__);
1104        return true;
1105    }
1106    return false;
1107}
1108
1109/*===========================================================================
1110 * FUNCTION   : getThumbnailSize
1111 *
1112 * DESCRIPTION: get user set thumbnail size
1113 *
1114 * PARAMETERS :
1115 *   @dim     : output of thumbnail dimension
1116 *
1117 * RETURN     : none
1118 *==========================================================================*/
1119void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim)
1120{
1121    dim = mJpegSettings->thumbnail_size;
1122}
1123
1124/*===========================================================================
1125 * FUNCTION   : getJpegQuality
1126 *
1127 * DESCRIPTION: get user set jpeg quality
1128 *
1129 * PARAMETERS : none
1130 *
1131 * RETURN     : jpeg quality setting
1132 *==========================================================================*/
1133int QCamera3PicChannel::getJpegQuality()
1134{
1135    int quality = mJpegSettings->jpeg_quality;
1136    if (quality < 0) {
1137        quality = 85;  //set to default quality value
1138    }
1139    return quality;
1140}
1141
1142/*===========================================================================
1143 * FUNCTION   : getJpegRotation
1144 *
1145 * DESCRIPTION: get rotation information to be passed into jpeg encoding
1146 *
1147 * PARAMETERS : none
1148 *
1149 * RETURN     : rotation information
1150 *==========================================================================*/
1151int QCamera3PicChannel::getJpegRotation() {
1152    int rotation = mJpegSettings->jpeg_orientation;
1153    if (rotation < 0) {
1154        rotation = 0;
1155    }
1156    return rotation;
1157}
1158
1159/*===========================================================================
1160 * FUNCTION   : getRational
1161 *
1162 * DESCRIPTION: compose rational struct
1163 *
1164 * PARAMETERS :
1165 *   @rat     : ptr to struct to store rational info
1166 *   @num     :num of the rational
1167 *   @denom   : denom of the rational
1168 *
1169 * RETURN     : int32_t type of status
1170 *              NO_ERROR  -- success
1171 *              none-zero failure code
1172 *==========================================================================*/
1173int32_t getRational(rat_t *rat, int num, int denom)
1174{
1175    if (NULL == rat) {
1176        ALOGE("%s: NULL rat input", __func__);
1177        return BAD_VALUE;
1178    }
1179    rat->num = num;
1180    rat->denom = denom;
1181    return NO_ERROR;
1182}
1183
1184/*===========================================================================
1185 * FUNCTION   : parseGPSCoordinate
1186 *
1187 * DESCRIPTION: parse GPS coordinate string
1188 *
1189 * PARAMETERS :
1190 *   @coord_str : [input] coordinate string
1191 *   @coord     : [output]  ptr to struct to store coordinate
1192 *
1193 * RETURN     : int32_t type of status
1194 *              NO_ERROR  -- success
1195 *              none-zero failure code
1196 *==========================================================================*/
1197int parseGPSCoordinate(const char *coord_str, rat_t* coord)
1198{
1199    if(coord == NULL) {
1200        ALOGE("%s: error, invalid argument coord == NULL", __func__);
1201        return BAD_VALUE;
1202    }
1203    float degF = atof(coord_str);
1204    if (degF < 0) {
1205        degF = -degF;
1206    }
1207    float minF = (degF - (int) degF) * 60;
1208    float secF = (minF - (int) minF) * 60;
1209
1210    getRational(&coord[0], (int)degF, 1);
1211    getRational(&coord[1], (int)minF, 1);
1212    getRational(&coord[2], (int)(secF * 10000), 10000);
1213    return NO_ERROR;
1214}
1215
1216/*===========================================================================
1217 * FUNCTION   : getExifDateTime
1218 *
1219 * DESCRIPTION: query exif date time
1220 *
1221 * PARAMETERS :
1222 *   @dateTime : string to store exif date time
1223 *   @count    : lenght of the dateTime string
1224 *
1225 * RETURN     : int32_t type of status
1226 *              NO_ERROR  -- success
1227 *              none-zero failure code
1228 *==========================================================================*/
1229int32_t getExifDateTime(char *dateTime, uint32_t &count)
1230{
1231    //get time and date from system
1232    time_t rawtime;
1233    struct tm * timeinfo;
1234    time(&rawtime);
1235    timeinfo = localtime (&rawtime);
1236    //Write datetime according to EXIF Spec
1237    //"YYYY:MM:DD HH:MM:SS" (20 chars including \0)
1238    snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d",
1239             timeinfo->tm_year + 1900, timeinfo->tm_mon + 1,
1240             timeinfo->tm_mday, timeinfo->tm_hour,
1241             timeinfo->tm_min, timeinfo->tm_sec);
1242    count = 20;
1243
1244    return NO_ERROR;
1245}
1246
1247/*===========================================================================
1248 * FUNCTION   : getExifFocalLength
1249 *
1250 * DESCRIPTION: get exif focal lenght
1251 *
1252 * PARAMETERS :
1253 *   @focalLength : ptr to rational strcut to store focal lenght
1254 *
1255 * RETURN     : int32_t type of status
1256 *              NO_ERROR  -- success
1257 *              none-zero failure code
1258 *==========================================================================*/
1259int32_t getExifFocalLength(rat_t *focalLength, float value)
1260{
1261    int focalLengthValue =
1262        (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION);
1263    return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION);
1264}
1265
1266/*===========================================================================
1267 * FUNCTION   : getExifGpsProcessingMethod
1268 *
1269 * DESCRIPTION: get GPS processing method
1270 *
1271 * PARAMETERS :
1272 *   @gpsProcessingMethod : string to store GPS process method
1273 *   @count               : lenght of the string
1274 *
1275 * RETURN     : int32_t type of status
1276 *              NO_ERROR  -- success
1277 *              none-zero failure code
1278 *==========================================================================*/
1279int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod,
1280                                                      uint32_t &count, int value)
1281{
1282    char str[30];
1283    snprintf(str, sizeof(str), "%d", value);
1284    if(str != NULL) {
1285        memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
1286        count = EXIF_ASCII_PREFIX_SIZE;
1287        strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str, strlen(str));
1288        count += strlen(str);
1289        gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char
1290        return NO_ERROR;
1291    } else {
1292        return BAD_VALUE;
1293    }
1294}
1295
1296/*===========================================================================
1297 * FUNCTION   : getExifLatitude
1298 *
1299 * DESCRIPTION: get exif latitude
1300 *
1301 * PARAMETERS :
1302 *   @latitude : ptr to rational struct to store latitude info
1303 *   @ladRef   : charater to indicate latitude reference
1304 *
1305 * RETURN     : int32_t type of status
1306 *              NO_ERROR  -- success
1307 *              none-zero failure code
1308 *==========================================================================*/
1309int32_t getExifLatitude(rat_t *latitude,
1310                                           char *latRef, double value)
1311{
1312    char str[30];
1313    snprintf(str, sizeof(str), "%f", value);
1314    if(str != NULL) {
1315        parseGPSCoordinate(str, latitude);
1316
1317        //set Latitude Ref
1318        float latitudeValue = strtof(str, 0);
1319        if(latitudeValue < 0.0f) {
1320            latRef[0] = 'S';
1321        } else {
1322            latRef[0] = 'N';
1323        }
1324        latRef[1] = '\0';
1325        return NO_ERROR;
1326    }else{
1327        return BAD_VALUE;
1328    }
1329}
1330
1331/*===========================================================================
1332 * FUNCTION   : getExifLongitude
1333 *
1334 * DESCRIPTION: get exif longitude
1335 *
1336 * PARAMETERS :
1337 *   @longitude : ptr to rational struct to store longitude info
1338 *   @lonRef    : charater to indicate longitude reference
1339 *
1340 * RETURN     : int32_t type of status
1341 *              NO_ERROR  -- success
1342 *              none-zero failure code
1343 *==========================================================================*/
1344int32_t getExifLongitude(rat_t *longitude,
1345                                            char *lonRef, double value)
1346{
1347    char str[30];
1348    snprintf(str, sizeof(str), "%f", value);
1349    if(str != NULL) {
1350        parseGPSCoordinate(str, longitude);
1351
1352        //set Longitude Ref
1353        float longitudeValue = strtof(str, 0);
1354        if(longitudeValue < 0.0f) {
1355            lonRef[0] = 'W';
1356        } else {
1357            lonRef[0] = 'E';
1358        }
1359        lonRef[1] = '\0';
1360        return NO_ERROR;
1361    }else{
1362        return BAD_VALUE;
1363    }
1364}
1365
1366/*===========================================================================
1367 * FUNCTION   : getExifAltitude
1368 *
1369 * DESCRIPTION: get exif altitude
1370 *
1371 * PARAMETERS :
1372 *   @altitude : ptr to rational struct to store altitude info
1373 *   @altRef   : charater to indicate altitude reference
1374 *
1375 * RETURN     : int32_t type of status
1376 *              NO_ERROR  -- success
1377 *              none-zero failure code
1378 *==========================================================================*/
1379int32_t getExifAltitude(rat_t *altitude,
1380                                           char *altRef, double value)
1381{
1382    char str[30];
1383    snprintf(str, sizeof(str), "%f", value);
1384    if(str != NULL) {
1385        double value = atof(str);
1386        *altRef = 0;
1387        if(value < 0){
1388            *altRef = 1;
1389            value = -value;
1390        }
1391        return getRational(altitude, value*1000, 1000);
1392    }else{
1393        return BAD_VALUE;
1394    }
1395}
1396
1397/*===========================================================================
1398 * FUNCTION   : getExifGpsDateTimeStamp
1399 *
1400 * DESCRIPTION: get exif GPS date time stamp
1401 *
1402 * PARAMETERS :
1403 *   @gpsDateStamp : GPS date time stamp string
1404 *   @bufLen       : length of the string
1405 *   @gpsTimeStamp : ptr to rational struct to store time stamp info
1406 *
1407 * RETURN     : int32_t type of status
1408 *              NO_ERROR  -- success
1409 *              none-zero failure code
1410 *==========================================================================*/
1411int32_t getExifGpsDateTimeStamp(char *gpsDateStamp,
1412                                                   uint32_t bufLen,
1413                                                   rat_t *gpsTimeStamp, int64_t value)
1414{
1415    char str[30];
1416    snprintf(str, sizeof(str), "%d", value);
1417    if(str != NULL) {
1418        time_t unixTime = (time_t)atol(str);
1419        struct tm *UTCTimestamp = gmtime(&unixTime);
1420
1421        strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp);
1422
1423        getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1);
1424        getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1);
1425        getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1);
1426
1427        return NO_ERROR;
1428    } else {
1429        return BAD_VALUE;
1430    }
1431}
1432/*===========================================================================
1433 * FUNCTION   : getExifData
1434 *
1435 * DESCRIPTION: get exif data to be passed into jpeg encoding
1436 *
1437 * PARAMETERS : none
1438 *
1439 * RETURN     : exif data from user setting and GPS
1440 *==========================================================================*/
1441QCamera3Exif *QCamera3PicChannel::getExifData()
1442{
1443    QCamera3Exif *exif = new QCamera3Exif();
1444    if (exif == NULL) {
1445        ALOGE("%s: No memory for QCamera3Exif", __func__);
1446        return NULL;
1447    }
1448
1449    int32_t rc = NO_ERROR;
1450    uint32_t count = 0;
1451
1452    // add exif entries
1453    char dateTime[20];
1454    memset(dateTime, 0, sizeof(dateTime));
1455    count = 20;
1456    rc = getExifDateTime(dateTime, count);
1457    if(rc == NO_ERROR) {
1458        exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
1459                       EXIF_ASCII,
1460                       count,
1461                       (void *)dateTime);
1462    } else {
1463        ALOGE("%s: getExifDateTime failed", __func__);
1464    }
1465
1466    rat_t focalLength;
1467    rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length);
1468    if (rc == NO_ERROR) {
1469        exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
1470                       EXIF_RATIONAL,
1471                       1,
1472                       (void *)&(focalLength));
1473    } else {
1474        ALOGE("%s: getExifFocalLength failed", __func__);
1475    }
1476
1477    //TBD_Later
1478    /*uint16_t isoSpeed = mParameters.getExifIsoSpeed();
1479    exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
1480                   EXIF_SHORT,
1481                   1,
1482                   (void *)&(isoSpeed));
1483    */
1484    char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
1485    count = 0;
1486    rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method);
1487    if(rc == NO_ERROR) {
1488        exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
1489                       EXIF_ASCII,
1490                       count,
1491                       (void *)gpsProcessingMethod);
1492    } else {
1493        ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
1494    }
1495
1496    rat_t latitude[3];
1497    char latRef[2];
1498    rc = getExifLatitude(latitude, latRef, mJpegSettings->gps_coordinates[0]);
1499    if(rc == NO_ERROR) {
1500        exif->addEntry(EXIFTAGID_GPS_LATITUDE,
1501                       EXIF_RATIONAL,
1502                       3,
1503                       (void *)latitude);
1504        exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
1505                       EXIF_ASCII,
1506                       2,
1507                       (void *)latRef);
1508    } else {
1509        ALOGE("%s: getExifLatitude failed", __func__);
1510    }
1511
1512    rat_t longitude[3];
1513    char lonRef[2];
1514    rc = getExifLongitude(longitude, lonRef, mJpegSettings->gps_coordinates[1]);
1515    if(rc == NO_ERROR) {
1516        exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
1517                       EXIF_RATIONAL,
1518                       3,
1519                       (void *)longitude);
1520
1521        exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
1522                       EXIF_ASCII,
1523                       2,
1524                       (void *)lonRef);
1525    } else {
1526        ALOGE("%s: getExifLongitude failed", __func__);
1527    }
1528
1529    rat_t altitude;
1530    char altRef;
1531    rc = getExifAltitude(&altitude, &altRef, mJpegSettings->gps_coordinates[2]);
1532    if(rc == NO_ERROR) {
1533        exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
1534                       EXIF_RATIONAL,
1535                       1,
1536                       (void *)&(altitude));
1537
1538        exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
1539                       EXIF_BYTE,
1540                       1,
1541                       (void *)&altRef);
1542    } else {
1543        ALOGE("%s: getExifAltitude failed", __func__);
1544    }
1545
1546    char gpsDateStamp[20];
1547    rat_t gpsTimeStamp[3];
1548    rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, mJpegSettings->gps_timestamp);
1549    if(rc == NO_ERROR) {
1550        exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
1551                       EXIF_ASCII,
1552                       strlen(gpsDateStamp) + 1,
1553                       (void *)gpsDateStamp);
1554
1555        exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
1556                       EXIF_RATIONAL,
1557                       3,
1558                       (void *)gpsTimeStamp);
1559    } else {
1560        ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
1561    }
1562
1563    return exif;
1564}
1565
1566int QCamera3PicChannel::kMaxBuffers = 1;
1567}; // namespace qcamera
1568