1 /*
2 * rk_aiq_ldch_generate_mesh.cpp
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
20 #include "xcam_log.h"
21 #include "rk_aiq_ldch_generate_mesh.h"
22
23 #define LDCH_CUSTOM_MESH "ldch_custom_mesh.bin"
24
25 RKAIQ_BEGIN_DECLARE
26
27
alloc_ldch_buf(LDCHContext_t * ldchCtx)28 static XCamReturn alloc_ldch_buf(LDCHContext_t* ldchCtx)
29 {
30 if (!ldchCtx->hasAllocShareMem.load(std::memory_order_acquire)) {
31 LOGD_ALDCH("alloc ldch buf");
32 release_ldch_buf(ldchCtx);
33 rk_aiq_share_mem_config_t share_mem_config;
34 share_mem_config.alloc_param.width = ldchCtx->dst_width;
35 share_mem_config.alloc_param.height = ldchCtx->dst_height;
36 share_mem_config.mem_type = MEM_TYPE_LDCH;
37 ldchCtx->share_mem_ops->alloc_mem(0, ldchCtx->share_mem_ops,
38 &share_mem_config,
39 &ldchCtx->share_mem_ctx);
40 if (ldchCtx->share_mem_ctx) {
41 ldchCtx->hasAllocShareMem.store(true, std::memory_order_release);
42 } else {
43 LOGE_ALDCH("Failed to alloc shared mem");
44 return XCAM_RETURN_ERROR_MEM;
45 }
46 }
47
48 return XCAM_RETURN_NO_ERROR;
49 }
50
release_ldch_buf(LDCHContext_t * ldchCtx)51 XCamReturn release_ldch_buf(LDCHContext_t* ldchCtx)
52 {
53 if (ldchCtx->hasAllocShareMem.load(std::memory_order_acquire)) {
54 LOGD_ALDCH("release ldch buf");
55 if (ldchCtx->share_mem_ctx)
56 ldchCtx->share_mem_ops->release_mem(0, ldchCtx->share_mem_ctx);
57 ldchCtx->hasAllocShareMem.store(false, std::memory_order_release);
58 }
59
60 return XCAM_RETURN_NO_ERROR;
61 }
62
get_ldch_buf(LDCHContext_t * ldchCtx)63 XCamReturn get_ldch_buf(LDCHContext_t* ldchCtx)
64 {
65 if (alloc_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
66 LOGE_ALDCH("Failed to alloc ldch buf\n");
67 return XCAM_RETURN_ERROR_MEM;
68 }
69
70 ldchCtx->ldch_mem_info = (rk_aiq_ldch_share_mem_info_t *)
71 ldchCtx->share_mem_ops->get_free_item(0, ldchCtx->share_mem_ctx);
72 if (ldchCtx->ldch_mem_info == NULL || \
73 (ldchCtx->ldch_mem_info && \
74 ldchCtx->ldch_mem_info->state[0] != MESH_BUF_INIT)) {
75 LOGE_ALDCH("%s: no free ldch buf", __FUNCTION__);
76 return XCAM_RETURN_ERROR_MEM;
77 }
78 ldchCtx->ldch_mem_info->state[0] = MESH_BUF_WAIT2CHIP; //mark that this buf is using.
79
80 LOGD_ALDCH("LDCH get buf: fd %d, addr %p, size %d",
81 ldchCtx->ldch_mem_info->fd,
82 ldchCtx->ldch_mem_info->addr,
83 ldchCtx->ldch_mem_info->size);
84
85 return XCAM_RETURN_NO_ERROR;
86 }
87
put_ldch_buf(LDCHContext_t * ldchCtx)88 void put_ldch_buf(LDCHContext_t* ldchCtx)
89 {
90 if (ldchCtx->ldch_mem_info && ldchCtx->ldch_mem_info->state[0] == MESH_BUF_WAIT2CHIP) {
91 ldchCtx->ldch_mem_info->state[0] = MESH_BUF_INIT;
92 LOGD_ALDCH("LDCH put buf: fd %d, addr %p, size %d",
93 ldchCtx->ldch_mem_info->fd,
94 ldchCtx->ldch_mem_info->addr,
95 ldchCtx->ldch_mem_info->size);
96
97 ldchCtx->ldch_mem_info = NULL;
98 }
99 }
100
101 bool
read_mesh_from_file(LDCHContext_t * ldchCtx,const char * fileName)102 read_mesh_from_file(LDCHContext_t* ldchCtx, const char* fileName)
103 {
104 FILE* ofp;
105 ofp = fopen(fileName, "rb");
106 if (ofp != NULL) {
107 unsigned short hpic, vpic, hsize, vsize, hstep, vstep = 0;
108 uint32_t lut_size = 0;
109
110 fread(&hpic, sizeof(unsigned short), 1, ofp);
111 fread(&vpic, sizeof(unsigned short), 1, ofp);
112 fread(&hsize, sizeof(unsigned short), 1, ofp);
113 fread(&vsize, sizeof(unsigned short), 1, ofp);
114 fread(&hstep, sizeof(unsigned short), 1, ofp);
115 fread(&vstep, sizeof(unsigned short), 1, ofp);
116
117 lut_size = hsize * vsize * sizeof(uint16_t);
118 LOGW_ALDCH("lut info: [%d-%d-%d-%d-%d-%d]", hpic, vpic, hsize, vsize, hstep, vstep);
119 unsigned int num = fread(ldchCtx->ldch_mem_info->addr, 1, lut_size, ofp);
120 fclose(ofp);
121
122 if (num != lut_size) {
123 LOGE_ALDCH("mismatched lut calib file");
124 return false;
125 }
126
127 if (ldchCtx->src_width != hpic || ldchCtx->src_height != vpic) {
128 LOGE_ALDCH("mismatched lut pic resolution: src %dx%d, lut %dx%d",
129 ldchCtx->src_width, ldchCtx->src_height, hpic, vpic);
130 return false;
131 }
132
133 ldchCtx->lut_h_size = hsize;
134 ldchCtx->lut_v_size = vsize;
135 ldchCtx->lut_mapxy_size = lut_size;
136 ldchCtx->lut_h_size = hsize / 2; //word unit
137
138 LOGW_ALDCH("check file, size: %d, num: %d", ldchCtx->lut_mapxy_size, num);
139 } else {
140 LOGE_ALDCH("lut file %s not exist", fileName);
141 return false;
142 }
143
144 return true;
145 }
146
147
148 #if GENMESH_ONLINE
aiqGenLdchMeshInit(LDCHContext_t * ldchCtx)149 XCamReturn aiqGenLdchMeshInit(LDCHContext_t* ldchCtx)
150 {
151 XCamReturn ret = XCAM_RETURN_NO_ERROR;
152
153 if (ldchCtx->genLdchMeshInit) {
154 LOGW_ALDCH("genLDCHMesh has been initialized!!\n");
155 if (get_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
156 LOGE_ALDCH("Failed to get ldch buf\n");
157 return XCAM_RETURN_ERROR_MEM;
158 }
159 return XCAM_RETURN_NO_ERROR;
160 }
161
162 ldchCtx->ldchParams.isLdchOld = 1;
163 ldchCtx->ldchParams.saveMeshX = false;
164 if (ldchCtx->ldchParams.saveMeshX) {
165 sprintf(ldchCtx->ldchParams.meshPath, "/tmp/");
166 }
167 genLdchMeshInit(ldchCtx->src_width, ldchCtx->src_height,
168 ldchCtx->dst_width, ldchCtx->dst_height,
169 ldchCtx->ldchParams, ldchCtx->camCoeff);
170
171 ldchCtx->lut_h_size = (ldchCtx->ldchParams.meshSizeW + 1) / 2; //word unit
172 ldchCtx->lut_v_size = ldchCtx->ldchParams.meshSizeH;
173 ldchCtx->lut_mapxy_size = ldchCtx->ldchParams.meshSize * sizeof(unsigned short);
174 LOGI_ALDCH("ldch en %d, h/v size(%dx%d), mapxy size(%d), correct_level: %d",
175 ldchCtx->ldch_en,
176 ldchCtx->lut_h_size,
177 ldchCtx->lut_v_size,
178 ldchCtx->lut_mapxy_size ,
179 ldchCtx->correct_level);
180
181 if (get_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
182 LOGE_ALDCH("Failed to get ldch buf\n");
183 ret = XCAM_RETURN_ERROR_MEM;
184 }
185
186 ldchCtx->genLdchMeshInit = true;
187
188 return ret;
189 }
190
aiqGenLdchMeshDeInit(LDCHContext_t * ldchCtx)191 XCamReturn aiqGenLdchMeshDeInit(LDCHContext_t* ldchCtx)
192 {
193 if (!ldchCtx->genLdchMeshInit) {
194 return XCAM_RETURN_NO_ERROR;
195 }
196
197 genLdchMeshDeInit(ldchCtx->ldchParams);
198 release_ldch_buf(ldchCtx);
199
200 ldchCtx->genLdchMeshInit = false;
201
202 return XCAM_RETURN_NO_ERROR;
203 }
204
aiqGenMesh(LDCHContext_t * ldchCtx,int32_t level)205 bool aiqGenMesh(LDCHContext_t* ldchCtx, int32_t level)
206 {
207 bool success = false;
208
209 if (level == 0) {
210 char filename[512];
211 sprintf(filename, "%s/%s",
212 ldchCtx->resource_path,
213 LDCH_CUSTOM_MESH);
214 success = read_mesh_from_file(ldchCtx, filename);
215 if (success) {
216 LOGW_ALDCH("read mesh from %s", filename);
217 }
218 }
219
220 if (!success && ldchCtx->ldch_mem_info)
221 success = genLDCMeshNLevel(ldchCtx->ldchParams, ldchCtx->camCoeff,
222 level, (uint16_t *)ldchCtx->ldch_mem_info->addr);
223
224 return success;
225 }
226 #endif
227
228 RKAIQ_END_DECLARE
229