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