QCameraChannel.cpp revision 744f5403bebb0e27140d16a5df7a341713c24a13
1/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6*     * Redistributions of source code must retain the above copyright
7*       notice, this list of conditions and the following disclaimer.
8*     * Redistributions in binary form must reproduce the above
9*       copyright notice, this list of conditions and the following
10*       disclaimer in the documentation and/or other materials provided
11*       with the distribution.
12*     * Neither the name of The Linux Foundation nor the names of its
13*       contributors may be used to endorse or promote products derived
14*       from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29
30#define LOG_TAG "QCameraChannel"
31
32#include <utils/Errors.h>
33#include "QCameraParameters.h"
34#include "QCamera2HWI.h"
35#include "QCameraChannel.h"
36
37using namespace android;
38
39namespace qcamera {
40
41/*===========================================================================
42 * FUNCTION   : QCameraChannel
43 *
44 * DESCRIPTION: constrcutor of QCameraChannel
45 *
46 * PARAMETERS :
47 *   @cam_handle : camera handle
48 *   @cam_ops    : ptr to camera ops table
49 *
50 * RETURN     : none
51 *==========================================================================*/
52QCameraChannel::QCameraChannel(uint32_t cam_handle,
53                               mm_camera_ops_t *cam_ops)
54{
55    m_camHandle = cam_handle;
56    m_camOps = cam_ops;
57    m_bIsActive = false;
58
59    m_handle = 0;
60    m_numStreams = 0;
61    memset(mStreams, 0, sizeof(mStreams));
62}
63
64/*===========================================================================
65 * FUNCTION   : QCameraChannel
66 *
67 * DESCRIPTION: default constrcutor of QCameraChannel
68 *
69 * PARAMETERS : none
70 *
71 * RETURN     : none
72 *==========================================================================*/
73QCameraChannel::QCameraChannel()
74{
75    m_camHandle = 0;
76    m_camOps = NULL;
77    m_bIsActive = false;
78
79    m_handle = 0;
80    m_numStreams = 0;
81    memset(mStreams, 0, sizeof(mStreams));
82}
83
84/*===========================================================================
85 * FUNCTION   : ~QCameraChannel
86 *
87 * DESCRIPTION: destructor of QCameraChannel
88 *
89 * PARAMETERS : none
90 *
91 * RETURN     : none
92 *==========================================================================*/
93QCameraChannel::~QCameraChannel()
94{
95    if (m_bIsActive) {
96        stop();
97    }
98
99    for (int i = 0; i < m_numStreams; i++) {
100        if (mStreams[i] != NULL) {
101            delete mStreams[i];
102            mStreams[i] = 0;
103        }
104    }
105    m_numStreams = 0;
106    m_camOps->delete_channel(m_camHandle, m_handle);
107    m_handle = 0;
108}
109
110/*===========================================================================
111 * FUNCTION   : init
112 *
113 * DESCRIPTION: initialization of channel
114 *
115 * PARAMETERS :
116 *   @attr    : channel bundle attribute setting
117 *   @dataCB  : data notify callback
118 *   @userData: user data ptr
119 *
120 * RETURN     : int32_t type of status
121 *              NO_ERROR  -- success
122 *              none-zero failure code
123 *==========================================================================*/
124int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
125                             mm_camera_buf_notify_t dataCB,
126                             void *userData)
127{
128    m_handle = m_camOps->add_channel(m_camHandle,
129                                      attr,
130                                      dataCB,
131                                      userData);
132    if (m_handle == 0) {
133        ALOGE("%s: Add channel failed", __func__);
134        return UNKNOWN_ERROR;
135    }
136    return NO_ERROR;
137}
138
139/*===========================================================================
140 * FUNCTION   : addStream
141 *
142 * DESCRIPTION: add a stream into channel
143 *
144 * PARAMETERS :
145 *   @allocator      : stream related buffer allocator
146 *   @streamInfoBuf  : ptr to buf that constains stream info
147 *   @minStreamBufNum: number of stream buffers needed
148 *   @paddingInfo    : padding information
149 *   @stream_cb      : stream data notify callback
150 *   @userdata       : user data ptr
151 *
152 * RETURN     : int32_t type of status
153 *              NO_ERROR  -- success
154 *              none-zero failure code
155 *==========================================================================*/
156int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
157                                  QCameraHeapMemory *streamInfoBuf,
158                                  uint8_t minStreamBufNum,
159                                  cam_padding_info_t *paddingInfo,
160                                  stream_cb_routine stream_cb,
161                                  void *userdata)
162{
163    int32_t rc = NO_ERROR;
164    if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
165        ALOGE("%s: stream number (%d) exceeds max limit (%d)",
166              __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
167        return BAD_VALUE;
168    }
169    QCameraStream *pStream = new QCameraStream(allocator,
170                                               m_camHandle,
171                                               m_handle,
172                                               m_camOps,
173                                               paddingInfo);
174    if (pStream == NULL) {
175        ALOGE("%s: No mem for Stream", __func__);
176        return NO_MEMORY;
177    }
178
179    rc = pStream->init(streamInfoBuf, minStreamBufNum, stream_cb, userdata);
180    if (rc == 0) {
181        mStreams[m_numStreams] = pStream;
182        m_numStreams++;
183    } else {
184        delete pStream;
185    }
186    return rc;
187}
188
189/*===========================================================================
190 * FUNCTION   : start
191 *
192 * DESCRIPTION: start channel, which will start all streams belong to this channel
193 *
194 * PARAMETERS : None
195 *
196 * RETURN     : int32_t type of status
197 *              NO_ERROR  -- success
198 *              none-zero failure code
199 *==========================================================================*/
200int32_t QCameraChannel::start()
201{
202    int32_t rc = NO_ERROR;
203
204    if (m_numStreams > 1) {
205        // there is more than one stream in the channel
206        // we need to notify mctl that all streams in this channel need to be bundled
207        cam_bundle_config_t bundleInfo;
208        memset(&bundleInfo, 0, sizeof(bundleInfo));
209        rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
210        if (rc != NO_ERROR) {
211            ALOGE("%s: get_bundle_info failed", __func__);
212            return rc;
213        }
214        if (bundleInfo.num_of_streams > 1) {
215            for (int i = 0; i < bundleInfo.num_of_streams; i++) {
216                QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
217                if (pStream != NULL) {
218                    if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
219                        // Skip metadata for reprocess now because PP module cannot handle meta data
220                        // May need furthur discussion if Imaginglib need meta data
221                        continue;
222                    }
223
224                    cam_stream_parm_buffer_t param;
225                    memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
226                    param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
227                    param.bundleInfo = bundleInfo;
228                    rc = pStream->setParameter(param);
229                    if (rc != NO_ERROR) {
230                        ALOGE("%s: stream setParameter for set bundle failed", __func__);
231                        return rc;
232                    }
233                }
234            }
235        }
236    }
237
238    for (int i = 0; i < m_numStreams; i++) {
239        if (mStreams[i] != NULL) {
240            mStreams[i]->start();
241        }
242    }
243    rc = m_camOps->start_channel(m_camHandle, m_handle);
244
245    if (rc != NO_ERROR) {
246        for (int i = 0; i < m_numStreams; i++) {
247            if (mStreams[i] != NULL) {
248                mStreams[i]->stop();
249            }
250        }
251    } else {
252        m_bIsActive = true;
253    }
254
255    return rc;
256}
257
258/*===========================================================================
259 * FUNCTION   : stop
260 *
261 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
262 *
263 * PARAMETERS : none
264 *
265 * RETURN     : int32_t type of status
266 *              NO_ERROR  -- success
267 *              none-zero failure code
268 *==========================================================================*/
269int32_t QCameraChannel::stop()
270{
271    int32_t rc = NO_ERROR;
272    rc = m_camOps->stop_channel(m_camHandle, m_handle);
273
274    for (int i = 0; i < m_numStreams; i++) {
275        if (mStreams[i] != NULL) {
276            mStreams[i]->stop();
277        }
278    }
279
280    m_bIsActive = false;
281    return rc;
282}
283
284/*===========================================================================
285 * FUNCTION   : bufDone
286 *
287 * DESCRIPTION: return a stream buf back to kernel
288 *
289 * PARAMETERS :
290 *   @recvd_frame  : stream buf frame to be returned
291 *
292 * RETURN     : int32_t type of status
293 *              NO_ERROR  -- success
294 *              none-zero failure code
295 *==========================================================================*/
296int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
297{
298    int32_t rc = NO_ERROR;
299    for (int i = 0; i < recvd_frame->num_bufs; i++) {
300         if (recvd_frame->bufs[i] != NULL) {
301             for (int j = 0; j < m_numStreams; j++) {
302                 if (mStreams[j] != NULL &&
303                     mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
304                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
305                     break; // break loop j
306                 }
307             }
308         }
309    }
310
311    return rc;
312}
313
314/*===========================================================================
315 * FUNCTION   : processZoomDone
316 *
317 * DESCRIPTION: process zoom done event
318 *
319 * PARAMETERS :
320 *   @previewWindoe : ptr to preview window ops table, needed to set preview
321 *                    crop information
322 *   @crop_info     : crop info as a result of zoom operation
323 *
324 * RETURN     : int32_t type of status
325 *              NO_ERROR  -- success
326 *              none-zero failure code
327 *==========================================================================*/
328int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
329                                        cam_crop_data_t &crop_info)
330{
331    int32_t rc = NO_ERROR;
332    for (int i = 0; i < m_numStreams; i++) {
333        if (mStreams[i] != NULL) {
334            rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
335        }
336    }
337    return rc;
338}
339
340/*===========================================================================
341 * FUNCTION   : getStreamByHandle
342 *
343 * DESCRIPTION: return stream object by stream handle
344 *
345 * PARAMETERS :
346 *   @streamHandle : stream handle
347 *
348 * RETURN     : stream object. NULL if not found
349 *==========================================================================*/
350QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
351{
352    for (int i = 0; i < m_numStreams; i++) {
353        if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
354            return mStreams[i];
355        }
356    }
357    return NULL;
358}
359
360/*===========================================================================
361 * FUNCTION   : getStreamByServerID
362 *
363 * DESCRIPTION: return stream object by stream server ID from daemon
364 *
365 * PARAMETERS :
366 *   @serverID : stream server ID
367 *
368 * RETURN     : stream object. NULL if not found
369 *==========================================================================*/
370QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
371{
372    for (int i = 0; i < m_numStreams; i++) {
373        if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
374            return mStreams[i];
375        }
376    }
377    return NULL;
378}
379
380/*===========================================================================
381 * FUNCTION   : getStreamByIndex
382 *
383 * DESCRIPTION: return stream object by index of streams in the channel
384 *
385 * PARAMETERS :
386 *   @index : index of stream in the channel
387 *
388 * RETURN     : stream object. NULL if not found
389 *==========================================================================*/
390QCameraStream *QCameraChannel::getStreamByIndex(uint8_t index)
391{
392    if (index < m_numStreams) {
393        return mStreams[index];
394    }
395    return NULL;
396}
397
398/*===========================================================================
399 * FUNCTION   : QCameraPicChannel
400 *
401 * DESCRIPTION: constructor of QCameraPicChannel
402 *
403 * PARAMETERS :
404 *   @cam_handle : camera handle
405 *   @cam_ops    : ptr to camera ops table
406 *
407 * RETURN     : none
408 *==========================================================================*/
409QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
410                                     mm_camera_ops_t *cam_ops) :
411    QCameraChannel(cam_handle, cam_ops)
412{
413}
414
415/*===========================================================================
416 * FUNCTION   : QCameraPicChannel
417 *
418 * DESCRIPTION: default constructor of QCameraPicChannel
419 *
420 * PARAMETERS : none
421 *
422 * RETURN     : none
423 *==========================================================================*/
424QCameraPicChannel::QCameraPicChannel()
425{
426}
427
428/*===========================================================================
429 * FUNCTION   : ~QCameraPicChannel
430 *
431 * DESCRIPTION: destructor of QCameraPicChannel
432 *
433 * PARAMETERS : none
434 *
435 * RETURN     : none
436 *==========================================================================*/
437QCameraPicChannel::~QCameraPicChannel()
438{
439}
440
441/*===========================================================================
442 * FUNCTION   : takePicture
443 *
444 * DESCRIPTION: send request for queued snapshot frames
445 *
446 * PARAMETERS :
447 *   @num_of_snapshot : number of snapshot frames requested
448 *
449 * RETURN     : int32_t type of status
450 *              NO_ERROR  -- success
451 *              none-zero failure code
452 *==========================================================================*/
453int32_t QCameraPicChannel::takePicture(uint8_t num_of_snapshot)
454{
455    int32_t rc = m_camOps->request_super_buf(m_camHandle,
456                                             m_handle,
457                                             num_of_snapshot);
458    return rc;
459}
460
461/*===========================================================================
462 * FUNCTION   : cancelPicture
463 *
464 * DESCRIPTION: cancel request for queued snapshot frames
465 *
466 * PARAMETERS : none
467 *
468 * RETURN     : int32_t type of status
469 *              NO_ERROR  -- success
470 *              none-zero failure code
471 *==========================================================================*/
472int32_t QCameraPicChannel::cancelPicture()
473{
474    int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
475    return rc;
476}
477
478/*===========================================================================
479 * FUNCTION   : QCameraVideoChannel
480 *
481 * DESCRIPTION: constructor of QCameraVideoChannel
482 *
483 * PARAMETERS :
484 *   @cam_handle : camera handle
485 *   @cam_ops    : ptr to camera ops table
486 *
487 * RETURN     : none
488 *==========================================================================*/
489QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
490                                         mm_camera_ops_t *cam_ops) :
491    QCameraChannel(cam_handle, cam_ops)
492{
493}
494
495/*===========================================================================
496 * FUNCTION   : QCameraVideoChannel
497 *
498 * DESCRIPTION: default constructor of QCameraVideoChannel
499 *
500 * PARAMETERS : none
501 *
502 * RETURN     : none
503 *==========================================================================*/
504QCameraVideoChannel::QCameraVideoChannel()
505{
506}
507
508/*===========================================================================
509 * FUNCTION   : ~QCameraVideoChannel
510 *
511 * DESCRIPTION: destructor of QCameraVideoChannel
512 *
513 * PARAMETERS : none
514 *
515 * RETURN     : none
516 *==========================================================================*/
517QCameraVideoChannel::~QCameraVideoChannel()
518{
519}
520
521/*===========================================================================
522 * FUNCTION   : releaseFrame
523 *
524 * DESCRIPTION: return video frame from app
525 *
526 * PARAMETERS :
527 *   @opaque     : ptr to video frame to be returned
528 *   @isMetaData : if frame is a metadata or real frame
529 *
530 * RETURN     : int32_t type of status
531 *              NO_ERROR  -- success
532 *              none-zero failure code
533 *==========================================================================*/
534int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
535{
536    QCameraStream *pVideoStream = NULL;
537    for (int i = 0; i < m_numStreams; i++) {
538        if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
539            pVideoStream = mStreams[i];
540            break;
541        }
542    }
543
544    if (NULL == pVideoStream) {
545        ALOGE("%s: No video stream in the channel", __func__);
546        return BAD_VALUE;
547    }
548
549    int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
550    return rc;
551}
552
553/*===========================================================================
554 * FUNCTION   : QCameraReprocessChannel
555 *
556 * DESCRIPTION: constructor of QCameraReprocessChannel
557 *
558 * PARAMETERS :
559 *   @cam_handle : camera handle
560 *   @cam_ops    : ptr to camera ops table
561 *   @pp_mask    : post-proccess feature mask
562 *
563 * RETURN     : none
564 *==========================================================================*/
565QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
566                                                 mm_camera_ops_t *cam_ops) :
567    QCameraChannel(cam_handle, cam_ops),
568    m_pSrcChannel(NULL)
569{
570    memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
571}
572
573/*===========================================================================
574 * FUNCTION   : QCameraReprocessChannel
575 *
576 * DESCRIPTION: default constructor of QCameraReprocessChannel
577 *
578 * PARAMETERS : none
579 *
580 * RETURN     : none
581 *==========================================================================*/
582QCameraReprocessChannel::QCameraReprocessChannel() :
583    m_pSrcChannel(NULL)
584{
585}
586
587/*===========================================================================
588 * FUNCTION   : ~QCameraReprocessChannel
589 *
590 * DESCRIPTION: destructor of QCameraReprocessChannel
591 *
592 * PARAMETERS : none
593 *
594 * RETURN     : none
595 *==========================================================================*/
596QCameraReprocessChannel::~QCameraReprocessChannel()
597{
598}
599
600/*===========================================================================
601 * FUNCTION   : addReprocStreamsFromSource
602 *
603 * DESCRIPTION: add reprocess streams from input source channel
604 *
605 * PARAMETERS :
606 *   @allocator      : stream related buffer allocator
607 *   @config         : pp feature configuration
608 *   @pSrcChannel    : ptr to input source channel that needs reprocess
609 *   @minStreamBufNum: number of stream buffers needed
610 *   @paddingInfo    : padding information
611 *
612 * RETURN     : int32_t type of status
613 *              NO_ERROR  -- success
614 *              none-zero failure code
615 *==========================================================================*/
616int32_t QCameraReprocessChannel::addReprocStreamsFromSource(QCameraAllocator& allocator,
617                                                            cam_pp_feature_config_t &config,
618                                                            QCameraChannel *pSrcChannel,
619                                                            uint8_t minStreamBufNum,
620                                                            cam_padding_info_t *paddingInfo)
621{
622    int32_t rc = 0;
623    QCameraStream *pStream = NULL;
624    QCameraHeapMemory *pStreamInfoBuf = NULL;
625    cam_stream_info_t *streamInfo = NULL;
626
627    memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
628
629    for (int i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
630        pStream = pSrcChannel->getStreamByIndex(i);
631        if (pStream != NULL) {
632            if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
633                // Skip metadata for reprocess now because PP module cannot handle meta data
634                // May need furthur discussion if Imaginglib need meta data
635                continue;
636            }
637
638            pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
639            if (pStreamInfoBuf == NULL) {
640                ALOGE("%s: no mem for stream info buf", __func__);
641                rc = NO_MEMORY;
642                break;
643            }
644
645            streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
646            memset(streamInfo, 0, sizeof(cam_stream_info_t));
647            streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
648            rc = pStream->getFormat(streamInfo->fmt);
649            rc = pStream->getFrameDimension(streamInfo->dim);
650            streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
651            streamInfo->num_of_burst = minStreamBufNum;
652
653            streamInfo->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
654            streamInfo->reprocess_config.online.input_stream_id = pStream->getMyServerID();
655            streamInfo->reprocess_config.online.input_stream_type = pStream->getMyType();
656            streamInfo->reprocess_config.pp_feature_config = config;
657
658            if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
659                pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT))) {
660                streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC;
661            }
662            if (streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
663                if (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
664                    streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270) {
665                    // rotated by 90 or 270, need to switch width and height
666                    int32_t temp = streamInfo->dim.height;
667                    streamInfo->dim.height = streamInfo->dim.width;
668                    streamInfo->dim.width = temp;
669                }
670            }
671
672            // save source stream handler
673            mSrcStreamHandles[m_numStreams] = pStream->getMyHandle();
674
675            // add reprocess stream
676            rc = addStream(allocator,
677                           pStreamInfoBuf, minStreamBufNum,
678                           paddingInfo,
679                           NULL, NULL);
680            if (rc != NO_ERROR) {
681                ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
682                break;
683            }
684        }
685    }
686
687    if (rc == NO_ERROR) {
688        m_pSrcChannel = pSrcChannel;
689    }
690    return rc;
691}
692
693/*===========================================================================
694 * FUNCTION   : getStreamBySrouceHandle
695 *
696 * DESCRIPTION: find reprocess stream by its source stream handle
697 *
698 * PARAMETERS :
699 *   @srcHandle : source stream handle
700 *
701 * RETURN     : ptr to reprocess stream if found. NULL if not found
702 *==========================================================================*/
703QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
704{
705    QCameraStream *pStream = NULL;
706
707    for (int i = 0; i < m_numStreams; i++) {
708        if (mSrcStreamHandles[i] == srcHandle) {
709            pStream = mStreams[i];
710            break;
711        }
712    }
713
714    return pStream;
715}
716
717/*===========================================================================
718 * FUNCTION   : doReprocess
719 *
720 * DESCRIPTION: request to do a reprocess on the frame
721 *
722 * PARAMETERS :
723 *   @frame   : frame to be performed a reprocess
724 *
725 * RETURN     : int32_t type of status
726 *              NO_ERROR  -- success
727 *              none-zero failure code
728 *==========================================================================*/
729int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame)
730{
731    int32_t rc = 0;
732    if (m_numStreams < 1) {
733        ALOGE("%s: No reprocess stream is created", __func__);
734        return -1;
735    }
736    if (m_pSrcChannel == NULL) {
737        ALOGE("%s: No source channel for reprocess", __func__);
738        return -1;
739    }
740
741    // find meta data stream and index of meta data frame in the superbuf
742    QCameraStream *pMetaStream = NULL;
743    uint8_t meta_buf_index = 0;
744    for (int i = 0; i < frame->num_bufs; i++) {
745        QCameraStream *pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id);
746        if (pStream != NULL) {
747            if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
748                meta_buf_index = frame->bufs[i]->buf_idx;
749                pMetaStream = pStream;
750                break;
751            }
752        }
753    }
754
755    for (int i = 0; i < frame->num_bufs; i++) {
756        QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
757        if (pStream != NULL) {
758            if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
759                // Skip metadata for reprocess now because PP module cannot handle meta data
760                // May need furthur discussion if Imaginglib need meta data
761                continue;
762            }
763
764            cam_stream_parm_buffer_t param;
765            memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
766            param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
767            param.reprocess.buf_index = frame->bufs[i]->buf_idx;
768            param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
769            if (pMetaStream != NULL) {
770                // we have meta data frame bundled, sent together with reprocess frame
771                param.reprocess.meta_present = 1;
772                param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
773                param.reprocess.meta_buf_index = meta_buf_index;
774            }
775            rc = pStream->setParameter(param);
776            if (rc != NO_ERROR) {
777                ALOGE("%s: stream setParameter for reprocess failed", __func__);
778                break;
779            }
780        }
781    }
782    return rc;
783}
784
785/*===========================================================================
786 * FUNCTION   : doReprocess
787 *
788 * DESCRIPTION: request to do a reprocess on the frame
789 *
790 * PARAMETERS :
791 *   @buf_fd     : fd to the input buffer that needs reprocess
792 *   @buf_lenght : length of the input buffer
793 *   @ret_val    : result of reprocess.
794 *                 Example: Could be faceID in case of register face image.
795 *
796 * RETURN     : int32_t type of status
797 *              NO_ERROR  -- success
798 *              none-zero failure code
799 *==========================================================================*/
800int32_t QCameraReprocessChannel::doReprocess(int buf_fd,
801                                             uint32_t buf_length,
802                                             int32_t &ret_val)
803{
804    int32_t rc = 0;
805    if (m_numStreams < 1) {
806        ALOGE("%s: No reprocess stream is created", __func__);
807        return -1;
808    }
809
810    uint32_t buf_idx = 0;
811    for (int i = 0; i < m_numStreams; i++) {
812        rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
813                                 buf_idx, -1,
814                                 buf_fd, buf_length);
815
816        if (rc == NO_ERROR) {
817            cam_stream_parm_buffer_t param;
818            memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
819            param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
820            param.reprocess.buf_index = buf_idx;
821            rc = mStreams[i]->setParameter(param);
822            if (rc == NO_ERROR) {
823                ret_val = param.reprocess.ret_val;
824            }
825            mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
826                                  buf_idx, -1);
827        }
828    }
829    return rc;
830}
831
832}; // namespace qcamera
833