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