xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/iq_parser_v2/scene/scene_manager.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *  Copyright (c) 2021 Rockchip Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #include "scene_manager.h"
19 #include "RkAiqCalibDbV2.h"
20 #include "j2s.h"
21 #include <fcntl.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 namespace RkCam {
27 
28 std::map<std::string, AiqScene> RkAiqSceneManager::sceneMap;
29 
loadIQFile(const char * name)30 cJSON *RkAiqSceneManager::loadIQFile(const char *name) {
31   char *json_data = NULL;
32   size_t json_data_size = 0;
33   cJSON *out_json = NULL;
34 
35   json_data = (char *)j2s_read_file(name, &json_data_size);
36   out_json = cJSON_Parse(json_data);
37   if (json_data) {
38     free(json_data);
39   }
40 
41   return out_json;
42 }
43 
addScene(const char * name,const char * base,const char * fragment)44 int RkAiqSceneManager::addScene(const char *name, const char *base,
45                                 const char *fragment) {
46   sceneMap[name] = std::make_pair(std::string(base), std::string(fragment));
47 
48   return 0;
49 }
50 
addScene(const char * name,AiqScene scene)51 int RkAiqSceneManager::addScene(const char *name, AiqScene scene) {
52   sceneMap[name] = scene;
53   return 0;
54 }
55 
matchScene(const char * name)56 AiqScene RkAiqSceneManager::matchScene(const char *name) {
57   auto search = sceneMap.find(std::string(name));
58 
59   if (search != sceneMap.end()) {
60     return search->second;
61   } else {
62     std::cout << "Not found\n";
63   }
64 
65   return AiqScene();
66 }
67 
getSceneIQ(const char * base,const char * fragment)68 const char *RkAiqSceneManager::getSceneIQ(const char *base,
69                                           const char *fragment) {
70   cJSON *base_json = NULL;
71   cJSON *fragment_json = NULL;
72   cJSON *out_json = NULL;
73 
74   base_json = loadIQFile(base);
75   if (!base_json) {
76     printf("Error before: [%s]\n", cJSON_GetErrorPtr());
77   } else {
78     char *out = cJSON_Print(base_json);
79     // printf("%s\n", out);
80     free(out);
81   }
82 
83   fragment_json = loadIQFile(fragment);
84   if (!fragment_json) {
85     printf("Error before: [%s]\n", cJSON_GetErrorPtr());
86   } else {
87     char *out = cJSON_Print(fragment_json);
88     // printf("%s\n", out);
89     free(out);
90   }
91 
92   // foreach fragment json obj, if fragment first level son obj is not empty
93   // then override base json's same object
94   if (cJSON_Compare(base_json, fragment_json, 1)) {
95     printf("same iq files, do nothing!\n");
96     char *out = cJSON_Print(base_json);
97     return out;
98   }
99 
100   for (int i = 0; i < cJSON_GetArraySize(base_json); i++) {
101     printf("[%d]:", i);
102     cJSON *item = cJSON_GetArrayItem(base_json, i);
103     if (cJSON_Invalid != item->type) {
104       printf("[%s]\n", item->string);
105       // printJson(item);
106     }
107   }
108 
109   out_json = cJSON_Duplicate(base_json, 1);
110 
111   // FIXME: memery leack issue
112   for (int i = 0; i < cJSON_GetArraySize(fragment_json); i++) {
113     printf("[%d]:", i);
114     cJSON *item = cJSON_GetArrayItem(fragment_json, i);
115     if (cJSON_Invalid != item->type) {
116       printf("[%s]\n", item->string);
117       // printJson(item);
118       cJSON_ReplaceItemInObjectCaseSensitive(out_json, item->string,
119                                              cJSON_Duplicate(item, 1));
120     }
121   }
122 
123   printf("new json:>\n%s\n", cJSON_Print(out_json));
124 
125   cJSON_Delete(base_json);
126   cJSON_Delete(fragment_json);
127 
128   return cJSON_Print(out_json);
129 }
130 
getSceneIQ(AiqScene scene)131 const char *RkAiqSceneManager::getSceneIQ(AiqScene scene) {
132   if (access(scene.first.c_str(), F_OK)) {
133     printf("[RkAiqSceneManager]: access %s failed\n", scene.first.c_str());
134     return NULL;
135   }
136 
137   if (access(scene.second.c_str(), F_OK)) {
138     printf("[RkAiqSceneManager]: access %s failed\n", scene.first.c_str());
139     return NULL;
140   }
141 
142   return getSceneIQ(scene.first.c_str(), scene.second.c_str());
143 }
144 
getSceneIQ(const char * scene)145 const char *RkAiqSceneManager::getSceneIQ(const char *scene) {
146   return getSceneIQ(matchScene(scene));
147 }
148 
addScene(CamCalibDbProj_t * calibproj,const char * main_scene,const char * sub_scene,CamCalibDbV2Context_t * calib)149 int RkAiqSceneManager::addScene(CamCalibDbProj_t *calibproj,
150                                 const char *main_scene, const char *sub_scene,
151                                 CamCalibDbV2Context_t *calib) {
152   return 0;
153 }
154 
155 CamCalibDbV2Context_t
refToScene(CamCalibDbProj_t * calibproj,const char * main_scene,const char * sub_scene)156 RkAiqSceneManager::refToScene(CamCalibDbProj_t *calibproj,
157                               const char *main_scene, const char *sub_scene) {
158   CamCalibDbV2Context_t ctx;
159   CamCalibMainSceneList_t *main_list = nullptr;
160   CamCalibSubSceneList_t *sub_list = nullptr;
161   void* dst_calib = nullptr;
162   int main_list_len = -1;
163   int sub_list_len = -1;
164   int curr_main_scene = 0;
165   int curr_sub_scene = 0;
166 
167   if (!calibproj) {
168     printf("No avaliable CamCalibDbProj loadded!\n");
169     return ctx;
170   }
171 
172   main_list = calibproj->main_scene;
173   main_list_len = calibproj->main_scene_len;
174   memset(&ctx, 0, sizeof(CamCalibDbV2Context_t));
175 
176   if (!main_list || main_list_len < 1) {
177     printf("No avaliable main scene for %s!\n", main_scene);
178     return ctx;
179   }
180 
181   // Find main scene
182   for (curr_main_scene = 0; curr_main_scene < main_list_len;
183        curr_main_scene++) {
184     if (0 == strcmp(main_list[curr_main_scene].name, main_scene)) {
185       // Found what we want, and this must be the only one.
186       sub_list = main_list[curr_main_scene].sub_scene;
187       sub_list_len = main_list[curr_main_scene].sub_scene_len;
188       break;
189     }
190   }
191 
192   if (!sub_list || sub_list_len < 1) {
193     printf("No avaliable sub scene!\n");
194     return ctx;
195   }
196 
197   // Find sub scene
198   for (curr_sub_scene = 0; curr_sub_scene < sub_list_len; curr_sub_scene++) {
199     if (0 != strcmp(sub_list[curr_sub_scene].name, sub_scene)) {
200       // Not what we want
201       continue;
202     }
203     dst_calib = calibdbv2_get_scene_ptr(&sub_list[curr_sub_scene]);
204     ctx.calib_scene = (char*)(dst_calib);
205     ctx.sensor_info = &calibproj->sensor_calib;
206     ctx.module_info = &calibproj->module_calib;
207     ctx.sys_cfg = &calibproj->sys_static_cfg;
208 
209     return ctx;
210   }
211 
212   printf("Can't find scene:[%s]/[%s]!\n", main_scene, sub_scene);
213 
214   return ctx;
215 }
216 
findMainScene(cJSON * base_json,const char * name)217 cJSON *RkAiqSceneManager::findMainScene(cJSON *base_json, const char *name) {
218   cJSON *json_item = NULL;
219   cJSON *found_main_json = NULL;
220   cJSON *main_scene_json = NULL;
221 
222   if (!base_json) {
223     XCAM_LOG_ERROR("input base json is invalid!\n");
224     return NULL;
225   }
226 
227   main_scene_json = cJSONUtils_GetPointer(base_json, "/main_scene");
228   if (!main_scene_json) {
229     XCAM_LOG_ERROR("invalid main scene!\n");
230     return NULL;
231   }
232 
233   int main_scene_sum = cJSON_GetArraySize(main_scene_json);
234   if (main_scene_sum <= 0) {
235     XCAM_LOG_ERROR("invalid main scene len!\n");
236     return NULL;
237   }
238 
239   json_item = main_scene_json->child;
240 
241   for (int i = 0; i <= (main_scene_sum - 1); ++i) {
242     if (json_item) {
243       char *name_str = cJSON_GetObjectItem(json_item, "name")->valuestring;
244       if (name_str && strstr(name_str, name)) {
245         found_main_json = json_item;
246         break;
247       }
248           }
249     json_item = json_item->next;
250   }
251 
252   return found_main_json;
253 }
254 
findSubScene(cJSON * main_json,const char * name)255 cJSON *RkAiqSceneManager::findSubScene(cJSON *main_json, const char *name) {
256   cJSON *json_item = NULL;
257   cJSON *found_sub_json = NULL;
258   cJSON *sub_scene_json = NULL;
259 
260   if (!main_json) {
261     XCAM_LOG_ERROR("input main scene json is invalid!\n");
262     return NULL;
263   }
264 
265   sub_scene_json = cJSONUtils_GetPointer(main_json, "/sub_scene");
266   if (!sub_scene_json) {
267     XCAM_LOG_ERROR("invalid sub scene!\n");
268     return NULL;
269   }
270 
271   int sub_scene_sum = cJSON_GetArraySize(sub_scene_json);
272   if (sub_scene_sum <= 0) {
273     XCAM_LOG_ERROR("invalid main scene len!\n");
274     return NULL;
275   }
276 
277   json_item = sub_scene_json->child;
278 
279   for (int i = 0; i < sub_scene_sum; ++i) {
280     if (json_item) {
281       char *name_str = cJSON_GetObjectItem(json_item, "name")->valuestring;
282       if (name_str && strstr(name_str, name)) {
283         found_sub_json = json_item;
284         break;
285       }
286     }
287     json_item = json_item->next;
288   }
289 
290   return found_sub_json;
291 }
292 
findSubScene(cJSON * json,const char * main_scene,const char * sub_scene)293 cJSON *RkAiqSceneManager::findSubScene(cJSON *json, const char *main_scene,
294                                        const char *sub_scene) {
295   return findSubScene(findMainScene(json, main_scene), sub_scene);
296 }
297 
mergeSubMultiScene(cJSON * sub_scene_list,cJSON * full_param,bool skip)298 cJSON *RkAiqSceneManager::mergeSubMultiScene(cJSON *sub_scene_list,
299                                              cJSON* full_param, bool skip) {
300   cJSON *json_item = NULL;
301   cJSON *new_item = NULL;
302   int sub_scene_sum = 0;
303   int i = 0;
304 
305   if (!sub_scene_list || !full_param) {
306     XCAM_LOG_ERROR("input base json is invalid!\n");
307     return NULL;
308   }
309 
310   // need skip first full param scene
311   if (cJSON_GetArraySize(sub_scene_list) <= skip) {
312     XCAM_LOG_ERROR("invalid main scene len!\n");
313     return NULL;
314   }
315 
316   json_item = sub_scene_list->child;
317 
318   sub_scene_sum = cJSON_GetArraySize(sub_scene_list);
319   for (i = 0; i < sub_scene_sum; i++) {
320     if (json_item) {
321       cJSON* temp_item = json_item;
322       json_item = json_item->next;
323       // skip the full param scene
324       if (i == 0 && skip) {
325         continue;
326       }
327       new_item = cJSON_Duplicate(full_param, 1);
328       new_item = cJSONUtils_MergePatch(new_item, temp_item);
329       cJSON_ReplaceItemInArray(sub_scene_list, i, new_item);
330     } else {
331       break;
332     }
333   }
334     return sub_scene_list;
335 }
336 
mergeMainMultiScene(cJSON * main_scene_list)337 cJSON *RkAiqSceneManager::mergeMainMultiScene(cJSON *main_scene_list) {
338   cJSON *json_item = NULL;
339   cJSON *first_sub_scene_list = NULL;
340   cJSON *main_first = NULL;
341   cJSON *full_param = NULL;
342 
343   if (!main_scene_list) {
344     XCAM_LOG_ERROR("input main scene list json is invalid!\n");
345     return NULL;
346   }
347 
348   if (cJSON_GetArraySize(main_scene_list) <= 0) {
349     XCAM_LOG_ERROR("invalid main scene len!\n");
350     return NULL;
351   }
352 
353   main_first = cJSON_GetArrayItem(main_scene_list, 0);
354   first_sub_scene_list = cJSONUtils_GetPointer(main_first, "/sub_scene");
355 
356   if (cJSON_GetArraySize(first_sub_scene_list) <= 0) {
357     XCAM_LOG_ERROR("invalid sub scene len!\n");
358     return NULL;
359   }
360 
361   full_param = cJSON_GetArrayItem(first_sub_scene_list, 0);
362 
363   if (!full_param) {
364     XCAM_LOG_ERROR("invalid full param scene!\n");
365     return NULL;
366   }
367 
368   json_item = main_scene_list->child;
369 
370   int main_scene_sum = cJSON_GetArraySize(main_scene_list);
371   for (int i = 0; i < main_scene_sum; i++) {
372     // need skip first main scene's sub scene
373     cJSON *sub_scene_list = cJSONUtils_GetPointer(json_item, "/sub_scene");
374     if (json_item && sub_scene_list) {
375       mergeSubMultiScene(sub_scene_list, full_param, i == 0);
376     }
377     json_item = json_item->next;
378   }
379 
380   return main_scene_list;
381 }
382 
mergeMultiSceneIQ(cJSON * base_json)383 cJSON *RkAiqSceneManager::mergeMultiSceneIQ(cJSON *base_json) {
384   cJSON *main_scene_list_json = NULL;
385 
386   // 1. foreach every sub scene.
387   // 2. merge every sub scene to base scene.
388   // 3. replace sub scene with new json.
389   if (!base_json) {
390     XCAM_LOG_ERROR("input base json is invalid!\n");
391     return NULL;
392   }
393 
394   main_scene_list_json = cJSONUtils_GetPointer(base_json, "/main_scene");
395   if (!main_scene_list_json) {
396     XCAM_LOG_ERROR("invalid main scene!\n");
397     return NULL;
398   }
399 
400   if (cJSON_GetArraySize(main_scene_list_json) <= 0) {
401     XCAM_LOG_ERROR("invalid main scene len!\n");
402     return NULL;
403   }
404 
405   if (!mergeMainMultiScene(main_scene_list_json)) {
406     return NULL;
407   }
408 
409   return base_json;
410 }
411 
createSceneCalib(CamCalibDbProj_t * calibproj,const char * main_scene,const char * sub_scene)412 CamCalibDbV2Context_t* RkAiqSceneManager::createSceneCalib(
413     CamCalibDbProj_t* calibproj,
414     const char* main_scene,
415     const char* sub_scene) {
416   CamCalibDbV2Context_t *calib = NULL;
417   CamCalibDbV2Context_t* new_calib = NULL;
418   char* json_buff = NULL;
419   cJSON* root_json = NULL;
420   cJSON* base_json = NULL;
421   cJSON* diff_json = NULL;
422   cJSON* scene_json = NULL;
423   cJSON* calib_json = NULL;
424   j2s_ctx ctx;
425   int ret = -1;
426 
427 #if defined(ISP_HW_V20)
428     CamCalibDbV2ContextIsp20_t *calib_scene = new CamCalibDbV2ContextIsp20_t;
429 #elif defined(ISP_HW_V21)
430     CamCalibDbV2ContextIsp21_t *calib_scene = new CamCalibDbV2ContextIsp21_t;
431 #elif defined(ISP_HW_V30)
432     CamCalibDbV2ContextIsp30_t *calib_scene = new CamCalibDbV2ContextIsp30_t;
433 #elif defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
434     CamCalibDbV2ContextIsp32_t *calib_scene = new CamCalibDbV2ContextIsp32_t;
435 #else
436 #error "WRONG ISP_HW_VERSION, ONLY SUPPORT V20 AND V21 AND V30 NOW !"
437 #endif
438 
439   j2s_init(&ctx);
440   json_buff = j2s_dump_root_struct(&ctx, calibproj);
441 
442   if (!json_buff) {
443     XCAM_LOG_ERROR("create CamCalibDbProj json failed.");
444     return NULL;
445   }
446 
447   root_json = cJSON_Parse(json_buff);
448   if (!root_json) {
449     XCAM_LOG_ERROR("create root json failed.");
450     goto error;
451   }
452 
453   base_json = findSubScene(root_json, "normal", "day");
454   diff_json = findSubScene(root_json, main_scene, sub_scene);
455 
456   if (!base_json || !diff_json) {
457     XCAM_LOG_ERROR("find sub scene json failed.");
458     goto error;
459   }
460 
461   scene_json = cJSONUtils_MergePatch(base_json, diff_json);
462   if (!scene_json) {
463     XCAM_LOG_ERROR("merge sub scene json failed.");
464     goto error;
465   }
466 
467 #if defined(ISP_HW_V20)
468     calib_json = cJSONUtils_GetPointer(scene_json, "scene_isp20");
469 #elif defined(ISP_HW_V21)
470     calib_json = cJSONUtils_GetPointer(scene_json, "scene_isp21");
471 #elif defined(ISP_HW_V30)
472     calib_json = cJSONUtils_GetPointer(scene_json, "scene_isp30");
473 #elif defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
474     calib_json = cJSONUtils_GetPointer(scene_json, "scene_isp32");
475 #else
476 #error "WRONG ISP_HW_VERSION, ONLY SUPPORT V20 AND V21 AND V30 NOW !"
477 #endif
478 
479     calib = RkAiqCalibDbV2::CalibV2Alloc();
480     ret = j2s_json_to_struct(&ctx, calib_json,
481                              calibdbv2_get_scene_ctx_struct_name(calib),
482                              calib_scene);
483     if (ret) {
484       XCAM_LOG_ERROR("merge sub scene json failed.");
485       goto error;
486     }
487 
488     calib->module_info = &calibproj->module_calib;
489     calib->module_info_len = 1;
490     calib->sensor_info = &calibproj->sensor_calib;
491     calib->sensor_info_len = 1;
492     calib->sys_cfg = &calibproj->sys_static_cfg;
493     calib->sys_cfg_len = 1;
494     calib->calib_scene = (char*)calib_scene;
495 
496     new_calib = calib;
497 
498 error:
499   if (json_buff) {
500     free(json_buff);
501   }
502 
503   if (root_json) {
504     cJSON_Delete(root_json);
505   }
506 
507   j2s_deinit(&ctx);
508 
509   return new_calib;
510 }
511 
512 } // namespace RkCam
513