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