3 ** Copyright 2013, Samsung Electronics Co. LTD
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
18 /* #define LOG_NDEBUG 0 */
19 #define LOG_TAG "ExynosCameraPipeGSC"
20 #include <cutils/log.h>
22 #include "ExynosCameraPipeGSC.h"
26 ExynosCameraPipeGSC::~ExynosCameraPipeGSC()
31 status_t
ExynosCameraPipeGSC::create(__unused
int32_t *sensorIds
)
33 CSC_METHOD cscMethod
= CSC_METHOD_HW
;
35 m_csc
= csc_init(cscMethod
);
37 CLOGE("ERR(%s):csc_init() fail", __FUNCTION__
);
38 return INVALID_OPERATION
;
41 csc_set_hw_property(m_csc
, m_property
, m_gscNum
);
43 m_mainThread
= ExynosCameraThreadFactory::createThread(this, &ExynosCameraPipeGSC::m_mainThreadFunc
, "GSCThread");
45 m_inputFrameQ
= new frame_queue_t(m_mainThread
);
47 CLOGI("INFO(%s[%d]):create() is succeed (%d)", __FUNCTION__
, __LINE__
, getPipeId());
52 status_t
ExynosCameraPipeGSC::destroy(void)
58 if (m_inputFrameQ
!= NULL
) {
59 m_inputFrameQ
->release();
64 CLOGI("INFO(%s[%d]):destroy() is succeed (%d)", __FUNCTION__
, __LINE__
, getPipeId());
69 status_t
ExynosCameraPipeGSC::start(void)
71 CLOGD("DEBUG(%s[%d])", __FUNCTION__
, __LINE__
);
73 m_flagTryStop
= false;
78 status_t
ExynosCameraPipeGSC::stop(void)
80 CLOGD("DEBUG(%s[%d])", __FUNCTION__
, __LINE__
);
85 m_mainThread
->requestExitAndWait();
87 CLOGD("DEBUG(%s[%d]): thead exited", __FUNCTION__
, __LINE__
);
89 m_inputFrameQ
->release();
91 m_flagTryStop
= false;
96 status_t
ExynosCameraPipeGSC::startThread(void)
98 CLOGV("DEBUG(%s[%d])", __FUNCTION__
, __LINE__
);
100 if (m_outputFrameQ
== NULL
) {
101 CLOGE("ERR(%s):outputFrameQ is NULL, cannot start", __FUNCTION__
);
102 return INVALID_OPERATION
;
107 CLOGI("INFO(%s[%d]):startThread is succeed (%d)", __FUNCTION__
, __LINE__
, getPipeId());
112 status_t
ExynosCameraPipeGSC::m_run(void)
114 ExynosCameraFrame
*newFrame
= NULL
;
115 ExynosCameraBuffer srcBuffer
;
116 ExynosCameraBuffer dstBuffer
;
119 ExynosCameraFrameEntity
*entity
= NULL
;
123 int flipHorizontal
= 0;
124 int flipVertical
= 0;
126 ret
= m_inputFrameQ
->waitAndPopProcessQ(&newFrame
);
128 /* TODO: We need to make timeout duration depends on FPS */
129 if (ret
== TIMED_OUT
) {
130 CLOGW("WARN(%s):wait timeout", __FUNCTION__
);
132 CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__
, ret
);
133 /* TODO: doing exception handling */
138 if (newFrame
== NULL
) {
139 CLOGE("ERR(%s):new frame is NULL", __FUNCTION__
);
143 entity
= newFrame
->searchEntityByPipeId(getPipeId());
144 if (entity
== NULL
|| entity
->getSrcBufState() == ENTITY_BUFFER_STATE_ERROR
) {
145 CLOGE("ERR(%s[%d]):frame(%d) entityState(ENTITY_BUFFER_STATE_ERROR), skip msc", __FUNCTION__
, __LINE__
, newFrame
->getFrameCount());
149 rotation
= newFrame
->getRotation(getPipeId());
150 CLOGV("INFO(%s[%d]): getPipeId(%d), rotation(%d)", __FUNCTION__
, __LINE__
, getPipeId(), rotation
);
152 #ifdef PERFRAME_CONTROL_FOR_FLIP
153 flipHorizontal
= newFrame
->getFlipHorizontal(getPipeId());
154 flipVertical
= newFrame
->getFlipVertical(getPipeId());
156 flipHorizontal
= m_parameters
->getFlipHorizontal();
157 flipVertical
= m_parameters
->getFlipVertical();
160 ret
= newFrame
->getSrcRect(getPipeId(), &srcRect
);
161 ret
= newFrame
->getDstRect(getPipeId(), &dstRect
);
163 switch (srcRect
.colorFormat
) {
164 case V4L2_PIX_FMT_NV21
:
165 srcRect
.fullH
= ALIGN_UP(srcRect
.fullH
, 2);
168 srcRect
.fullH
= ALIGN_UP(srcRect
.fullH
, GSCALER_IMG_ALIGN
);
172 csc_set_src_format(m_csc
,
173 ALIGN_UP(srcRect
.fullW
, GSCALER_IMG_ALIGN
),
175 srcRect
.x
, srcRect
.y
, srcRect
.w
, srcRect
.h
,
176 V4L2_PIX_2_HAL_PIXEL_FORMAT(srcRect
.colorFormat
),
179 csc_set_dst_format(m_csc
,
180 dstRect
.fullW
, dstRect
.fullH
,
181 dstRect
.x
, dstRect
.y
, dstRect
.fullW
, dstRect
.fullH
,
182 V4L2_PIX_2_HAL_PIXEL_FORMAT(dstRect
.colorFormat
),
185 ret
= newFrame
->getSrcBuffer(getPipeId(), &srcBuffer
);
187 CLOGE("ERR(%s[%d]):frame get src buffer fail, ret(%d)", __FUNCTION__
, __LINE__
, ret
);
188 /* TODO: doing exception handling */
192 ret
= newFrame
->getDstBuffer(getPipeId(), &dstBuffer
);
194 CLOGE("ERR(%s[%d]):frame get dst buffer fail, ret(%d)", __FUNCTION__
, __LINE__
, ret
);
195 /* TODO: doing exception handling */
199 csc_set_src_buffer(m_csc
,
200 (void **)srcBuffer
.fd
, CSC_MEMORY_TYPE
);
202 csc_set_dst_buffer(m_csc
,
203 (void **)dstBuffer
.fd
, CSC_MEMORY_TYPE
);
205 if (csc_convert_with_rotation(m_csc
, rotation
, flipHorizontal
, flipVertical
) != 0)
206 CLOGE("ERR(%s):csc_convert() fail", __FUNCTION__
);
208 CLOGV("DEBUG(%s[%d]):Rotation(%d), flip horizontal(%d), vertical(%d)",
209 __FUNCTION__
, __LINE__
, rotation
, flipHorizontal
, flipVertical
);
211 CLOGV("DEBUG(%s[%d]):CSC(%d) converting done", __FUNCTION__
, __LINE__
, m_gscNum
);
213 ret
= newFrame
->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE
);
215 CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__
, __LINE__
, ret
);
216 /* TODO: doing exception handling */
220 m_outputFrameQ
->pushProcessQ(&newFrame
);
226 ret
= newFrame
->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE
);
228 CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__
, __LINE__
, ret
);
229 /* TODO: doing exception handling */
233 m_outputFrameQ
->pushProcessQ(&newFrame
);
237 bool ExynosCameraPipeGSC::m_mainThreadFunc(void)
243 if (ret
!= TIMED_OUT
)
244 CLOGE("ERR(%s):m_putBuffer fail", __FUNCTION__
);
247 return m_checkThreadLoop();
250 void ExynosCameraPipeGSC::m_init(int32_t *nodeNums
)
252 if (nodeNums
== NULL
)
255 m_gscNum
= nodeNums
[0];
258 m_property
= (nodeNums
== NULL
) ? CSC_HW_PROPERTY_DEFAULT
: CSC_HW_PROPERTY_FIXED_NODE
;
261 }; /* namespace android */