1 /* Copyright (c) 2012-2016, The Linux Foundation. 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 "QCameraChannel"
31 
32 // System dependencies
33 #include <utils/Errors.h>
34 
35 // Camera dependencies
36 #include "QCamera2HWI.h"
37 
38 extern "C" {
39 #include "mm_camera_dbg.h"
40 }
41 
42 using namespace android;
43 
44 namespace qcamera {
45 
46 /*===========================================================================
47  * FUNCTION   : QCameraChannel
48  *
49  * DESCRIPTION: constrcutor of QCameraChannel
50  *
51  * PARAMETERS :
52  *   @cam_handle : camera handle
53  *   @cam_ops    : ptr to camera ops table
54  *
55  * RETURN     : none
56  *==========================================================================*/
QCameraChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)57 QCameraChannel::QCameraChannel(uint32_t cam_handle,
58                                mm_camera_ops_t *cam_ops)
59 {
60     m_camHandle = cam_handle;
61     m_camOps = cam_ops;
62     m_bIsActive = false;
63     m_bAllowDynBufAlloc = false;
64 
65     m_handle = 0;
66 }
67 
68 /*===========================================================================
69  * FUNCTION   : QCameraChannel
70  *
71  * DESCRIPTION: default constrcutor of QCameraChannel
72  *
73  * PARAMETERS : none
74  *
75  * RETURN     : none
76  *==========================================================================*/
QCameraChannel()77 QCameraChannel::QCameraChannel()
78 {
79     m_camHandle = 0;
80     m_camOps = NULL;
81     m_bIsActive = false;
82 
83     m_handle = 0;
84 }
85 
86 /*===========================================================================
87  * FUNCTION   : ~QCameraChannel
88  *
89  * DESCRIPTION: destructor of QCameraChannel
90  *
91  * PARAMETERS : none
92  *
93  * RETURN     : none
94  *==========================================================================*/
~QCameraChannel()95 QCameraChannel::~QCameraChannel()
96 {
97     if (m_bIsActive) {
98         stop();
99     }
100     for (size_t i = 0; i < mStreams.size(); i++) {
101         if (mStreams[i] != NULL) {
102                 if (m_handle == mStreams[i]->getChannelHandle()) {
103                     delete mStreams[i];
104                 }
105         }
106     }
107     mStreams.clear();
108     m_camOps->delete_channel(m_camHandle, m_handle);
109     m_handle = 0;
110 }
111 
112 /*===========================================================================
113  * FUNCTION   : deleteChannel
114  *
115  * DESCRIPTION: deletes a camera channel
116  *
117  * PARAMETERS : none
118  *
119  * RETURN     : none
120  *==========================================================================*/
deleteChannel()121 void QCameraChannel::deleteChannel()
122 {
123     if (m_bIsActive) {
124         stop();
125     }
126     for (size_t i = 0; i < mStreams.size(); i++) {
127         if ((mStreams[i] != NULL) && (m_handle == mStreams[i]->getChannelHandle())) {
128             mStreams[i]->deleteStream();
129         }
130     }
131     m_camOps->delete_channel(m_camHandle, m_handle);
132 }
133 
134 /*===========================================================================
135  * FUNCTION   : setStreamSyncCB
136  *
137  * DESCRIPTION: reg callback function to stream of stream type
138  *
139  * PARAMETERS :
140  *    @stream_type : Stream type for which callback needs to be registered.
141  *    @stream_cb   : Callback function
142 
143  * RETURN     : int32_t type of status
144  *              NO_ERROR  -- success
145  *              non-zero failure code
146  *==========================================================================*/
setStreamSyncCB(cam_stream_type_t stream_type,stream_cb_routine stream_cb)147 int32_t QCameraChannel::setStreamSyncCB (cam_stream_type_t stream_type,
148         stream_cb_routine stream_cb)
149 {
150     int32_t rc = UNKNOWN_ERROR;
151     for (size_t i = 0; i < mStreams.size(); i++) {
152         if ((mStreams[i] != NULL) && (stream_type == mStreams[i]->getMyType())) {
153             rc = mStreams[i]->setSyncDataCB(stream_cb);
154             break;
155         }
156     }
157     return rc;
158 }
159 
160 /*===========================================================================
161  * FUNCTION   : init
162  *
163  * DESCRIPTION: initialization of channel
164  *
165  * PARAMETERS :
166  *   @attr    : channel bundle attribute setting
167  *   @dataCB  : data notify callback
168  *   @userData: user data ptr
169  *
170  * RETURN     : int32_t type of status
171  *              NO_ERROR  -- success
172  *              none-zero failure code
173  *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)174 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
175                              mm_camera_buf_notify_t dataCB,
176                              void *userData)
177 {
178     m_handle = m_camOps->add_channel(m_camHandle,
179                                       attr,
180                                       dataCB,
181                                       userData);
182     if (m_handle == 0) {
183         LOGE("Add channel failed");
184         return UNKNOWN_ERROR;
185     }
186     return NO_ERROR;
187 }
188 
189 /*===========================================================================
190  * FUNCTION   : addStream
191  *
192  * DESCRIPTION: add a stream into channel
193  *
194  * PARAMETERS :
195  *   @allocator      : stream related buffer allocator
196  *   @streamInfoBuf  : ptr to buf that contains stream info
197  *   @miscBuf        : ptr to buf that contains misc buffers
198  *   @minStreamBufNum: number of stream buffers needed
199  *   @paddingInfo    : padding information
200  *   @stream_cb      : stream data notify callback
201  *   @userdata       : user data ptr
202  *   @bDynAllocBuf   : flag indicating if allow allocate buffers in 2 steps
203  *   @online_rotation: rotation applied online
204  *
205  * RETURN     : int32_t type of status
206  *              NO_ERROR  -- success
207  *              none-zero failure code
208  *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,QCameraHeapMemory * miscBuf,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata,bool bDynAllocBuf,bool bDeffAlloc,cam_rotation_t online_rotation)209 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
210         QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf,
211         uint8_t minStreamBufNum, cam_padding_info_t *paddingInfo,
212         stream_cb_routine stream_cb, void *userdata, bool bDynAllocBuf,
213         bool bDeffAlloc, cam_rotation_t online_rotation)
214 {
215     int32_t rc = NO_ERROR;
216     if (mStreams.size() >= MAX_STREAM_NUM_IN_BUNDLE) {
217         LOGE("stream number (%zu) exceeds max limit (%d)",
218                mStreams.size(), MAX_STREAM_NUM_IN_BUNDLE);
219         if (streamInfoBuf != NULL) {
220             streamInfoBuf->deallocate();
221             delete streamInfoBuf;
222             streamInfoBuf = NULL;
223         }
224         return BAD_VALUE;
225     }
226     QCameraStream *pStream = new QCameraStream(allocator,
227             m_camHandle, m_handle, m_camOps, paddingInfo, bDeffAlloc,
228             online_rotation);
229     if (pStream == NULL) {
230         LOGE("No mem for Stream");
231         if (streamInfoBuf != NULL) {
232             streamInfoBuf->deallocate();
233             delete streamInfoBuf;
234             streamInfoBuf = NULL;
235         }
236         return NO_MEMORY;
237     }
238 
239     rc = pStream->init(streamInfoBuf, miscBuf, minStreamBufNum,
240                        stream_cb, userdata, bDynAllocBuf);
241     if (rc == 0) {
242         mStreams.add(pStream);
243     } else {
244         delete pStream;
245     }
246     return rc;
247 }
248 
249 /*===========================================================================
250  * FUNCTION   : linkStream
251  *
252  * DESCRIPTION: link a stream into channel
253  *
254  * PARAMETERS :
255  *   @ch      : Channel which the stream belongs to
256  *   @stream  : Stream which needs to be linked
257  *
258  * RETURN     : int32_t type of status
259  *              NO_ERROR  -- success
260  *              none-zero failure code
261  *==========================================================================*/
linkStream(QCameraChannel * ch,QCameraStream * stream)262 int32_t QCameraChannel::linkStream(QCameraChannel *ch, QCameraStream *stream)
263 {
264     int32_t rc = NO_ERROR;
265 
266     if ((0 == m_handle) || (NULL == ch) || (NULL == stream)) {
267         return NO_INIT;
268     }
269 
270     int32_t handle = m_camOps->link_stream(m_camHandle,
271             ch->getMyHandle(),
272             stream->getMyHandle(),
273             m_handle);
274     if (0 == handle) {
275         LOGE("Linking of stream failed");
276         rc = INVALID_OPERATION;
277     } else {
278         mStreams.add(stream);
279     }
280 
281     return rc;
282 }
283 
284 /*===========================================================================
285  * FUNCTION   : start
286  *
287  * DESCRIPTION: start channel, which will start all streams belong to this channel
288  *
289  * PARAMETERS : None
290  *
291  * RETURN     : int32_t type of status
292  *              NO_ERROR  -- success
293  *              none-zero failure code
294  *==========================================================================*/
start()295 int32_t QCameraChannel::start()
296 {
297     int32_t rc = NO_ERROR;
298 
299     if(m_bIsActive) {
300         LOGW("Attempt to start active channel");
301         return rc;
302     }
303     if (mStreams.size() > 1) {
304         // there is more than one stream in the channel
305         // we need to notify mctl that all streams in this channel need to be bundled
306         cam_bundle_config_t bundleInfo;
307         memset(&bundleInfo, 0, sizeof(bundleInfo));
308         rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
309         if (rc != NO_ERROR) {
310             LOGE("get_bundle_info failed");
311             return rc;
312         }
313         if (bundleInfo.num_of_streams > 1) {
314             for (int i = 0; i < bundleInfo.num_of_streams; i++) {
315                 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
316                 if (pStream != NULL) {
317                     if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
318                             || (pStream->isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) {
319                         // Skip metadata for reprocess now because PP module cannot handle meta data
320                         // May need furthur discussion if Imaginglib need meta data
321                         continue;
322                     }
323 
324                     cam_stream_parm_buffer_t param;
325                     memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
326                     param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
327                     param.bundleInfo = bundleInfo;
328                     rc = pStream->setParameter(param);
329                     if (rc != NO_ERROR) {
330                         LOGE("stream setParameter for set bundle failed");
331                         return rc;
332                     }
333                 }
334             }
335         }
336     }
337 
338     for (size_t i = 0; i < mStreams.size(); i++) {
339         if ((mStreams[i] != NULL) &&
340                 (m_handle == mStreams[i]->getChannelHandle())) {
341             mStreams[i]->start();
342         }
343     }
344     rc = m_camOps->start_channel(m_camHandle, m_handle);
345 
346     if (rc != NO_ERROR) {
347         for (size_t i = 0; i < mStreams.size(); i++) {
348             if ((mStreams[i] != NULL) &&
349                     (m_handle == mStreams[i]->getChannelHandle())) {
350                 mStreams[i]->stop();
351             }
352         }
353     } else {
354         m_bIsActive = true;
355         for (size_t i = 0; i < mStreams.size(); i++) {
356             if (mStreams[i] != NULL) {
357                 mStreams[i]->cond_signal();
358             }
359         }
360     }
361 
362     return rc;
363 }
364 
365 /*===========================================================================
366  * FUNCTION   : stop
367  *
368  * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
369  *
370  * PARAMETERS : none
371  *
372  * RETURN     : int32_t type of status
373  *              NO_ERROR  -- success
374  *              none-zero failure code
375  *==========================================================================*/
stop()376 int32_t QCameraChannel::stop()
377 {
378     int32_t rc = NO_ERROR;
379     size_t i = 0;
380 
381     if (!m_bIsActive) {
382         return NO_INIT;
383     }
384 
385     while(i < mStreams.size()) {
386         if (mStreams[i] != NULL) {
387             if (m_handle == mStreams[i]->getChannelHandle()) {
388                 mStreams[i]->stop();
389                 i++;
390             } else {
391                 // Remove linked stream from stream list
392                 mStreams.removeAt(i);
393             }
394         }
395     }
396 
397     rc = m_camOps->stop_channel(m_camHandle, m_handle);
398 
399     m_bIsActive = false;
400     return rc;
401 }
402 
403 /*===========================================================================
404  * FUNCTION   : bufDone
405  *
406  * DESCRIPTION: return a stream buf back to kernel
407  *
408  * PARAMETERS :
409  *   @recvd_frame  : stream buf frame to be returned
410  *
411  * RETURN     : int32_t type of status
412  *              NO_ERROR  -- success
413  *              none-zero failure code
414  *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)415 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
416 {
417     int32_t rc = NO_ERROR;
418     for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
419         if (recvd_frame->bufs[i] != NULL) {
420             for (size_t j = 0; j < mStreams.size(); j++) {
421                 if (mStreams[j] != NULL &&
422                         mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
423                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
424                     break; // break loop j
425                 }
426             }
427         }
428     }
429 
430     return rc;
431 }
432 
433 /*===========================================================================
434  * FUNCTION   : bufDone
435  *
436  * DESCRIPTION: return specified buffer from super buffer to kernel
437  *
438  * PARAMETERS :
439  *   @recvd_frame  : stream buf frame to be returned
440  *   @stream_id      : stream ID of the buffer to be released
441  *
442  * RETURN     : int32_t type of status
443  *              NO_ERROR  -- success
444  *              none-zero failure code
445  *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame,uint32_t stream_id)446 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame, uint32_t stream_id)
447 {
448     int32_t rc = NO_ERROR;
449     int32_t index;
450     for (int32_t i = 0; i < (int32_t)recvd_frame->num_bufs; i++) {
451         index = -1;
452         if ((recvd_frame->bufs[i] != NULL) &&
453                 (recvd_frame->bufs[i]->stream_id == stream_id)) {
454             for (size_t j = 0; j < mStreams.size(); j++) {
455                 if ((mStreams[j] != NULL) &&
456                         (mStreams[j]->getMyHandle() == stream_id)) {
457                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
458                     index = i;
459                     break; // break loop j
460                 }
461             }
462             if ((index >= 0) && (index < (int32_t)recvd_frame->num_bufs)) {
463                 for (int32_t j = index; j < (int32_t)(recvd_frame->num_bufs - 1); j++) {
464                     recvd_frame->bufs[j] = recvd_frame->bufs[j + 1];
465                 }
466                 recvd_frame->num_bufs--;
467                 i--;
468             }
469         }
470     }
471 
472     return rc;
473 }
474 
475 /*===========================================================================
476  * FUNCTION   : processZoomDone
477  *
478  * DESCRIPTION: process zoom done event
479  *
480  * PARAMETERS :
481  *   @previewWindoe : ptr to preview window ops table, needed to set preview
482  *                    crop information
483  *   @crop_info     : crop info as a result of zoom operation
484  *
485  * RETURN     : int32_t type of status
486  *              NO_ERROR  -- success
487  *              none-zero failure code
488  *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)489 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
490                                         cam_crop_data_t &crop_info)
491 {
492     int32_t rc = NO_ERROR;
493     for (size_t i = 0; i < mStreams.size(); i++) {
494         if ((mStreams[i] != NULL) &&
495                 (m_handle == mStreams[i]->getChannelHandle())) {
496             rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
497         }
498     }
499     return rc;
500 }
501 
502 /*===========================================================================
503  * FUNCTION   : getStreamByHandle
504  *
505  * DESCRIPTION: return stream object by stream handle
506  *
507  * PARAMETERS :
508  *   @streamHandle : stream handle
509  *
510  * RETURN     : stream object. NULL if not found
511  *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)512 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
513 {
514     for (size_t i = 0; i < mStreams.size(); i++) {
515         if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
516             return mStreams[i];
517         }
518     }
519     return NULL;
520 }
521 
522 /*===========================================================================
523  * FUNCTION   : getStreamByServerID
524  *
525  * DESCRIPTION: return stream object by stream server ID from daemon
526  *
527  * PARAMETERS :
528  *   @serverID : stream server ID
529  *
530  * RETURN     : stream object. NULL if not found
531  *==========================================================================*/
getStreamByServerID(uint32_t serverID)532 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
533 {
534     for (size_t i = 0; i < mStreams.size(); i++) {
535         if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
536             return mStreams[i];
537         }
538     }
539     return NULL;
540 }
541 
542 /*===========================================================================
543  * FUNCTION   : getStreamByIndex
544  *
545  * DESCRIPTION: return stream object by index of streams in the channel
546  *
547  * PARAMETERS :
548  *   @index : index of stream in the channel
549  *
550  * RETURN     : stream object. NULL if not found
551  *==========================================================================*/
getStreamByIndex(uint32_t index)552 QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index)
553 {
554     if (index >= MAX_STREAM_NUM_IN_BUNDLE) {
555         return NULL;
556     }
557 
558     if (index < mStreams.size()) {
559         return mStreams[index];
560     }
561     return NULL;
562 }
563 
564 /*===========================================================================
565  * FUNCTION   : UpdateStreamBasedParameters
566  *
567  * DESCRIPTION: update any stream based settings from parameters
568  *
569  * PARAMETERS :
570  *   @param   : reference to parameters object
571  *
572  * RETURN     : int32_t type of status
573  *              NO_ERROR  -- success
574  *              none-zero failure code
575  *==========================================================================*/
UpdateStreamBasedParameters(QCameraParametersIntf & param)576 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParametersIntf &param)
577 {
578     int32_t rc = NO_ERROR;
579     if (param.isPreviewFlipChanged()) {
580         // try to find preview stream
581         for (size_t i = 0; i < mStreams.size(); i++) {
582             if ((mStreams[i] != NULL) &&
583                     (m_handle == mStreams[i]->getChannelHandle()) &&
584                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
585                     (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
586                 cam_stream_parm_buffer_t param_buf;
587                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
588                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
589                 param_buf.flipInfo.flip_mask =
590                         (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW);
591                 rc = mStreams[i]->setParameter(param_buf);
592                 if (rc != NO_ERROR) {
593                     LOGW("set preview stream flip failed");
594                 }
595             }
596         }
597     }
598     if (param.isVideoFlipChanged()) {
599         // try to find video stream
600         for (size_t i = 0; i < mStreams.size(); i++) {
601             if ((mStreams[i] != NULL) &&
602                     (m_handle == mStreams[i]->getChannelHandle()) &&
603                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
604                     (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
605                 cam_stream_parm_buffer_t param_buf;
606                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
607                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
608                 param_buf.flipInfo.flip_mask =
609                         (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO);
610                 rc = mStreams[i]->setParameter(param_buf);
611                 if (rc != NO_ERROR) {
612                     LOGW("set video stream flip failed");
613                 }
614             }
615         }
616     }
617     if (param.isSnapshotFlipChanged()) {
618         // try to find snapshot/postview stream
619         for (size_t i = 0; i < mStreams.size(); i++) {
620             if (mStreams[i] != NULL &&
621                     (m_handle == mStreams[i]->getChannelHandle()) &&
622                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
623                      mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
624                      mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
625                  mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) {
626                 cam_stream_parm_buffer_t param_buf;
627                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
628                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
629                 param_buf.flipInfo.flip_mask =
630                         (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
631                 rc = mStreams[i]->setParameter(param_buf);
632                 if (rc != NO_ERROR) {
633                     LOGW("set snapshot stream flip failed");
634                 }
635             }
636         }
637     }
638     return rc;
639 }
640 
641 /*===========================================================================
642  * FUNCTION   : QCameraPicChannel
643  *
644  * DESCRIPTION: constructor of QCameraPicChannel
645  *
646  * PARAMETERS :
647  *   @cam_handle : camera handle
648  *   @cam_ops    : ptr to camera ops table
649  *
650  * RETURN     : none
651  *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)652 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
653                                      mm_camera_ops_t *cam_ops) :
654     QCameraChannel(cam_handle, cam_ops)
655 {
656     m_bAllowDynBufAlloc = true;
657 }
658 
659 /*===========================================================================
660  * FUNCTION   : QCameraPicChannel
661  *
662  * DESCRIPTION: default constructor of QCameraPicChannel
663  *
664  * PARAMETERS : none
665  *
666  * RETURN     : none
667  *==========================================================================*/
QCameraPicChannel()668 QCameraPicChannel::QCameraPicChannel()
669 {
670     m_bAllowDynBufAlloc = true;
671 }
672 
673 /*===========================================================================
674  * FUNCTION   : ~QCameraPicChannel
675  *
676  * DESCRIPTION: destructor of QCameraPicChannel
677  *
678  * PARAMETERS : none
679  *
680  * RETURN     : none
681  *==========================================================================*/
~QCameraPicChannel()682 QCameraPicChannel::~QCameraPicChannel()
683 {
684 }
685 
686 /*===========================================================================
687  * FUNCTION   : takePicture
688  *
689  * DESCRIPTION: send request for queued snapshot frames
690  *
691  * PARAMETERS :
692  *   @buf : request buf info
693  *
694  * RETURN     : int32_t type of status
695  *              NO_ERROR  -- success
696  *              none-zero failure code
697  *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)698 int32_t QCameraPicChannel::takePicture (mm_camera_req_buf_t *buf)
699 {
700     int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf);
701     return rc;
702 }
703 
704 /*===========================================================================
705  * FUNCTION   : cancelPicture
706  *
707  * DESCRIPTION: cancel request for queued snapshot frames
708  *
709  * PARAMETERS : none
710  *
711  * RETURN     : int32_t type of status
712  *              NO_ERROR  -- success
713  *              none-zero failure code
714  *==========================================================================*/
cancelPicture()715 int32_t QCameraPicChannel::cancelPicture()
716 {
717     int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
718     return rc;
719 }
720 
721 /*===========================================================================
722  * FUNCTION   : stopAdvancedCapture
723  *
724  * DESCRIPTION: stop advanced capture based on advanced capture type.
725  *
726  * PARAMETERS :
727  *   @type : advanced capture type.
728  *
729  * RETURN     : int32_t type of status
730  *              NO_ERROR  -- success
731  *              none-zero failure code
732  *==========================================================================*/
stopAdvancedCapture(mm_camera_advanced_capture_t type)733 int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type)
734 {
735     int32_t rc = m_camOps->process_advanced_capture(m_camHandle,
736             m_handle, type, 0, NULL);
737     return rc;
738 }
739 
740 /*===========================================================================
741  * FUNCTION   : startAdvancedCapture
742  *
743  * DESCRIPTION: start advanced capture based on advanced capture type.
744  *
745  * PARAMETERS :
746  *   @type : advanced capture type.
747  *   @config: advance capture config
748  *
749  * RETURN     : int32_t type of status
750  *              NO_ERROR  -- success
751  *              none-zero failure code
752  *==========================================================================*/
startAdvancedCapture(mm_camera_advanced_capture_t type,cam_capture_frame_config_t * config)753 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type,
754         cam_capture_frame_config_t *config)
755 {
756     int32_t rc = NO_ERROR;
757 
758     rc = m_camOps->process_advanced_capture(m_camHandle, m_handle, type,
759             1, config);
760     return rc;
761 }
762 
763 /*===========================================================================
764 * FUNCTION   : flushSuperbuffer
765  *
766  * DESCRIPTION: flush the all superbuffer frames.
767  *
768  * PARAMETERS :
769  *   @frame_idx : frame index of focused frame
770  *
771  * RETURN     : int32_t type of status
772  *              NO_ERROR  -- success
773  *              none-zero failure code
774  *==========================================================================*/
flushSuperbuffer(uint32_t frame_idx)775 int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx)
776 {
777     int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx);
778     return rc;
779 }
780 
781 /*===========================================================================
782  * FUNCTION   : QCameraVideoChannel
783  *
784  * DESCRIPTION: constructor of QCameraVideoChannel
785  *
786  * PARAMETERS :
787  *   @cam_handle : camera handle
788  *   @cam_ops    : ptr to camera ops table
789  *
790  * RETURN     : none
791  *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)792 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
793                                          mm_camera_ops_t *cam_ops) :
794     QCameraChannel(cam_handle, cam_ops)
795 {
796 }
797 
798 /*===========================================================================
799  * FUNCTION   : QCameraVideoChannel
800  *
801  * DESCRIPTION: default constructor of QCameraVideoChannel
802  *
803  * PARAMETERS : none
804  *
805  * RETURN     : none
806  *==========================================================================*/
QCameraVideoChannel()807 QCameraVideoChannel::QCameraVideoChannel()
808 {
809 }
810 
811 /*===========================================================================
812  * FUNCTION   : ~QCameraVideoChannel
813  *
814  * DESCRIPTION: destructor of QCameraVideoChannel
815  *
816  * PARAMETERS : none
817  *
818  * RETURN     : none
819  *==========================================================================*/
~QCameraVideoChannel()820 QCameraVideoChannel::~QCameraVideoChannel()
821 {
822 }
823 
824 /*===========================================================================
825  * FUNCTION   : takePicture
826  *
827  * DESCRIPTION: send request for queued snapshot frames
828  *
829  * PARAMETERS :
830  *   @mm_camera_req_buf_t : request buf info
831  *
832  * RETURN     : int32_t type of status
833  *              NO_ERROR  -- success
834  *              none-zero failure code
835  *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)836 int32_t QCameraVideoChannel::takePicture(mm_camera_req_buf_t *buf)
837 {
838     int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf);
839     return rc;
840 }
841 
842 /*===========================================================================
843  * FUNCTION   : cancelPicture
844  *
845  * DESCRIPTION: cancel request for queued snapshot frames
846  *
847  * PARAMETERS : none
848  *
849  * RETURN     : int32_t type of status
850  *              NO_ERROR  -- success
851  *              none-zero failure code
852  *==========================================================================*/
cancelPicture()853 int32_t QCameraVideoChannel::cancelPicture()
854 {
855     int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
856     return rc;
857 }
858 
859 /*===========================================================================
860  * FUNCTION   : releaseFrame
861  *
862  * DESCRIPTION: return video frame from app
863  *
864  * PARAMETERS :
865  *   @opaque     : ptr to video frame to be returned
866  *   @isMetaData : if frame is a metadata or real frame
867  *
868  * RETURN     : int32_t type of status
869  *              NO_ERROR  -- success
870  *              none-zero failure code
871  *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)872 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
873 {
874     QCameraStream *pVideoStream = NULL;
875     for (size_t i = 0; i < mStreams.size(); i++) {
876         if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
877             pVideoStream = mStreams[i];
878             break;
879         }
880     }
881 
882     if (NULL == pVideoStream) {
883         LOGE("No video stream in the channel");
884         return BAD_VALUE;
885     }
886 
887     int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
888     return rc;
889 }
890 
891 /*===========================================================================
892  * FUNCTION   : QCameraReprocessChannel
893  *
894  * DESCRIPTION: constructor of QCameraReprocessChannel
895  *
896  * PARAMETERS :
897  *   @cam_handle : camera handle
898  *   @cam_ops    : ptr to camera ops table
899  *
900  * RETURN     : none
901  *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)902 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
903                                                  mm_camera_ops_t *cam_ops) :
904     QCameraChannel(cam_handle, cam_ops),
905     m_pSrcChannel(NULL),
906     mPassCount(0)
907 {
908     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
909 }
910 
911 /*===========================================================================
912  * FUNCTION   : QCameraReprocessChannel
913  *
914  * DESCRIPTION: default constructor of QCameraReprocessChannel
915  *
916  * PARAMETERS : none
917  *
918  * RETURN     : none
919  *==========================================================================*/
QCameraReprocessChannel()920 QCameraReprocessChannel::QCameraReprocessChannel() :
921     m_pSrcChannel(NULL),
922     mPassCount(0)
923 {
924 }
925 
926 /*===========================================================================
927  * FUNCTION   : ~QCameraReprocessChannel
928  *
929  * DESCRIPTION: destructor of QCameraReprocessChannel
930  *
931  * PARAMETERS : none
932  *
933  * RETURN     : none
934  *==========================================================================*/
~QCameraReprocessChannel()935 QCameraReprocessChannel::~QCameraReprocessChannel()
936 {
937 }
938 
939 /*===========================================================================
940  * FUNCTION   : addReprocStreamsFromSource
941  *
942  * DESCRIPTION: add reprocess streams from input source channel
943  *
944  * PARAMETERS :
945  *   @allocator      : stream related buffer allocator
946  *   @featureConfig  : pp feature configuration
947  *   @pSrcChannel    : ptr to input source channel that needs reprocess
948  *   @minStreamBufNum: number of stream buffers needed
949  *   @burstNum       : number of burst captures needed
950  *   @paddingInfo    : padding information
951  *   @param          : reference to parameters
952  *   @contStream     : continous streaming mode or burst
953  *   @offline        : configure for offline reprocessing
954  *
955  * RETURN     : int32_t type of status
956  *              NO_ERROR  -- success
957  *              none-zero failure code
958  *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & featureConfig,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,uint8_t burstNum,cam_padding_info_t * paddingInfo,QCameraParametersIntf & param,bool contStream,bool offline)959 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(
960         QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig,
961         QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum,
962         cam_padding_info_t *paddingInfo, QCameraParametersIntf &param, bool contStream,
963         bool offline)
964 {
965     int32_t rc = 0;
966     QCameraStream *pStream = NULL;
967     QCameraHeapMemory *pStreamInfoBuf = NULL;
968     QCameraHeapMemory *pMiscBuf = NULL;
969     cam_stream_info_t *streamInfo = NULL;
970     cam_padding_info_t padding;
971 
972     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
973     if (NULL == paddingInfo) {
974         return BAD_VALUE;
975     }
976     padding = *paddingInfo;
977     //Use maximum padding so that the buffer
978     //can be rotated
979     padding.width_padding = MAX(padding.width_padding, padding.height_padding);
980     padding.height_padding = padding.width_padding;
981     padding.offset_info.offset_x = 0;
982     padding.offset_info.offset_y = 0;
983 
984     LOGD("num of src stream = %d", pSrcChannel->getNumOfStreams());
985 
986     for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
987         cam_pp_feature_config_t pp_featuremask = featureConfig;
988         pStream = pSrcChannel->getStreamByIndex(i);
989         if (pStream != NULL) {
990             if (param.getofflineRAW() && !((pStream->isTypeOf(CAM_STREAM_TYPE_RAW))
991                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))
992                     || (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
993                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)))) {
994                 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
995                 continue;
996             }
997 
998             if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
999                     && (!param.getofflineRAW())) {
1000                 // Skip raw for reprocess now because PP module cannot handle
1001                 // meta data&raw. May need furthur discussion if Imaginglib need meta data
1002                 continue;
1003             }
1004 
1005             if (((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
1006                     && !(param.getManualCaptureMode() >=
1007                     CAM_MANUAL_CAPTURE_TYPE_3))
1008                     || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1009                 // Skip metadata
1010                 continue;
1011             }
1012 
1013             if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1014                     pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1015                     pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1016                     pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
1017                 cam_feature_mask_t feature_mask = featureConfig.feature_mask;
1018 
1019                 // skip thumbnail reprocessing if not needed
1020                 if (!param.needThumbnailReprocess(&feature_mask)) {
1021                     continue;
1022                 }
1023                 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1024                 // on preview/postview stream in realtime.
1025                 // So, need not apply again.
1026                 feature_mask &= ~(CAM_QCOM_FEATURE_DENOISE2D |
1027                         CAM_QCOM_FEATURE_CAC |
1028                         CAM_QCOM_FEATURE_SHARPNESS |
1029                         CAM_QCOM_FEATURE_FLIP |
1030                         CAM_QCOM_FEATURE_RAW_PROCESSING);
1031                 if (!feature_mask) {
1032                     // Skip thumbnail stream reprocessing since no other
1033                     //reprocessing is enabled.
1034                     continue;
1035                 }
1036             }
1037 
1038             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1039                 pp_featuremask.feature_mask = 0;
1040                 pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING;
1041             }
1042 
1043             pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
1044             if (pStreamInfoBuf == NULL) {
1045                 LOGE("no mem for stream info buf");
1046                 rc = NO_MEMORY;
1047                 break;
1048             }
1049 
1050             streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
1051             memset(streamInfo, 0, sizeof(cam_stream_info_t));
1052             streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
1053             // Enable CPP high performance mode to put it in turbo frequency mode for
1054             // burst/longshot/HDR snapshot cases
1055             streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE;
1056             if (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) {
1057                 streamInfo->fmt = CAM_FORMAT_YUV_420_NV21;
1058             } else {
1059                 rc = pStream->getFormat(streamInfo->fmt);
1060             }
1061 
1062             if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1063                     pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
1064                 param.getThumbnailSize(&(streamInfo->dim.width), &(streamInfo->dim.height));
1065             } else {
1066                 if ((param.isPostProcScaling()) &&
1067                         (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE)) {
1068                     rc = param.getStreamDimension(CAM_STREAM_TYPE_OFFLINE_PROC,
1069                             streamInfo->dim);
1070                 } else if ((param.getofflineRAW()) &&
1071                         (pStream->isTypeOf(CAM_STREAM_TYPE_RAW))) {
1072                     param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim);
1073                 } else {
1074                     rc = pStream->getFrameDimension(streamInfo->dim);
1075                 }
1076             }
1077 
1078             if ( contStream ) {
1079                 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1080                 streamInfo->num_of_burst = 0;
1081             } else {
1082                 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1083                 streamInfo->num_of_burst = burstNum;
1084             }
1085             streamInfo->num_bufs = minStreamBufNum;
1086 
1087             cam_stream_reproc_config_t rp_cfg;
1088             memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
1089             if (offline) {
1090                 cam_frame_len_offset_t offset;
1091                 memset(&offset, 0, sizeof(cam_frame_len_offset_t));
1092 
1093                 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
1094                 pStream->getFormat(rp_cfg.offline.input_fmt);
1095                 pStream->getFrameDimension(rp_cfg.offline.input_dim);
1096                 pStream->getFrameOffset(offset);
1097                 rp_cfg.offline.input_buf_planes.plane_info = offset;
1098                 rp_cfg.offline.input_type = pStream->getMyOriginalType();
1099                 //For input metadata + input buffer
1100                 rp_cfg.offline.num_of_bufs = 2;
1101             } else {
1102                 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE;
1103                 rp_cfg.online.input_stream_id = pStream->getMyServerID();
1104                 rp_cfg.online.input_stream_type = pStream->getMyOriginalType();
1105             }
1106             param.getStreamRotation(streamInfo->stream_type,
1107                     streamInfo->pp_config, streamInfo->dim);
1108             streamInfo->reprocess_config = rp_cfg;
1109             streamInfo->reprocess_config.pp_feature_config = pp_featuremask;
1110 
1111             if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1112                 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1113                 || pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1114                 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) {
1115                 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1116                 // on preview/postview stream in realtime. Need not apply again.
1117                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1118                         ~CAM_QCOM_FEATURE_CAC;
1119                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1120                         ~CAM_QCOM_FEATURE_SHARPNESS;
1121                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1122                         ~CAM_QCOM_FEATURE_FLIP;
1123                 //Don't do WNR for thumbnail
1124                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1125                         ~CAM_QCOM_FEATURE_DENOISE2D;
1126                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1127                         ~CAM_QCOM_FEATURE_CDS;
1128                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1129                         ~CAM_QCOM_FEATURE_DSDN;
1130                 //No need of RAW processing for other than RAW streams
1131                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1132                         ~CAM_QCOM_FEATURE_RAW_PROCESSING;
1133 
1134                 if (param.isHDREnabled()
1135                   && !param.isHDRThumbnailProcessNeeded()){
1136                     streamInfo->reprocess_config.pp_feature_config.feature_mask
1137                       &= ~CAM_QCOM_FEATURE_HDR;
1138                 }
1139             }
1140 
1141             cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
1142             if (offline) {
1143                 type = streamInfo->reprocess_config.offline.input_type;
1144             } else {
1145                 type = streamInfo->reprocess_config.online.input_stream_type;
1146             }
1147             if (type == CAM_STREAM_TYPE_SNAPSHOT) {
1148                 int flipMode = param.getFlipMode(type);
1149                 if (flipMode > 0) {
1150                     streamInfo->reprocess_config.pp_feature_config.feature_mask |=
1151                             CAM_QCOM_FEATURE_FLIP;
1152                     streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode;
1153                 }
1154             }
1155 
1156             if ((streamInfo->reprocess_config.pp_feature_config.feature_mask
1157                     & CAM_QCOM_FEATURE_SCALE)
1158                     && param.isReprocScaleEnabled()
1159                     && param.isUnderReprocScaling()) {
1160                 //we only Scale Snapshot frame
1161                 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
1162                     streamInfo->dim.width =
1163                             streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
1164                     streamInfo->dim.height =
1165                             streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
1166                 }
1167                 LOGH("stream width=%d, height=%d.",
1168                          streamInfo->dim.width, streamInfo->dim.height);
1169             }
1170 
1171             // save source stream handler
1172             mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
1173 
1174             pMiscBuf = allocator.allocateMiscBuf(streamInfo);
1175 
1176             LOGH("Configure Reprocessing: stream = %d, res = %dX%d, fmt = %d, type = %d",
1177                     pStream->getMyOriginalType(), streamInfo->dim.width,
1178                     streamInfo->dim.height, streamInfo->fmt, type);
1179 
1180             // add reprocess stream
1181             if (streamInfo->reprocess_config.pp_feature_config.feature_mask
1182                     & CAM_QCOM_FEATURE_ROTATION) {
1183                 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1184                         minStreamBufNum, &padding, NULL, NULL, false, false,
1185                         streamInfo->reprocess_config.pp_feature_config.rotation);
1186             } else {
1187                 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1188                         minStreamBufNum, &padding, NULL, NULL, false, false);
1189             }
1190             if (rc != NO_ERROR) {
1191                 LOGE("add reprocess stream failed, ret = %d", rc);
1192                 break;
1193             }
1194         }
1195     }
1196 
1197     if (rc == NO_ERROR) {
1198         m_pSrcChannel = pSrcChannel;
1199     }
1200     return rc;
1201 }
1202 
1203 /*===========================================================================
1204  * FUNCTION   : getStreamBySrouceHandle
1205  *
1206  * DESCRIPTION: find reprocess stream by its source stream handle
1207  *
1208  * PARAMETERS :
1209  *   @srcHandle : source stream handle
1210  *
1211  * RETURN     : ptr to reprocess stream if found. NULL if not found
1212  *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)1213 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
1214 {
1215     QCameraStream *pStream = NULL;
1216 
1217     for (size_t i = 0; i < mStreams.size(); i++) {
1218         if (mSrcStreamHandles[i] == srcHandle) {
1219             pStream = mStreams[i];
1220             break;
1221         }
1222     }
1223 
1224     return pStream;
1225 }
1226 
1227 /*===========================================================================
1228  * FUNCTION   : stop
1229  *
1230  * DESCRIPTION: stop channel and unmap offline buffers
1231  *
1232  * PARAMETERS : none
1233  *
1234  * RETURN     : int32_t type of status
1235  *              NO_ERROR  -- success
1236  *              none-zero failure code
1237  *==========================================================================*/
stop()1238 int32_t QCameraReprocessChannel::stop()
1239 {
1240     int32_t rc = QCameraChannel::stop();
1241 
1242     if (!mOfflineBuffers.empty()) {
1243         QCameraStream *stream = NULL;
1244         List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1245         int error = NO_ERROR;
1246         for( ; it != mOfflineBuffers.end(); it++) {
1247             stream = (*it).stream;
1248             if (NULL != stream) {
1249                 error = stream->unmapBuf((*it).type,
1250                                          (*it).index,
1251                                          -1);
1252                 if (NO_ERROR != error) {
1253                     LOGE("Error during offline buffer unmap %d",
1254                            error);
1255                 }
1256             }
1257         }
1258         mOfflineBuffers.clear();
1259     }
1260     return rc;
1261 }
1262 
1263 /*===========================================================================
1264  * FUNCTION   : doReprocessOffline
1265  *
1266  * DESCRIPTION: request to do offline reprocess on the frame
1267  *
1268  * PARAMETERS :
1269  *   @frame   : frame to be performed a reprocess
1270  *   @meta_buf : Metadata buffer for reprocessing
1271  *   @pStream  : Actual reprocess stream
1272  *
1273  * RETURN     : int32_t type of status
1274  *              NO_ERROR  -- success
1275  *              none-zero failure code
1276  *==========================================================================*/
doReprocessOffline(mm_camera_buf_def_t * frame,mm_camera_buf_def_t * meta_buf,QCameraStream * pStream)1277 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_buf_def_t *frame,
1278         mm_camera_buf_def_t *meta_buf, QCameraStream *pStream)
1279 {
1280     int32_t rc = 0;
1281     OfflineBuffer mappedBuffer;
1282     uint32_t buf_index = 0;
1283     uint32_t meta_buf_index = 0;
1284 
1285     if ((frame == NULL) || (meta_buf == NULL)) {
1286         LOGE("Invalid Input Paramters");
1287         return INVALID_OPERATION;
1288     }
1289 
1290     if (pStream == NULL) {
1291         pStream = getStreamBySrouceHandle(frame->stream_id);
1292         if (pStream == NULL) {
1293             LOGE("Input validation failed.");
1294             return INVALID_OPERATION;
1295         }
1296     }
1297 
1298     if (!mOfflineBuffers.empty()) {
1299         List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1300         for( ; it != mOfflineBuffers.end(); it++) {
1301             buf_index = (buf_index < ((*it).index)) ? ((*it).index) : buf_index;
1302         }
1303         buf_index += 1;
1304     }
1305 
1306     meta_buf_index = buf_index;
1307     if (meta_buf != NULL) {
1308         rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF,
1309                 meta_buf_index,
1310                 -1,
1311                 meta_buf->fd,
1312                 meta_buf->buffer,
1313                 meta_buf->frame_len);
1314         if (NO_ERROR != rc ) {
1315             LOGE("Error during metadata buffer mapping");
1316             rc = -1;
1317             return rc;
1318         }
1319 
1320         mappedBuffer.index = meta_buf_index;
1321         mappedBuffer.stream = pStream;
1322         mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF;
1323         mOfflineBuffers.push_back(mappedBuffer);
1324         buf_index += 1;
1325     }
1326 
1327     rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1328              buf_index,
1329              -1,
1330              frame->fd,
1331              frame->buffer,
1332              frame->frame_len);
1333     if (NO_ERROR != rc ) {
1334         LOGE("Error during reprocess input buffer mapping");
1335         rc = -1;
1336         return rc;
1337     }
1338     mappedBuffer.index = buf_index;
1339     mappedBuffer.stream = pStream;
1340     mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF;
1341     mOfflineBuffers.push_back(mappedBuffer);
1342 
1343     cam_stream_parm_buffer_t param;
1344     memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1345 
1346     param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1347     param.reprocess.buf_index = buf_index;
1348     param.reprocess.frame_idx = frame->frame_idx;
1349 
1350     if (meta_buf != NULL) {
1351         param.reprocess.meta_present = 1;
1352         param.reprocess.meta_buf_index = meta_buf_index;
1353     }
1354 
1355     LOGI("Offline reprocessing id = %d buf Id = %d meta index = %d type = %d",
1356              param.reprocess.frame_idx, param.reprocess.buf_index,
1357             param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1358 
1359     rc = pStream->setParameter(param);
1360     if (rc != NO_ERROR) {
1361         LOGE("stream setParameter for reprocess failed");
1362         return rc;
1363     }
1364     return rc;
1365 }
1366 
1367 /*===========================================================================
1368  * FUNCTION   : doReprocessOffline
1369  *
1370  * DESCRIPTION: request to do offline reprocess on the frame
1371  *
1372  * PARAMETERS :
1373  *   @frame   : frame to be performed a reprocess
1374  *   @meta_buf : Metadata buffer for reprocessing
1375  *   @mParameter : camera parameters
1376  *
1377  * RETURN     : int32_t type of status
1378  *              NO_ERROR  -- success
1379  *              none-zero failure code
1380  *==========================================================================*/
doReprocessOffline(mm_camera_super_buf_t * frame,mm_camera_buf_def_t * meta_buf,QCameraParametersIntf & mParameter)1381 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame,
1382         mm_camera_buf_def_t *meta_buf, QCameraParametersIntf &mParameter)
1383 {
1384     int32_t rc = 0;
1385     QCameraStream *pStream = NULL;
1386 
1387     if (mStreams.size() < 1) {
1388         LOGE("No reprocess streams");
1389         return -1;
1390     }
1391     if (m_pSrcChannel == NULL) {
1392         LOGE("No source channel for reprocess");
1393         return -1;
1394     }
1395 
1396     if (frame == NULL) {
1397         LOGE("Invalid source frame");
1398         return BAD_VALUE;
1399     }
1400 
1401     for (uint32_t i = 0; i < frame->num_bufs; i++) {
1402         pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1403         if ((pStream != NULL) &&
1404                 (m_handle == pStream->getChannelHandle())) {
1405             if (mParameter.getofflineRAW() &&
1406                     !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1407                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1408                 continue;
1409             }
1410 
1411             if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1412                      && (mParameter.getManualCaptureMode()
1413                      < CAM_MANUAL_CAPTURE_TYPE_3))
1414                      || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1415                 // Skip metadata for reprocess now because PP module cannot handle meta data
1416                 // May need furthur discussion if Imaginglib need meta data
1417                 continue;
1418             }
1419 
1420             // Update Metadata
1421             if (meta_buf != NULL) {
1422                 uint32_t stream_id = frame->bufs[i]->stream_id;
1423                 QCameraStream *srcStream =
1424                         m_pSrcChannel->getStreamByHandle(stream_id);
1425                 metadata_buffer_t *pMetaData =
1426                         (metadata_buffer_t *)meta_buf->buffer;
1427                 if ((NULL != pMetaData) && (NULL != srcStream)) {
1428                     IF_META_AVAILABLE(cam_crop_data_t, crop,
1429                             CAM_INTF_META_CROP_DATA, pMetaData) {
1430                         if (MAX_NUM_STREAMS > crop->num_of_streams) {
1431                             for (int j = 0; j < MAX_NUM_STREAMS; j++) {
1432                                 if (crop->crop_info[j].stream_id ==
1433                                             srcStream->getMyServerID()) {
1434                                     // Store crop/roi information for offline reprocess
1435                                     // in the reprocess stream slot
1436                                     crop->crop_info[crop->num_of_streams].crop =
1437                                             crop->crop_info[j].crop;
1438                                     crop->crop_info[crop->num_of_streams].roi_map =
1439                                             crop->crop_info[j].roi_map;
1440                                     for (uint8_t k = 0; k < mStreams.size(); k++) {
1441                                         if (srcStream->getMyType() ==
1442                                                 mStreams[k]->getMyOriginalType()) {
1443                                             crop->crop_info[crop->num_of_streams].stream_id =
1444                                                     mStreams[k]->getMyServerID();
1445                                             break;
1446                                         }
1447                                     }
1448                                     crop->num_of_streams++;
1449                                     break;
1450                                 }
1451                             }
1452                         } else {
1453                             LOGE("No space to add reprocess stream crop/roi information");
1454                         }
1455                     }
1456                 }
1457             }
1458 
1459             rc = doReprocessOffline (frame->bufs[i], meta_buf, pStream);
1460         }
1461     }
1462     return rc;
1463 }
1464 
1465 /*===========================================================================
1466  * FUNCTION   : doReprocess
1467  *
1468  * DESCRIPTION: request to do a reprocess on the frame
1469  *
1470  * PARAMETERS :
1471  *   @frame   : frame to be performed a reprocess
1472  *   @mParameter : camera parameters
1473  *   @pMetaStream: Metadata stream handle
1474  *   @meta_buf_index : Metadata buffer index
1475  *
1476  * RETURN     : int32_t type of status
1477  *              NO_ERROR  -- success
1478  *              none-zero failure code
1479  *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame,QCameraParametersIntf & mParameter,QCameraStream * pMetaStream,uint8_t meta_buf_index)1480 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
1481         QCameraParametersIntf &mParameter, QCameraStream *pMetaStream,
1482         uint8_t meta_buf_index)
1483 {
1484     int32_t rc = 0;
1485     if (mStreams.size() < 1) {
1486         LOGE("No reprocess streams");
1487         return -1;
1488     }
1489     if (m_pSrcChannel == NULL) {
1490         LOGE("No source channel for reprocess");
1491         return -1;
1492     }
1493 
1494     if (pMetaStream == NULL) {
1495         LOGW("Null Metadata buffer for processing");
1496     }
1497 
1498     for (uint32_t i = 0; i < frame->num_bufs; i++) {
1499         QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1500         if ((pStream != NULL) && (m_handle == pStream->getChannelHandle())) {
1501             if (mParameter.getofflineRAW() && !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1502                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW))
1503                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1504                 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
1505                 continue;
1506             }
1507             if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1508                      && (mParameter.getManualCaptureMode()
1509                      < CAM_MANUAL_CAPTURE_TYPE_3))
1510                      || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1511                 // Skip metadata for reprocess now because PP module cannot handle meta data
1512                 // May need furthur discussion if Imaginglib need meta data
1513                 continue;
1514             }
1515 
1516             cam_stream_parm_buffer_t param;
1517             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1518             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1519             param.reprocess.buf_index = frame->bufs[i]->buf_idx;
1520             param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1521             if (pMetaStream != NULL) {
1522                 // we have meta data frame bundled, sent together with reprocess frame
1523                 param.reprocess.meta_present = 1;
1524                 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
1525                 param.reprocess.meta_buf_index = meta_buf_index;
1526             }
1527 
1528             LOGI("Online reprocessing id = %d buf Id = %d meta index = %d type = %d",
1529                      param.reprocess.frame_idx, param.reprocess.buf_index,
1530                     param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1531 
1532             rc = pStream->setParameter(param);
1533             if (rc != NO_ERROR) {
1534                 LOGE("stream setParameter for reprocess failed");
1535                 break;
1536             }
1537         }
1538     }
1539     return rc;
1540 }
1541 
1542 /*===========================================================================
1543  * FUNCTION   : doReprocess
1544  *
1545  * DESCRIPTION: request to do a reprocess on the frame
1546  *
1547  * PARAMETERS :
1548  *   @buf_fd     : fd to the input buffer that needs reprocess
1549  *   @buffer     : buffer pointer of actual buffer
1550  *   @buf_lenght : length of the input buffer
1551  *   @ret_val    : result of reprocess.
1552  *                 Example: Could be faceID in case of register face image.
1553  *
1554  * RETURN     : int32_t type of status
1555  *              NO_ERROR  -- success
1556  *              none-zero failure code
1557  *==========================================================================*/
doReprocess(int buf_fd,void * buffer,size_t buf_length,int32_t & ret_val)1558 int32_t QCameraReprocessChannel::doReprocess(int buf_fd, void *buffer,
1559         size_t buf_length, int32_t &ret_val)
1560 {
1561     int32_t rc = 0;
1562     if (mStreams.size() < 1) {
1563         LOGE("No reprocess streams");
1564         return -1;
1565     }
1566 
1567     uint32_t buf_idx = 0;
1568     for (size_t i = 0; i < mStreams.size(); i++) {
1569         if ((mStreams[i] != NULL) &&
1570                 (m_handle != mStreams[i]->getChannelHandle())) {
1571             continue;
1572         }
1573         rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1574                                  buf_idx, -1,
1575                                  buf_fd, buffer, buf_length);
1576 
1577         if (rc == NO_ERROR) {
1578             cam_stream_parm_buffer_t param;
1579             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1580             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1581             param.reprocess.buf_index = buf_idx;
1582             rc = mStreams[i]->setParameter(param);
1583             if (rc == NO_ERROR) {
1584                 ret_val = param.reprocess.ret_val;
1585             }
1586             mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1587                                   buf_idx, -1);
1588         }
1589     }
1590     return rc;
1591 }
1592 
1593 }; // namespace qcamera
1594