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