/*
* xcam_log.cpp - xcam log
*
* Copyright (c) 2014-2015 Intel Corporation
* Copyright (c) 2019, Fuzhou Rockchip Electronics Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef ANDROID_OS
#include
#ifdef ALOGV
#undef ALOGV
#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#endif
#endif
static char log_file_name[XCAM_MAX_STR_SIZE] = {0};
/* use a 64 bits value to represent all modules bug level, and the
* module bit maps is as follow:
*
* bit: 11-4 3-0
* meaning: [sub modules] [level]
*
* bit: 21 20 19 18 17 16 15 14 13 12
* meaning: [ADEBAYER][AGIC] [ALSC] [ANR] [ATMO] [ADPCC] [ABLC] [AF] [AWB] [AEC]
*
* bit: 31 30 29 28 27 26 25 24 23 22
* meaning: [ASHARP] [AIE] [ACP] [AR2Y] [ALDCH][A3DLUT] [ADEHAZE] [AWDR] [AGAMMA][ACCM]
*
* bit: [63-39] 40 39 38 37 36 35 34 33 32
* meaning: [U] [AMERGE] [ADEGAMMA ] [CAMHW] [ANALYZER][XCORE][ASD] [AFEC] [ACGC] [AORB]
*
* [U] means unused now.
* [level]: use 4 bits to define log levels.
* each module log has following ascending levels:
* 0: error
* 1: warning
* 2: info
* 3: debug
* 4: verbose
* 5: low1
* 6-7: unused, now the same as debug
* [sub modules]: use bits 4-11 to define the sub modules of each module, the
* specific meaning of each bit is decided by the module itself. These bits
* is designed to implement the sub module's log switch.
* [modules]: AEC, AWB, AF ...
*
* set debug level example:
* eg. set module af log level to debug, and enable all sub modules of af:
* Android:
* setprop persist.vendor.rkisp.log 0x4ff4
* Linux:
* export persist_camera_engine_log=0x4ff4
* And if only want enable the sub module 1 log of af:
* Android:
* setprop persist.vendor.rkisp.log 0x4014
* Linux:
* export persist_camera_engine_log=0x4014
*/
static unsigned long long g_cam_engine_log_level = 0xff0;
#if 0
typedef struct xcore_cam_log_module_info_s {
const char* module_name;
int log_level;
int sub_modules;
} xcore_cam_log_module_info_t;
#endif
xcore_cam_log_module_info_t g_xcore_log_infos[XCORE_LOG_MODULE_MAX] = {
{ "AEC", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AEC
{ "AWB", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AWB
{ "AF", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AF
{ "ABLC", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ABLC
{ "ADPCC", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ADPCC
{ "ATMO", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ATMO
{ "ANR", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ANR
{ "ALSC", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ALSC
{ "AGIC", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AGIC
{ "ADEBAYER", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ADEBAYER
{ "ACCM", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ACCM
{ "AGAMMA", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AGAMMA
{ "AWDR", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AWDR
{ "ADEHAZE", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ADEHAZE
{ "A3DLUT", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_A3DLUT
{ "ALDCH", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ALDCH
{ "AR2Y", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AR2Y
{ "ACP", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ACP
{ "AIE", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AIE
{ "ASHARP", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ASHARP
{ "AORB", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AORB
{ "AFEC", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AFEC
{ "ACGC", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ACGC
{ "ASD", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ASD
{ "XCORE", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_XCORE
{ "ANALYZER", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ANALYZER
{ "CAMHW", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_CAMHW
{ "ADEGAMMA", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_ADEGAMMA
{ "AMERGE", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AMERGE
{ "AMD", XCORE_LOG_LEVEL_ERR, 0xff}, // XCORE_LOG_MODULE_AMMD
};
bool xcam_get_enviroment_value(const char* variable, unsigned long long* value)
{
if (!variable || !value) {
return false;
}
char* valueStr = getenv(variable);
if (valueStr) {
*value = strtoull(valueStr, nullptr, 16);
return true;
}
return false;
}
void xcam_get_runtime_log_level() {
const char* file_name = "/tmp/.rkaiq_log";
if (!access(file_name, F_OK)) {
FILE *fp = fopen(file_name, "r");
char level[64] = {'\0'};
if (!fp)
return;
fseek(fp, 0, SEEK_SET);
if (fp && fread(level, 1, sizeof (level), fp) > 0) {
for (int i = 0; i < XCORE_LOG_MODULE_MAX; i++) {
g_xcore_log_infos[i].log_level = 0;
g_xcore_log_infos[i].sub_modules = 0;
}
g_cam_engine_log_level = strtoull(level, nullptr, 16);
unsigned long long module_mask = g_cam_engine_log_level >> 12;
for (int i = 0; i < XCORE_LOG_MODULE_MAX; i++) {
if (module_mask & (1 << i)) {
g_xcore_log_infos[i].log_level = g_cam_engine_log_level & 0xf;
g_xcore_log_infos[i].sub_modules = (g_cam_engine_log_level >> 4) & 0xff;
}
}
}
fclose (fp);
}
}
int xcam_get_log_level() {
#ifdef ANDROID_OS
char property_value[PROPERTY_VALUE_MAX] = {0};
property_get("persist.vendor.rkisp.log", property_value, "0");
g_cam_engine_log_level = strtoull(property_value, nullptr, 16);
#else
xcam_get_enviroment_value("persist_camera_engine_log",
&g_cam_engine_log_level);
#endif
unsigned long long module_mask = g_cam_engine_log_level >> 12;
for (int i = 0; i < XCORE_LOG_MODULE_MAX; i++) {
if (module_mask & (1 << i)) {
g_xcore_log_infos[i].log_level = g_cam_engine_log_level & 0xf;
g_xcore_log_infos[i].sub_modules = (g_cam_engine_log_level >> 4) & 0xff;
}
}
return 0;
}
char* timeString() {
struct timeval tv;
gettimeofday(&tv, NULL);
struct tm * timeinfo = localtime(&tv.tv_sec);
static char timeStr[64];
sprintf(timeStr, "%.2d:%.2d:%.2d.%.6ld", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, tv.tv_usec);
return timeStr;
}
void xcam_print_log (int module, int sub_modules, int level, const char* format, ...) {
char buffer[XCAM_MAX_STR_SIZE] = {0};
va_list va_list;
va_start (va_list, format);
vsnprintf (buffer, XCAM_MAX_STR_SIZE, format, va_list);
va_end (va_list);
if (strlen (log_file_name) > 0) {
FILE* p_file = fopen (log_file_name, "ab+");
if (NULL != p_file) {
fwrite (buffer, sizeof (buffer[0]), strlen (buffer), p_file);
fclose (p_file);
} else {
printf("error! can't open log file !\n");
}
return ;
}
#ifdef ANDROID_OS
switch(level) {
case XCORE_LOG_LEVEL_ERR:
ALOGE("[%s]:%s", g_xcore_log_infos[module].module_name, buffer);
break;
case XCORE_LOG_LEVEL_WARNING:
ALOGW("[%s]:%s", g_xcore_log_infos[module].module_name, buffer);
break;
case XCORE_LOG_LEVEL_INFO:
ALOGI("[%s]:%s", g_xcore_log_infos[module].module_name, buffer);
break;
case XCORE_LOG_LEVEL_VERBOSE:
ALOGV("[%s]:%s", g_xcore_log_infos[module].module_name, buffer);
break;
case XCORE_LOG_LEVEL_DEBUG:
default:
ALOGD("[%s]:%s", g_xcore_log_infos[module].module_name, buffer);
break;
}
#else
printf ("[%s][%s]:%s", timeString(), g_xcore_log_infos[module].module_name, buffer);
#endif
}
void xcam_set_log (const char* file_name) {
if (NULL != file_name) {
memset (log_file_name, 0, XCAM_MAX_STR_SIZE);
strncpy (log_file_name, file_name, XCAM_MAX_STR_SIZE);
}
}
void xcam_get_awb_log_level(unsigned char *log_level, unsigned char *sub_modules)
{
//xcam_get_log_level();
*log_level = g_xcore_log_infos[XCORE_LOG_MODULE_AWB].log_level;
*sub_modules = g_xcore_log_infos[XCORE_LOG_MODULE_AWB].sub_modules;
}