blob: e8e3a7e50bd50945475a953dce09450fde03abaf [file] [log] [blame]
/*
* Copyright@ Samsung 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.
*/
/*!
* \file ExynosCameraLogManager.h
* \brief header file for ExynosCameraLogManager
* \author Teahyung, Kim(tkon.kim@samsung.com)
* \date 2018/05/08
*
* <b>Revision History: </b>
* - 2018/05/08 : Teahyung, Kim(tkon.kim@samsung.com) \n
*/
#ifndef EXYNOS_CAMERA_LOG_MANAGER_H
#define EXYNOS_CAMERA_LOG_MANAGER_H
#ifdef USE_DEBUG_PROPERTY
#include <map>
#include <utils/Log.h>
#include <utils/Mutex.h>
#include <utils/Timers.h>
#include <utils/String8.h>
#include <utils/RefBase.h>
#include "ExynosCameraConfig.h"
#include "ExynosCameraCommonDefine.h"
#include "ExynosCameraCommonEnum.h"
using namespace android;
class ExynosCameraProperty;
/**
* ExynosCameraLogManager:
* ExynosCameraLogManager is the class to manage all kind of logs in CameraHAL.
* This Class can't be create by a instance. It should be used by accessing to
* static method. We provide some macro function like CLOG_COMMON, CLOG_PERFRAME,
* CLOG_PERFORMANCE in ExynosCameraCommonDefine.h.
* There are some example like following.
* This class has one instance of ExynosCameraProperty class. You can refer to
* more details in ExynosCameraProperty.class for examples.
*
* ex.
* CLOGD("Test");
* CLOG_PERFRAME(META, m_cameraId, m_name, frame.get(), &shot_ext->shot,
* frame->getRequestKey(), "");
* CLOG_PERFORMANCE(FPS, factory->getCameraId(),
* factory->getFactoryType(), DURATION,
* FRAME_CREATE, 0, request->getKey(), nullptr);
*/
class ExynosCameraLogManager
{
public:
/* Type of Perframe log */
typedef enum {
PERFRAME_TYPE_SIZE,
PERFRAME_TYPE_PATH,
PERFRAME_TYPE_BUF,
PERFRAME_TYPE_META,
PERFRAME_TYPE_MAX,
} PerframeType;
/* Type of Performance log */
typedef enum {
PERFORMANCE_TYPE_FPS,
PERFORMANCE_TYPE_MAX
} PerformanceType;
/* Position Tag of Performance log */
typedef enum {
PERF_FPS_SERVICE_REQUEST,
PERF_FPS_FRAME_CREATE,
PERF_FPS_PATIAL_RESULT,
PERF_FPS_FRAME_COMPLETE,
PERF_FPS_ALL_RESULT,
PERFORMANCE_POS_MAX
} PerformancePos;
/* Type for Meta Perframe control */
typedef enum {
TYPE_INT8,
TYPE_INT16,
TYPE_INT32,
TYPE_INT64,
TYPE_FLOAT,
TYPE_DOUBLE,
TYPE_RATIONAL,
TYPE_STRUCT,
TYPE_MAX,
} MetaFieldType;
/* Meta of S.LSI's Metadata to map with string from get_property() */
class MetaMapper : public RefBase {
public:
explicit MetaMapper(const char *pStr, MetaFieldType pType, long pOffset, uint32_t pArraySize) :
str(pStr), type(pType), offset(pOffset), arraySize(pArraySize) {
}
void removeChild(std::map<std::string, MetaMapper *> &child) {
if (child.size() == 0) return;
std::map<std::string, MetaMapper *>::iterator it;
it = child.begin();
for (; it != child.end(); ++it) {
MetaMapper *remove = it->second;
if (remove != nullptr) {
removeChild(remove->child); //recursive
child.erase(it);
delete remove;
}
}
}
~MetaMapper() {
removeChild(child);
}
public:
const char *str;
MetaFieldType type;
long offset;
uint32_t arraySize;
std::map<std::string, MetaMapper *> child;
};
/* The way to measure performance */
typedef enum {
TM_INTERVAL,
TM_DURATION,
/**
* TBD
* CUMUL_CNT : to count error or specific events
* USER_DATA : some specific record
*/
TM_CUMUL_CNT,
TM_USER_DATA,
TM_MAX,
} TimeCalcType;
/* basic timeunit for performance */
typedef struct {
int32_t count;
nsecs_t min;
nsecs_t max;
nsecs_t sum;
nsecs_t lastTimestamp;
} TimeUnitInfo;
/* specific timesubunit for performance like all pipe's performance */
class TimeSubInfo : public RefBase {
public:
std::map<int32_t, TimeUnitInfo> duration;
std::map<int32_t, TimeUnitInfo> interval;
};
typedef sp<TimeSubInfo> TimeSubInfo_sp_t;
/* summary for time performance */
class TimeInfo {
public:
TimeInfo() {
index = 0;
count = 0;
errCnt = 0;
memset(&time, 0x0, sizeof(TimeUnitInfo));
sub = new TimeSubInfo;
}
public:
uint32_t index;
uint32_t count;
uint32_t errCnt;
TimeUnitInfo time;
/* sub infomation eg.each entry(pipe)'s info <subkey, TimeUnit> */
TimeSubInfo_sp_t sub;
};
/* init */
static void init();
/**
* Print basic log.
* But by searching m_property and matching the values,
* some log can't be printed or this process can be panic by
* enabling trap feature.
* @prio : android log level
* @tag : LOG_TAG for android log print
* @prefix : prefix string literal(for cameraId, instance name)
* @cameraId : camera device id (ex. back : 0, front : 1)
* @name : instance name to call
* @func : function name to call
* @line : linenumber to call
* @fmt : string literal for print
* eg.
* logCommon(ANDROID_LOG_VERBOSE, LOG_TAG, "cam(%s), name(%s)",
* m_cameraId, m_name, __FUNCTION__, __LINE__,
* "Test log(%d)", i);
*
* <Property>
* 1. For verborse level log print
* # setprop log.tag."tag" V
* # setprop persist.log.tag."tag" V //still keep it's value maintain after reboot
*
* 2. Enable Trap for debuging
* # setprop sys.camera.debug.trap.enable true
* # setprop sys.camera.debug.trap.words "fatal error|device error"
* //User can assign multiple string to property by delimeter "|"
* # setprop sys.camera.debug.trap.event "panic"
* //panic : kernel panic
* //assert : process kill
* # setprop sys.camera.debug.trap.count 5
* //after decreasing this number to 0, trap would be triggered
*
* 3. Change the assert action
* # setprop sys.camera.assert "errlog"
* //errlog : just print log by error level
* //assert : process kill(same as normal)
* //panic : kernel panic
*/
static void logCommon(android_LogPriority prio,
const char* tag,
const char* prefix,
int cameraId,
const char* name,
const char* func,
int line,
const char* fmt,
...);
/**
* Print perframe log.
* Now that this class support perframe log about path, buf, meta or
* size. Most of time, it's better that caller gives the frame to this
* function, because this function print the frame's information by default.
* @prio : android log level
* @tag : LOG_TAG for android log print
* @prefix : prefix string literal(for cameraId, instance name)
* @cameraId : camera device id (ex. back : 0, front : 1)
* @name : instance name to call
* @func : function name to call
* @line : linenumber to call
* @fmt : string literal for print
* @type : type of perframe log (size, buf, path, meta)
* @frame : ExynosCameraFrame pointer
* @data : specific object for perframe log type
* - size : nullptr
* - buf : camera3_stream_buffer pointer
* - meta : camera2_shot buffer pointer
* - path : nullptr
*
* eg.
* CLOG_PERFRAME(META, m_cameraId, m_name, frame.get(), &shot_ext->shot,
* frame->getRequestKey(), "");
* CLOG_PERFRAME(BUF, m_cameraId, m_name, nullptr, (void *)(pStreamBuf),
* request->frame_number, "[INPUT]");
* CLOG_PERFRAME(SIZE, frame->getCameraId(), "", frame, nullptr, frame->getRequestKey(),
* "%s", str.c_str());
* CLOG_PERFRAME(PATH, m_cameraId, m_name, newFrame.get(), nullptr, newFrame->getRequestKey(), "");
*
* <Property>
* 1. Path
* # setprop sys.camera.log.perframe.enable true
* # setprop sys.camera.log.perframe.path.enable true
*
* 2. Size
* # setprop sys.camera.log.perframe.enable true
* # setprop sys.camera.log.perframe.size.enable true
*
* 3. Buf
* # setprop sys.camera.log.perframe.enable true
* # setprop sys.camera.log.perframe.buf.enable true
* # setprop sys.camera.log.perframe.buf.filter "MCSC_OUT_BUF|DEPTH_MAP_BUF"
*
* 4. Meta
* * Only the field that user set in "filter" property can be only printed.
* # setprop sys.camera.log.perframe.enable true
* # setprop sys.camera.log.perframe.meta.enable true
* # setprop sys.camera.log.perframe.meta.filter "ctl.aa.afMode|ctl.aa.aeTargetFpsRange|ctl.aa.vendor_isoMode"
* //print ctl.aa.afMode, ctl.aa.aeTargetFpsRange and ctl.aa.vendor_isoMode
* # setprop sys.camera.log.perframe.meta.values "1|15,30|100"
* //forcely value setting by fields on filter
* ctl.aa.afMode = 1
* ctl.aa.aeTargetFpsRange[0] = 15
* ctl.aa.aeTargetFpsRange[1] = 30
* ctl.aa.vendor_isoMode = 100
*
* 5. Filtering
* # setprop sys.camera.log.perframe.filter.cameraId "0|1"
* //print the log if cameraId is 0 or 1
* # setprop sys.camera.log.perframe.filter.factory "reproc|jpeg_reproc"
* //"reproc" : FRAME_FACTORY_TYPE_REPROCESSING
* //"jpeg_reproc" : FRAME_FACTORY_TYPE_JPEG_REPROCESSING
* //"cap_prev" : FRAME_FACTORY_TYPE_CAPTURE_PREVIEW
* //"prev_dual" : FRAME_FACTORY_TYPE_PREVIEW_DUAL
* //"reproc_dual" : FRAME_FACTORY_TYPE_REPROCESSING_DUAL
* //"vision" : FRAME_FACTORY_TYPE_VISION
*/
static void logPerframe(android_LogPriority prio,
const char* tag,
const char* prefix,
int cameraId,
const char* name,
const char* func,
int line,
const char* fmt,
PerframeType type,
void *frame,
void *data,
uint32_t requestKey,
...);
/**
* Print performance log.
* print performance log like fps by summarizing of N frames.
* @prio : android log level
* @tag : LOG_TAG for android log print
* @prefix : prefix string literal(for cameraId, instance name)
* @cameraId : camera device id (ex. back : 0, front : 1)
* @factoryType : factory instance to call
* @pType : type of performance log
* @pos : position tag
* @posSubKey : sub key like pipeId
* @key : unique key like request key
* @data : some specific object like ExynosCameraFrame pointer
*
* eg.
* CLOG_PERFORMANCE(FPS, getCameraId(),
* getFactoryType(), DURATION,
* FRAME_COMPLETE, 0, getRequestKey(), this);
*
* <Property>
* 1. Fps
* # setprop sys.camera.log.performance.enable true
* # setprop sys.camera.log.performance.fps.enable true
* # setprop sys.camera.log.performance.frames 120
* // summary based on this N frames (in this ex, 120 frames)
*/
static void logPerformance(android_LogPriority prio,
const char* tag,
const char* prefix,
int cameraId,
int factoryType,
PerformanceType pType,
TimeCalcType tType,
int pos,
__unused int posSubKey, /* eg.pipeId */
int key, /* eg.requestKey */
void *data /* eg.ExynosCameraFrame */
...);
protected:
static void m_panic(void);
static void m_printLog(android_LogPriority prio, const char *tag, String8& logStr);
static void m_logDebug(android_LogPriority &prio, const char *tag, String8& logStr);
/**
* Performance sub function
*/
static void m_logPerformanceFps(android_LogPriority prio,
const char* tag,
const char* prefix,
int cameraId,
int factoryType,
PerformanceType pType,
TimeCalcType tType,
int pos,
int requestKey,
void *frame);
static void m_initMetaMapper(void);
private:
ExynosCameraLogManager(); /* can't create an instance */
static ExynosCameraProperty m_property;
/**
* For performance Lock
*/
static Mutex m_perfLock[PERFORMANCE_TYPE_MAX];
/**
* Timestamp key value(64bit)
* Refer to function "m_makeTimestampkey" to make key
*/
static std::map<int64_t, nsecs_t> m_perfTimestamp[PERFORMANCE_TYPE_MAX][PERFORMANCE_POS_MAX];
/**
* Summary key value(32bit)
* For Summary of statistics
* Refer to function "m_makeSummaryKey" to make key
*/
static std::map<int32_t, TimeInfo> m_perfSummary[PERFORMANCE_TYPE_MAX];
/* Mata Mapper */
static MetaMapper kLv1MetaMap;
};
#endif //USE_DEBUG_PROPERTY
#endif //EXYNOS_CAMERA_LOG_MANAGER_H