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"
37extern "C" {
38#include "mm_camera_dbg.h"
39}
40
41namespace qcamera {
42
43/*===========================================================================
44 * FUNCTION   : QCameraHALPP
45 *
46 * DESCRIPTION: constructor of QCameraHALPP.
47 *
48 * PARAMETERS : None
49 *
50 * RETURN     : None
51 *==========================================================================*/
52QCameraHALPP::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 *==========================================================================*/
70QCameraHALPP::~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 *==========================================================================*/
88int32_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 *==========================================================================*/
109int32_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 *==========================================================================*/
129int32_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 *==========================================================================*/
149int32_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 *==========================================================================*/
167int32_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 *==========================================================================*/
184int32_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 *==========================================================================*/
202std::vector<qcamera_hal_pp_data_t*>*
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 *==========================================================================*/
223void 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 *==========================================================================*/
276void 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 *==========================================================================*/
295void 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
318void 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