• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.deinit();
931     if (rc != 0) {
932         ALOGE("De-init Postprocessor failed");
933     }
934     if (mCamera3Buffers) {
935         delete[] mCamera3Buffers;
936     }
937 }
938 
initialize()939 int32_t QCamera3PicChannel::initialize()
940 {
941     int32_t rc = NO_ERROR;
942     cam_dimension_t streamDim;
943     cam_stream_type_t streamType;
944     cam_format_t streamFormat;
945     mm_camera_channel_attr_t attr;
946 
947     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
948     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
949     attr.look_back = 1;
950     attr.post_frame_skip = 1;
951     attr.water_mark = 1;
952     attr.max_unmatched_frames = 1;
953 
954     rc = init(&attr, NULL);
955     if (rc < 0) {
956         ALOGE("%s: init failed", __func__);
957         return rc;
958     }
959 
960     streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT;
961     streamFormat = CAM_FORMAT_YUV_420_NV21;
962     streamDim.width = mCamera3Stream->width;
963     streamDim.height = mCamera3Stream->height;
964 
965     int num_buffers = 1;
966 
967     rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
968             num_buffers);
969 
970     return rc;
971 }
972 
request(buffer_handle_t * buffer,uint32_t frameNumber,jpeg_settings_t * jpegSettings,mm_camera_buf_def_t * pInputBuffer,QCamera3Channel * pInputChannel)973 int32_t QCamera3PicChannel::request(buffer_handle_t *buffer,
974         uint32_t frameNumber, jpeg_settings_t* jpegSettings,
975         mm_camera_buf_def_t *pInputBuffer,QCamera3Channel* pInputChannel)
976 {
977     //FIX ME: Return buffer back in case of failures below.
978 
979     int32_t rc = NO_ERROR;
980     int index;
981     mJpegSettings = jpegSettings;
982     if(!m_bIsActive) {
983         ALOGD("%s: First request on this channel starting stream",__func__);
984         //Stream on for main image. YUV buffer is queued to the kernel at the end of this call.
985         if(!pInputBuffer)
986             rc = start();
987         else
988             ALOGD("%s: Current request has input buffer no need to start h/w stream", __func__);
989     } else {
990         mStreams[0]->bufDone(0);
991         ALOGD("%s: Request on an existing stream",__func__);
992     }
993 
994     if(rc != NO_ERROR) {
995         ALOGE("%s: Failed to start the stream on the request",__func__);
996         return rc;
997     }
998 
999 
1000     if(!mMemory) {
1001         if(pInputBuffer) {
1002             mMemory = new QCamera3GrallocMemory();
1003             if (mMemory == NULL) {
1004                 return NO_MEMORY;
1005             }
1006 
1007             //Registering Jpeg output buffer
1008             if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
1009                 delete mMemory;
1010                 mMemory = NULL;
1011                 return NO_MEMORY;
1012             }
1013         } else {
1014             ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__);
1015             return NO_MEMORY;
1016         }
1017     }
1018 
1019     index = mMemory->getMatchBufIndex((void*)buffer);
1020     if(index < 0) {
1021         ALOGE("%s: Could not find object among registered buffers",__func__);
1022         return DEAD_OBJECT;
1023     }
1024     rc = mMemory->markFrameNumber(index, frameNumber);
1025 
1026     //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer
1027     mCurrentBufIndex = index;
1028 
1029     m_postprocessor.start(mMemory, index, this);
1030 
1031     ALOGD("%s: Post-process started", __func__);
1032     if(pInputBuffer) {
1033         ALOGD("%s: Issue call to reprocess", __func__);
1034         m_postprocessor.processAuxiliaryData(pInputBuffer,pInputChannel);
1035     }
1036     return rc;
1037 }
1038 
1039 /*===========================================================================
1040  * FUNCTION   : dataNotifyCB
1041  *
1042  * DESCRIPTION: Channel Level callback used for super buffer data notify.
1043  *              This function is registered with mm-camera-interface to handle
1044  *              data notify
1045  *
1046  * PARAMETERS :
1047  *   @recvd_frame   : stream frame received
1048  *   userdata       : user data ptr
1049  *
1050  * RETURN     : none
1051  *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)1052 void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
1053                                  void *userdata)
1054 {
1055     ALOGV("%s: E\n", __func__);
1056     QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata;
1057 
1058     if (channel == NULL) {
1059         ALOGE("%s: invalid channel pointer", __func__);
1060         return;
1061     }
1062 
1063     if(channel->m_numStreams != 1) {
1064         ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__);
1065         return;
1066     }
1067 
1068 
1069     if(channel->mStreams[0] == NULL) {
1070         ALOGE("%s: Error: Invalid Stream object",__func__);
1071         return;
1072     }
1073 
1074     channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]);
1075 
1076     ALOGV("%s: X\n", __func__);
1077     return;
1078 }
1079 
1080 
registerBuffers(uint32_t num_buffers,buffer_handle_t ** buffers)1081 int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers,
1082                         buffer_handle_t **buffers)
1083 {
1084     int rc = 0;
1085     cam_stream_type_t streamType;
1086     cam_format_t streamFormat;
1087 
1088     ALOGV("%s: E",__func__);
1089     rc = QCamera3PicChannel::initialize();
1090     if (rc < 0) {
1091         ALOGE("%s: init failed", __func__);
1092         return rc;
1093     }
1094 
1095     if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) {
1096         streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT;
1097         streamFormat = CAM_FORMAT_YUV_420_NV21;
1098     } else {
1099         //TODO: Fail for other types of streams for now
1100         ALOGE("%s: format is not BLOB", __func__);
1101         return -EINVAL;
1102     }
1103     /* Bookkeep buffer set because they go out of scope after register call */
1104     mNumBufs = num_buffers;
1105     mCamera3Buffers = new buffer_handle_t*[num_buffers];
1106     if (mCamera3Buffers == NULL) {
1107         ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
1108         return -ENOMEM;
1109     }
1110     for (size_t i = 0; i < num_buffers; i++)
1111         mCamera3Buffers[i] = buffers[i];
1112 
1113     ALOGV("%s: X",__func__);
1114     return rc;
1115 }
1116 
streamCbRoutine(mm_camera_super_buf_t * super_frame,QCamera3Stream * stream)1117 void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
1118                             QCamera3Stream *stream)
1119 {
1120     //TODO
1121     //Used only for getting YUV. Jpeg callback will be sent back from channel
1122     //directly to HWI. Refer to func jpegEvtHandle
1123 
1124     //Got the yuv callback. Calling yuv callback handler in PostProc
1125     uint8_t frameIndex;
1126     mm_camera_super_buf_t* frame = NULL;
1127     if(!super_frame) {
1128          ALOGE("%s: Invalid Super buffer",__func__);
1129          return;
1130     }
1131 
1132     if(super_frame->num_bufs != 1) {
1133          ALOGE("%s: Multiple streams are not supported",__func__);
1134          return;
1135     }
1136     if(super_frame->bufs[0] == NULL ) {
1137          ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
1138                   __func__);
1139          return;
1140     }
1141 
1142     frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
1143     if(frameIndex >= mNumBufs) {
1144          ALOGE("%s: Error, Invalid index for buffer",__func__);
1145          if(stream) {
1146              stream->bufDone(frameIndex);
1147          }
1148          return;
1149     }
1150 
1151     frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
1152     if (frame == NULL) {
1153        ALOGE("%s: Error allocating memory to save received_frame structure.",
1154                                                                     __func__);
1155        if(stream) {
1156            stream->bufDone(frameIndex);
1157        }
1158        return;
1159     }
1160     *frame = *super_frame;
1161 
1162     m_postprocessor.processData(frame);
1163     free(super_frame);
1164     return;
1165 }
1166 
getStreamBufs(uint32_t len)1167 QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
1168 {
1169     int rc = 0;
1170 
1171     if (mNumBufs == 0 || mCamera3Buffers == NULL) {
1172         ALOGE("%s: buffers not registered yet", __func__);
1173         return NULL;
1174     }
1175 
1176     if(mMemory) {
1177         delete mMemory;
1178         mMemory = NULL;
1179     }
1180     mMemory = new QCamera3GrallocMemory();
1181     if (mMemory == NULL) {
1182         return NULL;
1183     }
1184 
1185     //Registering Jpeg output buffer
1186     if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
1187         delete mMemory;
1188         mMemory = NULL;
1189         return NULL;
1190     }
1191 
1192     mYuvMemory = new QCamera3HeapMemory();
1193     if (!mYuvMemory) {
1194         ALOGE("%s: unable to create metadata memory", __func__);
1195         return NULL;
1196     }
1197 
1198     //Queue YUV buffers in the beginning mQueueAll = true
1199     rc = mYuvMemory->allocate(1, len, true);
1200     if (rc < 0) {
1201         ALOGE("%s: unable to allocate metadata memory", __func__);
1202         delete mYuvMemory;
1203         mYuvMemory = NULL;
1204         return NULL;
1205     }
1206     return mYuvMemory;
1207 }
1208 
putStreamBufs()1209 void QCamera3PicChannel::putStreamBufs()
1210 {
1211     mMemory->unregisterBuffers();
1212     delete mMemory;
1213     mMemory = NULL;
1214 
1215     mYuvMemory->deallocate();
1216     delete mYuvMemory;
1217     mYuvMemory = NULL;
1218 }
1219 
isRawSnapshot()1220 bool QCamera3PicChannel::isRawSnapshot()
1221 {
1222    return !(mJpegSettings->is_jpeg_format);
1223 }
1224 /*===========================================================================
1225  * FUNCTION   : getThumbnailSize
1226  *
1227  * DESCRIPTION: get user set thumbnail size
1228  *
1229  * PARAMETERS :
1230  *   @dim     : output of thumbnail dimension
1231  *
1232  * RETURN     : none
1233  *==========================================================================*/
getThumbnailSize(cam_dimension_t & dim)1234 void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim)
1235 {
1236     dim = mJpegSettings->thumbnail_size;
1237 }
1238 
1239 /*===========================================================================
1240  * FUNCTION   : getJpegQuality
1241  *
1242  * DESCRIPTION: get user set jpeg quality
1243  *
1244  * PARAMETERS : none
1245  *
1246  * RETURN     : jpeg quality setting
1247  *==========================================================================*/
getJpegQuality()1248 int QCamera3PicChannel::getJpegQuality()
1249 {
1250     int quality = mJpegSettings->jpeg_quality;
1251     if (quality < 0) {
1252         quality = 85;  //set to default quality value
1253     }
1254     return quality;
1255 }
1256 
1257 /*===========================================================================
1258  * FUNCTION   : getJpegRotation
1259  *
1260  * DESCRIPTION: get rotation information to be passed into jpeg encoding
1261  *
1262  * PARAMETERS : none
1263  *
1264  * RETURN     : rotation information
1265  *==========================================================================*/
getJpegRotation()1266 int QCamera3PicChannel::getJpegRotation() {
1267     int rotation = mJpegSettings->jpeg_orientation;
1268     if (rotation < 0) {
1269         rotation = 0;
1270     }
1271     return rotation;
1272 }
1273 
queueMetadata(mm_camera_super_buf_t * metadata_buf)1274 void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf)
1275 {
1276     m_postprocessor.processPPMetadata(metadata_buf);
1277 }
1278 /*===========================================================================
1279  * FUNCTION   : getRational
1280  *
1281  * DESCRIPTION: compose rational struct
1282  *
1283  * PARAMETERS :
1284  *   @rat     : ptr to struct to store rational info
1285  *   @num     :num of the rational
1286  *   @denom   : denom of the rational
1287  *
1288  * RETURN     : int32_t type of status
1289  *              NO_ERROR  -- success
1290  *              none-zero failure code
1291  *==========================================================================*/
getRational(rat_t * rat,int num,int denom)1292 int32_t getRational(rat_t *rat, int num, int denom)
1293 {
1294     if (NULL == rat) {
1295         ALOGE("%s: NULL rat input", __func__);
1296         return BAD_VALUE;
1297     }
1298     rat->num = num;
1299     rat->denom = denom;
1300     return NO_ERROR;
1301 }
1302 
1303 /*===========================================================================
1304  * FUNCTION   : getRational
1305  *
1306  * DESCRIPTION: compose rational struct
1307  *
1308  * PARAMETERS :
1309  *   @rat     : ptr to struct to store rational info
1310  *   @num     :num of the rational
1311  *   @denom   : denom of the rational
1312  *
1313  * RETURN     : int32_t type of status
1314  *              NO_ERROR  -- success
1315  *              none-zero failure code
1316  *==========================================================================*/
getRationalExposureTime(rat_t * rat,double num,double denom)1317 int32_t getRationalExposureTime(rat_t *rat, double num, double denom)
1318 {
1319     if (NULL == rat) {
1320         ALOGE("%s: NULL rat input", __func__);
1321         return BAD_VALUE;
1322     }
1323     rat->num = num;
1324     rat->denom = round(1.0 / denom);
1325     return NO_ERROR;
1326 }
1327 
1328 /*===========================================================================
1329  * FUNCTION   : parseGPSCoordinate
1330  *
1331  * DESCRIPTION: parse GPS coordinate string
1332  *
1333  * PARAMETERS :
1334  *   @coord_str : [input] coordinate string
1335  *   @coord     : [output]  ptr to struct to store coordinate
1336  *
1337  * RETURN     : int32_t type of status
1338  *              NO_ERROR  -- success
1339  *              none-zero failure code
1340  *==========================================================================*/
parseGPSCoordinate(const char * coord_str,rat_t * coord)1341 int parseGPSCoordinate(const char *coord_str, rat_t* coord)
1342 {
1343     if(coord == NULL) {
1344         ALOGE("%s: error, invalid argument coord == NULL", __func__);
1345         return BAD_VALUE;
1346     }
1347     float degF = atof(coord_str);
1348     if (degF < 0) {
1349         degF = -degF;
1350     }
1351     float minF = (degF - (int) degF) * 60;
1352     float secF = (minF - (int) minF) * 60;
1353 
1354     getRational(&coord[0], (int)degF, 1);
1355     getRational(&coord[1], (int)minF, 1);
1356     getRational(&coord[2], (int)(secF * 10000), 10000);
1357     return NO_ERROR;
1358 }
1359 
1360 /*===========================================================================
1361  * FUNCTION   : getExifDateTime
1362  *
1363  * DESCRIPTION: query exif date time
1364  *
1365  * PARAMETERS :
1366  *   @dateTime : string to store exif date time
1367  *   @count    : lenght of the dateTime string
1368  *
1369  * RETURN     : int32_t type of status
1370  *              NO_ERROR  -- success
1371  *              none-zero failure code
1372  *==========================================================================*/
getExifDateTime(char * dateTime,uint32_t & count)1373 int32_t getExifDateTime(char *dateTime, uint32_t &count)
1374 {
1375     //get time and date from system
1376     time_t rawtime;
1377     struct tm * timeinfo;
1378     time(&rawtime);
1379     timeinfo = localtime (&rawtime);
1380     //Write datetime according to EXIF Spec
1381     //"YYYY:MM:DD HH:MM:SS" (20 chars including \0)
1382     snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d",
1383              timeinfo->tm_year + 1900, timeinfo->tm_mon + 1,
1384              timeinfo->tm_mday, timeinfo->tm_hour,
1385              timeinfo->tm_min, timeinfo->tm_sec);
1386     count = 20;
1387 
1388     return NO_ERROR;
1389 }
1390 
1391 /*===========================================================================
1392  * FUNCTION   : getExifFocalLength
1393  *
1394  * DESCRIPTION: get exif focal lenght
1395  *
1396  * PARAMETERS :
1397  *   @focalLength : ptr to rational strcut to store focal lenght
1398  *
1399  * RETURN     : int32_t type of status
1400  *              NO_ERROR  -- success
1401  *              none-zero failure code
1402  *==========================================================================*/
getExifFocalLength(rat_t * focalLength,float value)1403 int32_t getExifFocalLength(rat_t *focalLength, float value)
1404 {
1405     int focalLengthValue =
1406         (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION);
1407     return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION);
1408 }
1409 
1410 /*===========================================================================
1411   * FUNCTION   : getExifExpTimeInfo
1412   *
1413   * DESCRIPTION: get exif exposure time information
1414   *
1415   * PARAMETERS :
1416   *   @expoTimeInfo     : expousure time value
1417   * RETURN     : nt32_t type of status
1418   *              NO_ERROR  -- success
1419   *              none-zero failure code
1420   *==========================================================================*/
getExifExpTimeInfo(rat_t * expoTimeInfo,int64_t value)1421 int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value)
1422 {
1423 
1424     float cal_exposureTime;
1425     if (value != 0)
1426         cal_exposureTime = (double)(value / 1000000000.0);
1427     else
1428         cal_exposureTime = 60.00;
1429     return getRationalExposureTime(expoTimeInfo, 1, cal_exposureTime);
1430 }
1431 
1432 /*===========================================================================
1433  * FUNCTION   : getExifGpsProcessingMethod
1434  *
1435  * DESCRIPTION: get GPS processing method
1436  *
1437  * PARAMETERS :
1438  *   @gpsProcessingMethod : string to store GPS process method
1439  *   @count               : lenght of the string
1440  *
1441  * RETURN     : int32_t type of status
1442  *              NO_ERROR  -- success
1443  *              none-zero failure code
1444  *==========================================================================*/
getExifGpsProcessingMethod(char * gpsProcessingMethod,uint32_t & count,char * value)1445 int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod,
1446                                    uint32_t &count, char* value)
1447 {
1448     if(value != NULL) {
1449         memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
1450         count = EXIF_ASCII_PREFIX_SIZE;
1451         strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value));
1452         count += strlen(value);
1453         gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char
1454         return NO_ERROR;
1455     } else {
1456         return BAD_VALUE;
1457     }
1458 }
1459 
1460 /*===========================================================================
1461  * FUNCTION   : getExifLatitude
1462  *
1463  * DESCRIPTION: get exif latitude
1464  *
1465  * PARAMETERS :
1466  *   @latitude : ptr to rational struct to store latitude info
1467  *   @ladRef   : charater to indicate latitude reference
1468  *
1469  * RETURN     : int32_t type of status
1470  *              NO_ERROR  -- success
1471  *              none-zero failure code
1472  *==========================================================================*/
getExifLatitude(rat_t * latitude,char * latRef,double value)1473 int32_t getExifLatitude(rat_t *latitude,
1474                                            char *latRef, double value)
1475 {
1476     char str[30];
1477     snprintf(str, sizeof(str), "%f", value);
1478     if(str != NULL) {
1479         parseGPSCoordinate(str, latitude);
1480 
1481         //set Latitude Ref
1482         float latitudeValue = strtof(str, 0);
1483         if(latitudeValue < 0.0f) {
1484             latRef[0] = 'S';
1485         } else {
1486             latRef[0] = 'N';
1487         }
1488         latRef[1] = '\0';
1489         return NO_ERROR;
1490     }else{
1491         return BAD_VALUE;
1492     }
1493 }
1494 
1495 /*===========================================================================
1496  * FUNCTION   : getExifLongitude
1497  *
1498  * DESCRIPTION: get exif longitude
1499  *
1500  * PARAMETERS :
1501  *   @longitude : ptr to rational struct to store longitude info
1502  *   @lonRef    : charater to indicate longitude reference
1503  *
1504  * RETURN     : int32_t type of status
1505  *              NO_ERROR  -- success
1506  *              none-zero failure code
1507  *==========================================================================*/
getExifLongitude(rat_t * longitude,char * lonRef,double value)1508 int32_t getExifLongitude(rat_t *longitude,
1509                                             char *lonRef, double value)
1510 {
1511     char str[30];
1512     snprintf(str, sizeof(str), "%f", value);
1513     if(str != NULL) {
1514         parseGPSCoordinate(str, longitude);
1515 
1516         //set Longitude Ref
1517         float longitudeValue = strtof(str, 0);
1518         if(longitudeValue < 0.0f) {
1519             lonRef[0] = 'W';
1520         } else {
1521             lonRef[0] = 'E';
1522         }
1523         lonRef[1] = '\0';
1524         return NO_ERROR;
1525     }else{
1526         return BAD_VALUE;
1527     }
1528 }
1529 
1530 /*===========================================================================
1531  * FUNCTION   : getExifAltitude
1532  *
1533  * DESCRIPTION: get exif altitude
1534  *
1535  * PARAMETERS :
1536  *   @altitude : ptr to rational struct to store altitude info
1537  *   @altRef   : charater to indicate altitude reference
1538  *
1539  * RETURN     : int32_t type of status
1540  *              NO_ERROR  -- success
1541  *              none-zero failure code
1542  *==========================================================================*/
getExifAltitude(rat_t * altitude,char * altRef,double value)1543 int32_t getExifAltitude(rat_t *altitude,
1544                                            char *altRef, double value)
1545 {
1546     char str[30];
1547     snprintf(str, sizeof(str), "%f", value);
1548     if(str != NULL) {
1549         double value = atof(str);
1550         *altRef = 0;
1551         if(value < 0){
1552             *altRef = 1;
1553             value = -value;
1554         }
1555         return getRational(altitude, value*1000, 1000);
1556     }else{
1557         return BAD_VALUE;
1558     }
1559 }
1560 
1561 /*===========================================================================
1562  * FUNCTION   : getExifGpsDateTimeStamp
1563  *
1564  * DESCRIPTION: get exif GPS date time stamp
1565  *
1566  * PARAMETERS :
1567  *   @gpsDateStamp : GPS date time stamp string
1568  *   @bufLen       : length of the string
1569  *   @gpsTimeStamp : ptr to rational struct to store time stamp info
1570  *
1571  * RETURN     : int32_t type of status
1572  *              NO_ERROR  -- success
1573  *              none-zero failure code
1574  *==========================================================================*/
getExifGpsDateTimeStamp(char * gpsDateStamp,uint32_t bufLen,rat_t * gpsTimeStamp,int64_t value)1575 int32_t getExifGpsDateTimeStamp(char *gpsDateStamp,
1576                                            uint32_t bufLen,
1577                                            rat_t *gpsTimeStamp, int64_t value)
1578 {
1579     char str[30];
1580     snprintf(str, sizeof(str), "%lld", value);
1581     if(str != NULL) {
1582         time_t unixTime = (time_t)atol(str);
1583         struct tm *UTCTimestamp = gmtime(&unixTime);
1584 
1585         strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp);
1586 
1587         getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1);
1588         getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1);
1589         getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1);
1590 
1591         return NO_ERROR;
1592     } else {
1593         return BAD_VALUE;
1594     }
1595 }
1596 
getExifExposureValue(srat_t * exposure_val,int32_t exposure_comp,cam_rational_type_t step)1597 int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp,
1598                              cam_rational_type_t step)
1599 {
1600     exposure_val->num = exposure_comp * step.numerator;
1601     exposure_val->denom = step.denominator;
1602     return 0;
1603 }
1604 /*===========================================================================
1605  * FUNCTION   : getExifData
1606  *
1607  * DESCRIPTION: get exif data to be passed into jpeg encoding
1608  *
1609  * PARAMETERS : none
1610  *
1611  * RETURN     : exif data from user setting and GPS
1612  *==========================================================================*/
getExifData()1613 QCamera3Exif *QCamera3PicChannel::getExifData()
1614 {
1615     QCamera3Exif *exif = new QCamera3Exif();
1616     if (exif == NULL) {
1617         ALOGE("%s: No memory for QCamera3Exif", __func__);
1618         return NULL;
1619     }
1620 
1621     int32_t rc = NO_ERROR;
1622     uint32_t count = 0;
1623 
1624     // add exif entries
1625     char dateTime[20];
1626     memset(dateTime, 0, sizeof(dateTime));
1627     count = 20;
1628     rc = getExifDateTime(dateTime, count);
1629     if(rc == NO_ERROR) {
1630         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL,
1631                        EXIF_ASCII,
1632                        count,
1633                        (void *)dateTime);
1634         exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED,
1635                        EXIF_ASCII,
1636                        count,
1637                        (void *)dateTime);
1638     } else {
1639         ALOGE("%s: getExifDateTime failed", __func__);
1640     }
1641 
1642     rat_t focalLength;
1643     rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length);
1644     if (rc == NO_ERROR) {
1645         exif->addEntry(EXIFTAGID_FOCAL_LENGTH,
1646                        EXIF_RATIONAL,
1647                        1,
1648                        (void *)&(focalLength));
1649     } else {
1650         ALOGE("%s: getExifFocalLength failed", __func__);
1651     }
1652 
1653     uint16_t isoSpeed = (uint16_t)mJpegSettings->sensor_sensitivity;
1654     if(isoSpeed == 0) {
1655         isoSpeed = (uint16_t)(mJpegSettings->lens_focal_length + 0.5)*100;
1656     }
1657 
1658     exif->addEntry(EXIFTAGID_ISO_SPEED_RATING,
1659                    EXIF_SHORT,
1660                    1,
1661                    (void *)&(isoSpeed));
1662 
1663     rat_t sensorExpTime, temp;
1664     rc = getExifExpTimeInfo(&sensorExpTime, (int64_t)mJpegSettings->sensor_exposure_time);
1665     if(sensorExpTime.denom <= 0) {// avoid zero-divide problem
1666         sensorExpTime.denom  = 0.01668; // expoure time will be 1/60 s
1667         uint16_t temp2 = (uint16_t)(sensorExpTime.denom <= 0 * 100000);
1668         temp2 = (uint16_t)(100000 / temp2);
1669         temp.num = 1;
1670         temp.denom = temp2;
1671         memcpy(&sensorExpTime, &temp, sizeof(sensorExpTime));
1672     }
1673     exif->addEntry(EXIFTAGID_EXPOSURE_TIME,
1674                     EXIF_LONG,
1675                     1,
1676                     (void *) &(sensorExpTime.denom));
1677 
1678     if (strlen(mJpegSettings->gps_processing_method) > 0) {
1679         char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
1680         count = 0;
1681         rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method);
1682         if(rc == NO_ERROR) {
1683             exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
1684                            EXIF_ASCII,
1685                            count,
1686                            (void *)gpsProcessingMethod);
1687         } else {
1688             ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
1689         }
1690     }
1691 
1692     if (mJpegSettings->gps_coordinates[0]) {
1693         rat_t latitude[3];
1694         char latRef[2];
1695         rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0]));
1696         if(rc == NO_ERROR) {
1697             exif->addEntry(EXIFTAGID_GPS_LATITUDE,
1698                            EXIF_RATIONAL,
1699                            3,
1700                            (void *)latitude);
1701             exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
1702                            EXIF_ASCII,
1703                            2,
1704                            (void *)latRef);
1705         } else {
1706             ALOGE("%s: getExifLatitude failed", __func__);
1707         }
1708     }
1709 
1710     if (mJpegSettings->gps_coordinates[1]) {
1711         rat_t longitude[3];
1712         char lonRef[2];
1713         rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1]));
1714         if(rc == NO_ERROR) {
1715             exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
1716                            EXIF_RATIONAL,
1717                            3,
1718                            (void *)longitude);
1719 
1720             exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
1721                            EXIF_ASCII,
1722                            2,
1723                            (void *)lonRef);
1724         } else {
1725             ALOGE("%s: getExifLongitude failed", __func__);
1726         }
1727     }
1728 
1729     if (mJpegSettings->gps_coordinates[2]) {
1730         rat_t altitude;
1731         char altRef;
1732         rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2]));
1733         if(rc == NO_ERROR) {
1734             exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
1735                            EXIF_RATIONAL,
1736                            1,
1737                            (void *)&(altitude));
1738 
1739             exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
1740                            EXIF_BYTE,
1741                            1,
1742                            (void *)&altRef);
1743         } else {
1744             ALOGE("%s: getExifAltitude failed", __func__);
1745         }
1746     }
1747 
1748     if (mJpegSettings->gps_timestamp) {
1749         char gpsDateStamp[20];
1750         rat_t gpsTimeStamp[3];
1751         rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp));
1752         if(rc == NO_ERROR) {
1753             exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
1754                            EXIF_ASCII,
1755                            strlen(gpsDateStamp) + 1,
1756                            (void *)gpsDateStamp);
1757 
1758             exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
1759                            EXIF_RATIONAL,
1760                            3,
1761                            (void *)gpsTimeStamp);
1762         } else {
1763             ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
1764         }
1765     }
1766 
1767     srat_t exposure_val;
1768     rc = getExifExposureValue(&exposure_val, mJpegSettings->exposure_compensation,
1769                               mJpegSettings->exposure_comp_step);
1770     if(rc == NO_ERROR) {
1771         exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE,
1772                        EXIF_SRATIONAL,
1773                        1,
1774                        (void *)(&exposure_val));
1775     } else {
1776         ALOGE("%s: getExifExposureValue failed ", __func__);
1777     }
1778 
1779     char value[PROPERTY_VALUE_MAX];
1780     if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) {
1781         exif->addEntry(EXIFTAGID_MAKE,
1782                        EXIF_ASCII,
1783                        strlen(value) + 1,
1784                        (void *)value);
1785     } else {
1786         ALOGE("%s: getExifMaker failed", __func__);
1787     }
1788 
1789     if (property_get("ro.product.model", value, "QCAM-AA") > 0) {
1790         exif->addEntry(EXIFTAGID_MODEL,
1791                        EXIF_ASCII,
1792                        strlen(value) + 1,
1793                        (void *)value);
1794     } else {
1795         ALOGE("%s: getExifModel failed", __func__);
1796     }
1797 
1798     float f_number = 0.0f;
1799     f_number = mJpegSettings->f_number;
1800     rat_t aperture;
1801     getRational(&aperture, (uint32_t)f_number*F_NUMBER_DECIMAL_PRECISION, (uint32_t)F_NUMBER_DECIMAL_PRECISION);
1802     exif->addEntry(EXIFTAGID_APERTURE,
1803                        EXIF_RATIONAL,
1804                        1,
1805                        (void *)&(aperture));
1806 
1807     exif->addEntry(EXIFTAGID_F_NUMBER,
1808                        EXIF_RATIONAL,
1809                        1,
1810                        (void *)&(aperture));
1811 
1812     uint16_t flash = mJpegSettings->flash;
1813     exif->addEntry(EXIFTAGID_FLASH,
1814                    EXIF_SHORT, 1,
1815                    (void *)&(flash));
1816 
1817     int wb;
1818     short val_short;
1819     wb = mJpegSettings->wb;
1820     if(wb == CAM_WB_MODE_AUTO)
1821         val_short = 0;
1822     else
1823         val_short = 1;
1824 
1825     exif->addEntry(EXIFTAGID_WHITE_BALANCE,
1826                        EXIF_SHORT,
1827                        1,
1828                        (void *)&(wb));
1829 
1830     struct timeval tv;
1831     char subsecTime[7];
1832     gettimeofday(&tv, NULL);
1833     snprintf(subsecTime, 7, "%06ld", tv.tv_usec);
1834 
1835     exif->addEntry(EXIFTAGID_SUBSEC_TIME,
1836                    EXIF_ASCII, 7,
1837                    (void *)subsecTime);
1838 
1839     exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL,
1840                    EXIF_ASCII, 7,
1841                    (void *)subsecTime);
1842 
1843     exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED,
1844                    EXIF_ASCII, 7,
1845                    (void *)subsecTime);
1846 
1847     return exif;
1848 }
1849 
1850 int QCamera3PicChannel::kMaxBuffers = 2;
1851 
1852 /*===========================================================================
1853  * FUNCTION   : QCamera3ReprocessChannel
1854  *
1855  * DESCRIPTION: constructor of QCamera3ReprocessChannel
1856  *
1857  * PARAMETERS :
1858  *   @cam_handle : camera handle
1859  *   @cam_ops    : ptr to camera ops table
1860  *   @pp_mask    : post-proccess feature mask
1861  *
1862  * RETURN     : none
1863  *==========================================================================*/
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)1864 QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle,
1865                                                  mm_camera_ops_t *cam_ops,
1866                                                  channel_cb_routine cb_routine,
1867                                                  cam_padding_info_t *paddingInfo,
1868                                                  void *userData, void *ch_hdl) :
1869     QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData),
1870     picChHandle(ch_hdl),
1871     m_pSrcChannel(NULL),
1872     m_pMetaChannel(NULL),
1873     m_metaFrame(NULL),
1874     mMemory(NULL)
1875 {
1876     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
1877 }
1878 
1879 
1880 /*===========================================================================
1881  * FUNCTION   : QCamera3ReprocessChannel
1882  *
1883  * DESCRIPTION: constructor of QCamera3ReprocessChannel
1884  *
1885  * PARAMETERS :
1886  *   @cam_handle : camera handle
1887  *   @cam_ops    : ptr to camera ops table
1888  *   @pp_mask    : post-proccess feature mask
1889  *
1890  * RETURN     : none
1891  *==========================================================================*/
initialize()1892 int32_t QCamera3ReprocessChannel::initialize()
1893 {
1894     int32_t rc = NO_ERROR;
1895     mm_camera_channel_attr_t attr;
1896 
1897     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
1898     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
1899     attr.max_unmatched_frames = 1;
1900 
1901     rc = init(&attr, NULL);
1902     if (rc < 0) {
1903         ALOGE("%s: init failed", __func__);
1904     }
1905     return rc;
1906 }
1907 
1908 
1909 /*===========================================================================
1910  * FUNCTION   : QCamera3ReprocessChannel
1911  *
1912  * DESCRIPTION: constructor of QCamera3ReprocessChannel
1913  *
1914  * PARAMETERS :
1915  *   @cam_handle : camera handle
1916  *   @cam_ops    : ptr to camera ops table
1917  *   @pp_mask    : post-proccess feature mask
1918  *
1919  * RETURN     : none
1920  *==========================================================================*/
streamCbRoutine(mm_camera_super_buf_t * super_frame,QCamera3Stream * stream)1921 void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
1922                                   QCamera3Stream *stream)
1923 {
1924     //Got the pproc data callback. Now send to jpeg encoding
1925     uint8_t frameIndex;
1926     mm_camera_super_buf_t* frame = NULL;
1927     QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle;
1928 
1929     if(!super_frame) {
1930          ALOGE("%s: Invalid Super buffer",__func__);
1931          return;
1932     }
1933 
1934     if(super_frame->num_bufs != 1) {
1935          ALOGE("%s: Multiple streams are not supported",__func__);
1936          return;
1937     }
1938     if(super_frame->bufs[0] == NULL ) {
1939          ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
1940                   __func__);
1941          return;
1942     }
1943 
1944     frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
1945     frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
1946     if (frame == NULL) {
1947        ALOGE("%s: Error allocating memory to save received_frame structure.",
1948                                                                     __func__);
1949        if(stream) {
1950            stream->bufDone(frameIndex);
1951        }
1952        return;
1953     }
1954     *frame = *super_frame;
1955     //queue back the metadata buffer
1956     if (m_metaFrame != NULL) {
1957        ((QCamera3MetadataChannel*)m_pMetaChannel)->bufDone(m_metaFrame);
1958        free(m_metaFrame);
1959        m_metaFrame = NULL;
1960     } else {
1961        ALOGE("%s: Meta frame was NULL", __func__);
1962     }
1963     obj->m_postprocessor.processPPData(frame);
1964     return;
1965 }
1966 
1967 /*===========================================================================
1968  * FUNCTION   : QCamera3ReprocessChannel
1969  *
1970  * DESCRIPTION: default constructor of QCamera3ReprocessChannel
1971  *
1972  * PARAMETERS : none
1973  *
1974  * RETURN     : none
1975  *==========================================================================*/
QCamera3ReprocessChannel()1976 QCamera3ReprocessChannel::QCamera3ReprocessChannel() :
1977     m_pSrcChannel(NULL),
1978     m_pMetaChannel(NULL),
1979     m_metaFrame(NULL)
1980 {
1981 }
1982 
1983 /*===========================================================================
1984  * FUNCTION   : QCamera3ReprocessChannel
1985  *
1986  * DESCRIPTION: register the buffers of the reprocess channel
1987  *
1988  * PARAMETERS : none
1989  *
1990  * RETURN     : none
1991  *==========================================================================*/
registerBuffers(uint32_t num_buffers,buffer_handle_t ** buffers)1992 int32_t QCamera3ReprocessChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
1993 {
1994    return 0;
1995 }
1996 
1997 /*===========================================================================
1998  * FUNCTION   : getStreamBufs
1999  *
2000  * DESCRIPTION: register the buffers of the reprocess channel
2001  *
2002  * PARAMETERS : none
2003  *
2004  * RETURN     : QCamera3Memory *
2005  *==========================================================================*/
getStreamBufs(uint32_t len)2006 QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len)
2007 {
2008    int rc = 0;
2009 
2010     mMemory = new QCamera3HeapMemory();
2011     if (!mMemory) {
2012         ALOGE("%s: unable to create reproc memory", __func__);
2013         return NULL;
2014     }
2015 
2016     //Queue YUV buffers in the beginning mQueueAll = true
2017     rc = mMemory->allocate(2, len, true);
2018     if (rc < 0) {
2019         ALOGE("%s: unable to allocate reproc memory", __func__);
2020         delete mMemory;
2021         mMemory = NULL;
2022         return NULL;
2023     }
2024     return mMemory;
2025 }
2026 
2027 /*===========================================================================
2028  * FUNCTION   : getStreamBufs
2029  *
2030  * DESCRIPTION: register the buffers of the reprocess channel
2031  *
2032  * PARAMETERS : none
2033  *
2034  * RETURN     :
2035  *==========================================================================*/
putStreamBufs()2036 void QCamera3ReprocessChannel::putStreamBufs()
2037 {
2038     mMemory->deallocate();
2039     delete mMemory;
2040     mMemory = NULL;
2041 }
2042 
2043 /*===========================================================================
2044  * FUNCTION   : ~QCamera3ReprocessChannel
2045  *
2046  * DESCRIPTION: destructor of QCamera3ReprocessChannel
2047  *
2048  * PARAMETERS : none
2049  *
2050  * RETURN     : none
2051  *==========================================================================*/
~QCamera3ReprocessChannel()2052 QCamera3ReprocessChannel::~QCamera3ReprocessChannel()
2053 {
2054 }
2055 
2056 /*===========================================================================
2057  * FUNCTION   : getStreamBySourceHandle
2058  *
2059  * DESCRIPTION: find reprocess stream by its source stream handle
2060  *
2061  * PARAMETERS :
2062  *   @srcHandle : source stream handle
2063  *
2064  * RETURN     : ptr to reprocess stream if found. NULL if not found
2065  *==========================================================================*/
getStreamBySourceHandle(uint32_t srcHandle)2066 QCamera3Stream * QCamera3ReprocessChannel::getStreamBySourceHandle(uint32_t srcHandle)
2067 {
2068     QCamera3Stream *pStream = NULL;
2069 
2070     for (int i = 0; i < m_numStreams; i++) {
2071         if (mSrcStreamHandles[i] == srcHandle) {
2072             pStream = mStreams[i];
2073             break;
2074         }
2075     }
2076     return pStream;
2077 }
2078 
2079 /*===========================================================================
2080  * FUNCTION   : doReprocess
2081  *
2082  * DESCRIPTION: request to do a reprocess on the frame
2083  *
2084  * PARAMETERS :
2085  *   @frame   : frame to be performed a reprocess
2086  *
2087  * RETURN     : int32_t type of status
2088  *              NO_ERROR  -- success
2089  *              none-zero failure code
2090  *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame,mm_camera_super_buf_t * meta_frame)2091 int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
2092                                               mm_camera_super_buf_t *meta_frame)
2093 {
2094     int32_t rc = 0;
2095     if (m_numStreams < 1) {
2096         ALOGE("%s: No reprocess stream is created", __func__);
2097         return -1;
2098     }
2099     if (m_pSrcChannel == NULL) {
2100         ALOGE("%s: No source channel for reprocess", __func__);
2101         return -1;
2102     }
2103     m_metaFrame = meta_frame;
2104     for (int i = 0; i < frame->num_bufs; i++) {
2105         QCamera3Stream *pStream = getStreamBySourceHandle(frame->bufs[i]->stream_id);
2106         if (pStream != NULL) {
2107             cam_stream_parm_buffer_t param;
2108             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
2109             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
2110             param.reprocess.buf_index = frame->bufs[i]->buf_idx;
2111             param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
2112             if (meta_frame != NULL) {
2113                param.reprocess.meta_present = 1;
2114                param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID();
2115                param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx;
2116             }
2117             rc = pStream->setParameter(param);
2118             if (rc != NO_ERROR) {
2119                 ALOGE("%s: stream setParameter for reprocess failed", __func__);
2120                 break;
2121             }
2122         }
2123     }
2124     return rc;
2125 }
2126 
2127 /*===========================================================================
2128  * FUNCTION   : doReprocess
2129  *
2130  * DESCRIPTION: request to do a reprocess on the frame
2131  *
2132  * PARAMETERS :
2133  *   @buf_fd     : fd to the input buffer that needs reprocess
2134  *   @buf_lenght : length of the input buffer
2135  *   @ret_val    : result of reprocess.
2136  *                 Example: Could be faceID in case of register face image.
2137  *
2138  * RETURN     : int32_t type of status
2139  *              NO_ERROR  -- success
2140  *              none-zero failure code
2141  *==========================================================================*/
doReprocess(int buf_fd,uint32_t buf_length,int32_t & ret_val,mm_camera_super_buf_t * meta_frame)2142 int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd,
2143                                               uint32_t buf_length,
2144                                               int32_t &ret_val,
2145                                               mm_camera_super_buf_t *meta_frame)
2146 {
2147     int32_t rc = 0;
2148     if (m_numStreams < 1) {
2149         ALOGE("%s: No reprocess stream is created", __func__);
2150         return -1;
2151     }
2152     if (meta_frame == NULL) {
2153         ALOGE("%s: Did not get corresponding metadata in time", __func__);
2154         return -1;
2155     }
2156 
2157     uint32_t buf_idx = 0;
2158     for (int i = 0; i < m_numStreams; i++) {
2159         rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
2160                                  buf_idx, -1,
2161                                  buf_fd, buf_length);
2162 
2163         if (rc == NO_ERROR) {
2164             cam_stream_parm_buffer_t param;
2165             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
2166             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
2167             param.reprocess.buf_index = buf_idx;
2168             param.reprocess.meta_present = 1;
2169             param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID();
2170             param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx;
2171             rc = mStreams[i]->setParameter(param);
2172             if (rc == NO_ERROR) {
2173                 ret_val = param.reprocess.ret_val;
2174             }
2175             mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
2176                                   buf_idx, -1);
2177         }
2178     }
2179     return rc;
2180 }
2181 
2182 /*===========================================================================
2183  * FUNCTION   : addReprocStreamsFromSource
2184  *
2185  * DESCRIPTION: add reprocess streams from input source channel
2186  *
2187  * PARAMETERS :
2188  *   @config         : pp feature configuration
2189  *   @pSrcChannel    : ptr to input source channel that needs reprocess
2190  *   @pMetaChannel   : ptr to metadata channel to get corresp. metadata
2191  *
2192  * RETURN     : int32_t type of status
2193  *              NO_ERROR  -- success
2194  *              none-zero failure code
2195  *==========================================================================*/
addReprocStreamsFromSource(cam_pp_feature_config_t & config,QCamera3Channel * pSrcChannel,QCamera3Channel * pMetaChannel)2196 int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &config,
2197                                                              QCamera3Channel *pSrcChannel,
2198                                                              QCamera3Channel *pMetaChannel)
2199 {
2200     int32_t rc = 0;
2201     QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0);
2202     if (pSrcStream == NULL) {
2203        ALOGE("%s: source channel doesn't have a stream", __func__);
2204        return BAD_VALUE;
2205     }
2206     cam_stream_reproc_config_t reprocess_config;
2207     cam_dimension_t streamDim;
2208     cam_stream_type_t streamType;
2209     cam_format_t streamFormat;
2210     cam_frame_len_offset_t frameOffset;
2211     int num_buffers = 2;
2212 
2213     streamType = CAM_STREAM_TYPE_OFFLINE_PROC;
2214     pSrcStream->getFormat(streamFormat);
2215     pSrcStream->getFrameDimension(streamDim);
2216     pSrcStream->getFrameOffset(frameOffset);
2217 
2218     reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
2219     reprocess_config.online.input_stream_id = pSrcStream->getMyServerID();
2220     reprocess_config.online.input_stream_type = pSrcStream->getMyType();
2221     reprocess_config.pp_feature_config = config;
2222 
2223     mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle();
2224 
2225     if (reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
2226         if (reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
2227             reprocess_config.pp_feature_config.rotation == ROTATE_270) {
2228             // rotated by 90 or 270, need to switch width and height
2229             int32_t temp = streamDim.height;
2230             streamDim.height = streamDim.width;
2231             streamDim.width = temp;
2232         }
2233     }
2234 
2235     QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
2236                                                m_handle,
2237                                                m_camOps,
2238                                                mPaddingInfo,
2239                                                (QCamera3Channel*)this);
2240     if (pStream == NULL) {
2241         ALOGE("%s: No mem for Stream", __func__);
2242         return NO_MEMORY;
2243     }
2244 
2245     rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config,
2246                        num_buffers,QCamera3Channel::streamCbRoutine, this);
2247 
2248 
2249     if (rc == 0) {
2250         mStreams[m_numStreams] = pStream;
2251         m_numStreams++;
2252     } else {
2253         ALOGE("%s: failed to create reprocess stream", __func__);
2254         delete pStream;
2255     }
2256 
2257     if (rc == NO_ERROR) {
2258         m_pSrcChannel = pSrcChannel;
2259         m_pMetaChannel = pMetaChannel;
2260     }
2261     if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) {
2262         ALOGE("%s: Request for super buffer failed",__func__);
2263     }
2264     return rc;
2265 }
2266 
2267 
2268 }; // namespace qcamera
2269