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