1 /* Copyright (c) 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 "QCameraHALPP"
31 
32 // Camera dependencies
33 #include <sys/stat.h>
34 #include "QCameraTrace.h"
35 #include "QCameraHALPP.h"
36 #include "QCameraQueue.h"
37 extern "C" {
38 #include "mm_camera_dbg.h"
39 }
40 
41 namespace qcamera {
42 
43 /*===========================================================================
44  * FUNCTION   : QCameraHALPP
45  *
46  * DESCRIPTION: constructor of QCameraHALPP.
47  *
48  * PARAMETERS : None
49  *
50  * RETURN     : None
51  *==========================================================================*/
QCameraHALPP()52 QCameraHALPP::QCameraHALPP()
53     : m_iuputQ(releaseInputDataCb, this),
54       m_outgoingQ(releaseOngoingDataCb, this),
55       m_halPPBufNotifyCB(NULL),
56       m_halPPGetOutputCB(NULL),
57       m_pQCameraPostProc(NULL)
58 {
59 }
60 
61 /*===========================================================================
62  * FUNCTION   : ~QCameraHALPP
63  *
64  * DESCRIPTION: destructor of QCameraHALPP.
65  *
66  * PARAMETERS : None
67  *
68  * RETURN     : None
69  *==========================================================================*/
~QCameraHALPP()70 QCameraHALPP::~QCameraHALPP()
71 {
72 }
73 
74 /*===========================================================================
75  * FUNCTION   : init
76  *
77  * DESCRIPTION: initialization of QCameraHALPP
78  *
79  * PARAMETERS :
80  *   @bufNotifyCb      : call back function after HALPP process done and return frame
81  *   @getOutputCb      : call back function to request output buffer
82  *   @pUserData        : Parent of HALPP, i.e. QCameraPostProc
83  *
84  * RETURN     : int32_t type of status
85  *              NO_ERROR  -- success
86  *              none-zero failure code
87  *==========================================================================*/
init(halPPBufNotify bufNotifyCb,halPPGetOutput getOutputCb,void * pUserData)88 int32_t QCameraHALPP::init(halPPBufNotify bufNotifyCb, halPPGetOutput getOutputCb, void *pUserData)
89 {
90     int32_t rc = NO_ERROR;
91     // connect HALPP call back function
92     m_halPPBufNotifyCB = bufNotifyCb;
93     m_halPPGetOutputCB = getOutputCb;
94     m_pQCameraPostProc = (QCameraPostProcessor*)pUserData;
95     return rc;
96 }
97 
98 /*===========================================================================
99  * FUNCTION   : deinit
100  *
101  * DESCRIPTION: de-initialization of QCameraHALPP
102  *
103  * PARAMETERS :
104  *
105  * RETURN     : int32_t type of status
106  *              NO_ERROR  -- success
107  *              none-zero failure code
108  *==========================================================================*/
deinit()109 int32_t QCameraHALPP::deinit()
110 {
111     int32_t rc = NO_ERROR;
112     m_halPPBufNotifyCB = NULL;
113     m_halPPGetOutputCB = NULL;
114     m_pQCameraPostProc = NULL;
115     return rc;
116 }
117 
118 /*===========================================================================
119  * FUNCTION   : start
120  *
121  * DESCRIPTION: starting QCameraHALPP
122  *
123  * PARAMETERS :
124  *
125  * RETURN     : int32_t type of status
126  *              NO_ERROR  -- success
127  *              none-zero failure code
128  *==========================================================================*/
start()129 int32_t QCameraHALPP::start()
130 {
131     int32_t rc = NO_ERROR;
132     LOGD("E");
133 
134     LOGD("X");
135     return rc;
136 }
137 
138 /*===========================================================================
139  * FUNCTION   : stop
140  *
141  * DESCRIPTION: stop QCameraHALPP
142  *
143  * PARAMETERS :
144  *
145  * RETURN     : int32_t type of status
146  *              NO_ERROR  -- success
147  *              none-zero failure code
148  *==========================================================================*/
stop()149 int32_t QCameraHALPP::stop()
150 {
151     int32_t rc = NO_ERROR;
152     LOGD("E");
153 
154     LOGD("X");
155     return rc;
156 }
157 
158 /*===========================================================================
159  * FUNCTION   : flushQ
160  *
161  * DESCRIPTION: flush m_iuputQ and m_outgoingQ.
162  *
163  * PARAMETERS : None
164  *
165  * RETURN     : None
166  *==========================================================================*/
flushQ()167 int32_t QCameraHALPP::flushQ()
168 {
169     int32_t rc = NO_ERROR;
170     m_iuputQ.flush();
171     m_outgoingQ.flush();
172     return rc;
173 }
174 
175 /*===========================================================================
176  * FUNCTION   : initQ
177  *
178  * DESCRIPTION: init m_iuputQ and m_outgoingQ.
179  *
180  * PARAMETERS : None
181  *
182  * RETURN     : None
183  *==========================================================================*/
initQ()184 int32_t QCameraHALPP::initQ()
185 {
186     int32_t rc = NO_ERROR;
187     m_iuputQ.init();
188     m_outgoingQ.init();
189     return rc;
190 }
191 
192 /*===========================================================================
193  * FUNCTION   : getFrameVector
194  *
195  * DESCRIPTION: get vector of input frames from map
196  *
197  * PARAMETERS :
198  *   @frameIndex      : frame index (key of the map)
199  *
200  * RETURN     : vector pointer
201  *==========================================================================*/
202 std::vector<qcamera_hal_pp_data_t*>*
getFrameVector(uint32_t frameIndex)203         QCameraHALPP::getFrameVector(uint32_t frameIndex)
204 {
205     std::vector<qcamera_hal_pp_data_t*> *pVector = NULL;
206     // Search vector of input frames in frame map
207     if (m_frameMap.find(frameIndex) != m_frameMap.end()) {
208         pVector = m_frameMap[frameIndex];
209     }
210     return pVector;
211 }
212 
213 /*===========================================================================
214  * FUNCTION   : releaseData
215  *
216  * DESCRIPTION: release buffer in qcamera_hal_pp_data_t
217  *
218  * PARAMETERS :
219  *   @pData      : hal pp data
220  *
221  * RETURN     : None
222  *==========================================================================*/
releaseData(qcamera_hal_pp_data_t * pData)223 void QCameraHALPP::releaseData(qcamera_hal_pp_data_t *pData)
224 {
225     if (pData) {
226         if (pData->src_reproc_frame) {
227             if (!pData->reproc_frame_release) {
228                 m_pQCameraPostProc->releaseSuperBuf(pData->src_reproc_frame);
229             }
230             free(pData->src_reproc_frame);
231             pData->src_reproc_frame = NULL;
232         }
233         mm_camera_super_buf_t *frame = pData->frame;
234         if (frame) {
235             if (pData->halPPAllocatedBuf && pData->bufs) {
236                 free(pData->bufs);
237             } else {
238                 m_pQCameraPostProc->releaseSuperBuf(frame);
239             }
240             free(frame);
241             frame = NULL;
242         }
243         if (pData->snapshot_heap) {
244             pData->snapshot_heap->deallocate();
245             delete pData->snapshot_heap;
246             pData->snapshot_heap = NULL;
247         }
248         if (pData->metadata_heap) {
249             pData->metadata_heap->deallocate();
250             delete pData->metadata_heap;
251             pData->metadata_heap = NULL;
252         }
253         if (NULL != pData->src_reproc_bufs) {
254             delete [] pData->src_reproc_bufs;
255         }
256         if ((pData->offline_reproc_buf != NULL)
257                 && (pData->offline_buffer)) {
258             free(pData->offline_reproc_buf);
259             pData->offline_reproc_buf = NULL;
260             pData->offline_buffer = false;
261         }
262     }
263 }
264 
265 /*===========================================================================
266  * FUNCTION   : releaseOngoingDataCb
267  *
268  * DESCRIPTION: callback function to release ongoing data node
269  *
270  * PARAMETERS :
271  *   @pData     : ptr to ongoing job data
272  *   @pUserData : user data ptr (QCameraHALPP)
273  *
274  * RETURN     : None
275  *==========================================================================*/
releaseOngoingDataCb(void * pData,void * pUserData)276 void QCameraHALPP::releaseOngoingDataCb(void *pData, void *pUserData)
277 {
278     if (pUserData != NULL && pData != NULL) {
279         QCameraHALPP *pme = (QCameraHALPP *)pUserData;
280         pme->releaseData((qcamera_hal_pp_data_t*)pData);
281     }
282 }
283 
284 /*===========================================================================
285  * FUNCTION   : releaseInputDataCb
286  *
287  * DESCRIPTION: callback function to release input data node
288  *
289  * PARAMETERS :
290  *   @pData     : ptr to input job data
291  *   @pUserData : user data ptr (QCameraHALPP)
292  *
293  * RETURN     : None
294  *==========================================================================*/
releaseInputDataCb(void * pData,void * pUserData)295 void QCameraHALPP::releaseInputDataCb(void *pData, void *pUserData)
296 {
297     if (pUserData != NULL && pData != NULL) {
298         QCameraHALPP *pme = (QCameraHALPP *)pUserData;
299         // what enqueued to the input queue is just the frame index
300         // we need to use hash map to find the vector of frames and release the buffers
301         uint32_t *pFrameIndex = (uint32_t *)pData;
302         uint32_t frameIndex = *pFrameIndex;
303         std::vector<qcamera_hal_pp_data_t*> *pVector = pme->getFrameVector(frameIndex);
304         if (pVector != NULL) {
305             for (size_t i = 0; i < pVector->size(); i++) {
306                 if (pVector->at(i) != NULL) {
307                     pme->releaseData(pVector->at(i));
308                 }
309             }
310             delete pVector;
311             pVector = NULL;
312         }
313         delete pFrameIndex;
314         pFrameIndex = NULL;
315     }
316 }
317 
dumpYUVtoFile(const uint8_t * pBuf,const char * name,ssize_t buf_len)318 void QCameraHALPP::dumpYUVtoFile(const uint8_t* pBuf, const char *name, ssize_t buf_len)
319 {
320     LOGD("E.");
321 
322     int file_fd = open(name, O_RDWR | O_CREAT, 0777);
323     if (file_fd > 0) {
324         fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
325         ssize_t writen_bytes = 0;
326         writen_bytes = write(file_fd, pBuf, buf_len);
327         close(file_fd);
328         LOGD("dump output frame to file: %s, size:%d", name, buf_len);
329     }
330 
331     LOGD("X.");
332 }
333 
334 } // namespace qcamera
335