xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/aiq_core/RkLumaCore.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * rkisp_aiq_core.h
3  *
4  *  Copyright (c) 2019 Rockchip Corporation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 #include "RkLumaCore.h"
20 
21 #include <string.h>
22 
23 #include "v4l2_buffer_proxy.h"
24 #ifdef RK_SIMULATOR_HW
25 #include "simulator/isp20_hw_simulator.h"
26 #endif
27 #include "common/rk_aiq_comm.h"
28 #include "common/rkisp2-config.h"
29 
30 namespace RkCam {
31 #define ISP2X_MIPI_RAW_NORMAL 0
32 #define ISP2X_MIPI_RAW_LONG   1
33 #define ISP2X_MIPI_RAW_SHORT  2
34 
35 bool
loop()36 RkLumaCoreThread::loop()
37 {
38     ENTER_ANALYZER_FUNCTION();
39 
40     const static int32_t timeout = -1;
41     SmartPtr<VideoBuffer> luma = mStatsQueue.pop (timeout);
42 
43     if (!luma.ptr()) {
44         LOGW_ANALYZER("RkLumaCoreThread got empty stats, stop thread");
45         return false;
46     }
47 
48     XCamReturn ret = mRkLumaCore->analyze (luma);
49     if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_BYPASS)
50         return true;
51 
52     LOGE_ANALYZER("RkAiqCoreThread failed to analyze 3a stats");
53 
54     EXIT_ANALYZER_FUNCTION();
55 
56     return false;
57 }
58 
59 uint16_t RkLumaCore::DEFAULT_POOL_SIZE = 20;
60 
RkLumaCore()61 RkLumaCore::RkLumaCore()
62     : mState(RK_AIQ_CORE_STATE_INVALID)
63     , mWorkingMode(RK_AIQ_WORKING_MODE_NORMAL)
64     , mCb(NULL)
65     , mRkLumaCoreTh(new RkLumaCoreThread(this))
66 {
67     ENTER_ANALYZER_FUNCTION();
68     EXIT_ANALYZER_FUNCTION();
69 }
70 
~RkLumaCore()71 RkLumaCore::~RkLumaCore()
72 {
73     ENTER_ANALYZER_FUNCTION();
74     EXIT_ANALYZER_FUNCTION();
75 }
76 
77 XCamReturn
init(const CalibDbV2_LUMA_DETECT_t * lumaCalib)78 RkLumaCore::init(const CalibDbV2_LUMA_DETECT_t* lumaCalib)
79 {
80     ENTER_ANALYZER_FUNCTION();
81 
82     if (mState != RK_AIQ_CORE_STATE_INVALID) {
83         LOGE_ANALYZER("wrong state %d\n", mState);
84         return XCAM_RETURN_ERROR_ANALYZER;
85     }
86 
87     calib = lumaCalib;
88     LOGD_ANALYZER("en: %d, threshold: %f\n",
89                   lumaCalib->luma_detect_en,
90                   lumaCalib->mutation_threshold);
91 
92     mState = RK_AIQ_CORE_STATE_INITED;
93     return XCAM_RETURN_NO_ERROR;
94 
95     EXIT_ANALYZER_FUNCTION();
96 }
97 
98 XCamReturn
deInit()99 RkLumaCore::deInit()
100 {
101     ENTER_ANALYZER_FUNCTION();
102 
103     if (mState == RK_AIQ_CORE_STATE_STARTED) {
104         LOGE_ANALYZER("wrong state %d\n", mState);
105         return XCAM_RETURN_ERROR_ANALYZER;
106     }
107 
108     mState = RK_AIQ_CORE_STATE_INVALID;
109 
110     EXIT_ANALYZER_FUNCTION();
111 
112     return XCAM_RETURN_NO_ERROR;
113 }
114 
115 XCamReturn
start()116 RkLumaCore::start()
117 {
118     ENTER_ANALYZER_FUNCTION();
119 
120     if ((mState != RK_AIQ_CORE_STATE_INITED) &&
121             (mState != RK_AIQ_CORE_STATE_PREPARED) &&
122             (mState != RK_AIQ_CORE_STATE_STOPED)) {
123         LOGE_ANALYZER("wrong state %d\n", mState);
124         return XCAM_RETURN_ERROR_ANALYZER;
125     }
126 
127     mRkLumaCoreTh->triger_start();
128     mRkLumaCoreTh->start();
129     mState = RK_AIQ_CORE_STATE_STARTED;
130 
131     EXIT_ANALYZER_FUNCTION();
132 
133     return XCAM_RETURN_NO_ERROR;
134 }
135 
136 XCamReturn
stop()137 RkLumaCore::stop()
138 {
139     ENTER_ANALYZER_FUNCTION();
140 
141     if (mState != RK_AIQ_CORE_STATE_STARTED) {
142         LOGW_ANALYZER("in state %d\n", mState);
143         return XCAM_RETURN_NO_ERROR;
144     }
145 
146     mRkLumaCoreTh->triger_stop();
147     mRkLumaCoreTh->stop();
148     mState = RK_AIQ_CORE_STATE_STOPED;
149 
150     EXIT_ANALYZER_FUNCTION();
151 
152     return XCAM_RETURN_NO_ERROR;
153 }
154 
155 
156 XCamReturn
pushStats(SmartPtr<VideoBuffer> & buffer)157 RkLumaCore::pushStats(SmartPtr<VideoBuffer> &buffer)
158 {
159     ENTER_ANALYZER_FUNCTION();
160 
161     XCAM_ASSERT(buffer.ptr());
162     mRkLumaCoreTh->push_stats(buffer);
163 
164     EXIT_ANALYZER_FUNCTION();
165 
166     return XCAM_RETURN_NO_ERROR;
167 }
168 
169 XCamReturn
prepare(int mode)170 RkLumaCore::prepare(int mode)
171 {
172     mWorkingMode = mode;
173     return XCAM_RETURN_NO_ERROR;
174 }
175 
176 XCamReturn
analyze(const SmartPtr<VideoBuffer> & buffer)177 RkLumaCore::analyze(const SmartPtr<VideoBuffer> &buffer)
178 {
179     rk_aiq_luma_params_t luma_params;
180     memset(&luma_params, 0, sizeof(luma_params));
181     const SmartPtr<V4l2BufferProxy> buf =
182         buffer.dynamic_cast_ptr<V4l2BufferProxy>();
183 #ifdef RK_SIMULATOR_HW
184     rk_sim_isp_v200_luma_t* luma =
185         (rk_sim_isp_v200_luma_t*)(buf->get_v4l2_userptr());
186     LOGD_ANALYZER("lumatest rkaiq get luma(%d): %d\n",
187                   luma->valid_luma,
188                   luma->image_luma_result.mean_luma[0]);
189 
190     if (!mLumaQueueFIFO.is_empty()) {
191         SmartPtr<isp_luma_stat_t> luma_frame_pre = mLumaQueueFIFO.pop();
192         LOGD_ANALYZER("lumatest now pre: %d-%d-%d, datasize: %d\n",
193                       luma->image_luma_result.mean_luma[0],
194                       luma_frame_pre->mean_luma[0],
195                       mLumaQueueFIFO.size());
196         float dluma = float(luma_frame_pre->mean_luma[0] - luma->image_luma_result.mean_luma[0]) /
197                       (luma_frame_pre->mean_luma[0] + luma->image_luma_result.mean_luma[0]);
198 
199         if (dluma > 0.2 || dluma < -0.2) {
200             luma_params.hdrProcessCnt++;
201         }
202     }
203 
204     SmartPtr<isp_luma_stat_t> luma_result = new isp_luma_stat_t();
205     luma_result->mean_luma[0] = luma->image_luma_result.mean_luma[0];
206 
207     mLumaQueueFIFO.push(luma_result);
208 
209 
210     if (mCb)
211         mCb->rkLumaCalcDone(luma_params);
212 #else
213     rkisp_isp2x_luma_buffer* lumaStat =
214         (rkisp_isp2x_luma_buffer*)(buf->get_v4l2_userptr());
215     luma_params.frame_id = lumaStat->frame_id;
216 
217     if (calib->fixed_times > 0) {
218         luma_params.hdrProcessCnt = calib->fixed_times - 1;
219         if (luma_params.hdrProcessCnt > 2)
220             luma_params.hdrProcessCnt = 2;
221 
222         if (mCb)
223             mCb->rkLumaCalcDone(luma_params);
224 
225         return XCAM_RETURN_NO_ERROR;
226     }
227 
228 
229     int raw_channal = 1;
230     switch (mWorkingMode)
231     {
232     case RK_AIQ_WORKING_MODE_NORMAL:
233         raw_channal = 0;
234         break;
235     case RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR:
236     case RK_AIQ_ISP_HDR_MODE_2_LINE_HDR:
237         raw_channal = 0;
238         break;
239     case RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR:
240     case RK_AIQ_ISP_HDR_MODE_3_LINE_HDR:
241         raw_channal = 1;
242         break;
243     default:
244         raw_channal = 1;
245         break;
246     }
247 
248     memcpy(luma_params.luma, lumaStat->luma, sizeof(lumaStat->luma));
249 
250     unsigned int mean_luma = 0;
251     for (int i = 0; i < ISP2X_MIPI_LUMA_MEAN_MAX; i++) {
252         mean_luma += lumaStat->luma[raw_channal].exp_mean[i];
253     }
254     mean_luma = mean_luma / ISP2X_MIPI_LUMA_MEAN_MAX;
255 
256     if (!mLumaQueueFIFO.is_empty()) {
257         SmartPtr<isp_luma_stat_t> luma_frame_pre = mLumaQueueFIFO.pop();
258 
259         float dluma = int(luma_frame_pre->mean_luma[raw_channal] - mean_luma) /
260                       float(luma_frame_pre->mean_luma[raw_channal] + mean_luma);
261 
262         if (dluma > calib->mutation_threshold_level2 || \
263                 dluma < -calib->mutation_threshold_level2)
264             luma_params.hdrProcessCnt = 2;
265         else if (dluma > calib->mutation_threshold || \
266                 dluma < -calib->mutation_threshold )
267             luma_params.hdrProcessCnt = 1;
268 
269         LOGV_ANALYZER("id(%d) working_mode(0x%x) now-pre: %d-%d, threshold: %f, threshold_level2: %f, "
270                       "dluma: %f, hdrProcessCnt: %d, datasize: %d\n",
271                       lumaStat->frame_id,
272                       mWorkingMode,
273                       mean_luma,
274                       luma_frame_pre->mean_luma[raw_channal],
275                       calib->mutation_threshold,
276                       calib->mutation_threshold_level2,
277                       dluma,
278                       luma_params.hdrProcessCnt,
279                       mLumaQueueFIFO.size());
280     }
281 
282     SmartPtr<isp_luma_stat_t> luma_result = new isp_luma_stat_t();
283     luma_result->mean_luma[raw_channal] = mean_luma;
284 
285     mLumaQueueFIFO.push(luma_result);
286 
287     if (mCb)
288         mCb->rkLumaCalcDone(luma_params);
289 #endif
290 
291 
292     return XCAM_RETURN_NO_ERROR;
293 }
294 
295 } //namespace RkCam
296