一、写在前面
上网🏄经常看到一些好文章,除了收藏之外,顺手一会照着搞一搞。这次看到 qiuxintai 写的
有点东西,写的很详细,
适合来一遍,文章是基于MTK 9.0 的,大差不差。我就基于最新的 11 搞了。
二、准备工作
qiuxintai 文章中并没有提供 libwatermark.so watermark.rgba
libmultiframe.so 这几个关键的东西,所以我们要先把这几个东西集齐才能召唤神龙。
经过一顿翻看,好在 qiuxintai 还是留了点线索,去他 github 中提取这几个关键的东西。
虽然你找到了这些原材料,好戏才刚刚开始,你需要将原材料提取成可放到 aosp 中编译的格式且不报错还是
有一点麻烦的。这期间停滞了好几天,也算是补充了不少 so 编译相关的知识。 那么开始干吧!
三、提取精华
新建 AS 工程,就叫 jnidemo 吧,从 YUV420Converter 中提取 cpp 文件夹下所有文件到 jnidemo 中
从 qiuxintai 多帧文章中提取 mf_processor_impl.cpp
从 Watermark 中提取 watermark.cpp 并进行改造
整合后的 jnidemo 链接
这里说一下 CMakeLists.txt 含义
cmake_minimum_required(VERSION 3.4.1)
#引入头文件依赖编译
include_directories(${CMAKE_SOURCE_DIR}/include)
find_library(log-lib log)
#编译 libNativeUtils.so
add_library(
NativeUtils
SHARED
native.cpp
native_utils.cpp
)
target_link_libraries(NativeUtils ${log-lib})
#引入第三方libopencv_java3.so 编译 opencv3
add_library(opencv3 SHARED IMPORTED)
set_target_properties(
opencv3
PROPERTIES
IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libopencv_java3.so
)
#编译 libOpencvUtils.so 并链接刚刚 opencv3
add_library(
OpencvUtils
SHARED
opencv.cpp
opencv_utils.cpp
)
target_link_libraries(OpencvUtils opencv3 ${log-lib})
#引入第三方libyuv.so 编译 libyuv
add_library(libyuv SHARED IMPORTED)
set_target_properties(
libyuv
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libyuv.so
)
#编译 libLibyuvUtils.so 并链接刚刚 libyuv
add_library(
LibyuvUtils
SHARED
libyuv.cpp
libyuv_utils.cpp
)
target_link_libraries(LibyuvUtils libyuv ${log-lib})
#编译 libmultiframe.so 并链接刚刚 libyuv
add_library(
multiframe
SHARED
mf_processor_impl.cpp
)
target_link_libraries(multiframe libyuv ${log-lib})
#编译 libwatermark.so
add_library(
watermark
SHARED
watermark.cpp
)
target_link_libraries(watermark ${log-lib})
build.gradle 中配置使用 cmake 编译 so,并制定 so 对应平台
defaultConfig {
....
/*externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}*/
externalNativeBuild {
cmake {
cppFlags ""
}
}
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
ubuntu16.04 安装交叉编译工具aarch64-linux-gnu-gcc/g++
项目 build 成功后, so 位于 \jnidemo\build\intermediates\cmake\release\obj\arm64-v8a
问题一
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: error: DT_NEEDED "libstdc++.so" is not specified in shared_libs.
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note:
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note: Fix suggestions:
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note: Android.bp: shared_libs: ["libc", "libdl", "libm", "libstdc++"],
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note: Android.mk: LOCAL_SHARED_LIBRARIES := libc libdl libm libstdc++
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note:
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note: If the fix above doesn't work, bypass this check with:
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note: Android.bp: check_elf_files: false,
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/lib/arm64-v8a/libwatermark.so: note: Android.mk: LOCAL_CHECK_ELF_FILES := false
[ 5% 661/11941] target Strip: vendor.mediatek.hardware.camera.bgservice@1.1-impl
libwatermark.so 有问题,最开始用的 ndk 编译 so 文件,扔到源码里就出现上面奇怪的错误,一开始并没有想到用
cmake 编译,而是去 Ubuntu 下使用 ndk 再次编译,结果还是一样的。
四、注入灵魂(水印算法+多帧算法)
接下来就是跟着 qiuxintai 步骤来
4.1 添加自定义feature
添加新feature,我们选择添加一个自定义feature:TP_FEATURE_WATERMARK
vendor/mediatek/proprietary/hardware/mtkcam3/include/mtkcam3/3rdparty/customer/customer_feature_type.h
@@ -61,6 +61,7 @@ enum eFeatureIndexCustomer {
TP_FEATURE_RELIGHTING = 1ULL << 45,
TP_FEATURE_ASYNC_ASD = 1ULL << 46,
TP_FEATURE_ZOOM_FUSION = 1ULL << 47, // used by zoom scenario
+ TP_FEATURE_WATERMARK = 1ULL << 48, //cczheng
// TODO: reserve for customer feature index (bit 32-63)
};
vendor/mediatek/proprietary/hardware/mtkcam3/feature/core/featurePipe/capture/CaptureFeature_Common.cpp
@@ -592,6 +592,7 @@ const char* FeatID2Name(FeatureID_T fid)
case FID_RELIGHTING_3RD_PARTY: return "relighting_3rd_party";
case FID_AINR_YHDR: return "ainr_yhdr";
case FID_AIHDR: return "aihdr";
+ case FID_WATERMARK_3RD_PARTY: return "watermark_3rd_party";//cczheng
default: return "unknown";
};
vendor/mediatek/proprietary/hardware/mtkcam3/feature/core/featurePipe/capture/nodes/YUVNode.cpp
@@ -619,6 +619,9 @@ MBOOL YUVNode::onInit()
featId = FID_RELIGHTING_3RD_PARTY;
else if(rProperty.mFeatures & MTK_FEATURE_YHDR_FOR_AINR)
featId = FID_AINR_YHDR;
+ else if (rProperty.mFeatures & TP_FEATURE_WATERMARK)
+ featId = FID_WATERMARK_3RD_PARTY;//cczheng
+
if (featId != NULL_FEATURE) {
MY_LOGD_IF(mLogLevel, "%s finds plugin:%s, priority:%d",
vendor/mediatek/proprietary/hardware/mtkcam3/include/mtkcam3/feature/featurePipe/ICaptureFeaturePipe.h
@@ -191,6 +191,7 @@ enum CaptureFeatureFeatureID {
FID_RELIGHTING_3RD_PARTY,
FID_AINR_YHDR,
FID_AIHDR,
+ FID_WATERMARK_3RD_PARTY,
NUM_OF_FEATURE,
NULL_FEATURE = 0xFF,
};
vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/hwnode/p2/P2_CaptureProcessor.cpp
@@ -487,6 +487,8 @@ MBOOL CaptureProcessor::onEnque(const sp<P2FrameRequest> &pP2FrameRequest)
pCapRequest->addFeature(FID_HFG);
if (feature & MTK_FEATURE_DCE)
pCapRequest->addFeature(FID_DCE);
+ if (feature & TP_FEATURE_WATERMARK)
+ pCapRequest->addFeature(FID_WATERMARK_3RD_PARTY);//cczheng
if (feature & MTK_FEATURE_AINR_YUV)
pCapRequest->addFeature(FID_AINR_YUV);
if (feature & MTK_FEATURE_AINR_YHDR)
4.2 将算法对应的feature添加到scenario配置表
在我们打开camera进行预览和拍照的时候,MTK HAL3会执行vendor/mediatek/proprietary/hardware/mtkcam3/pipeline/policy/FeatureSettingPolicy.cpp的代码,会分别调用 vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/scenario_mgr.cpp的 get_streaming_scenario函数和get_capture_scenario函数。它们会读取一个scenario的feature配置表,遍历所有的feature,决定哪些feature会被执行。这个配置表中有许多的scenario,一个scenario可能对应多个feature。因此添加自定义feature后,还需将自定义的feature添加到配置表中。MTK feature 对应的配置表是 gMtkScenarioFeaturesMaps,customer feature 对应的配置表是 gCustomerScenarioFeaturesMaps。
vendor/mediatek/proprietary/custom/mt6765/hal/camera/camera_custom_feature_table.cpp
#include "camera_custom_feature_table.h"
using namespace NSCam::NSPipelinePlugin;
// ======================================================================================================
// For Camera HAL Server
// ======================================================================================================
// TODO: Feature Combinations for MTK Camera HAL server
// #define <feature combination> (key feature | post-processing features | ...)
//
// logical stream
// single cam capture feature combination
#define MTK_FEATURE_COMBINATION_SINGLE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_HDR (TP_FEATURE_HDR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_AINR (MTK_FEATURE_AINR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_AIHDR (MTK_FEATURE_AIHDR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_REMOSAIC_MFNR (MTK_FEATURE_REMOSAIC_MFNR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_REMOSAIC (MTK_FEATURE_REMOSAIC| MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_CSHOT (NO_FEATURE_NORMAL | MTK_FEATURE_CZ| MTK_FEATURE_HFG)
#define MTK_FEATURE_COMBINATION_MULTICAM (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_YUV_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_RAW_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_SUPER_NIGHT_RAW_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB| TP_FEATURE_WATERMARK)
// request source frame from camerahalserver.
// no feature pure image quality for processing, the full image processing will be process in isp hidl.
#define MTK_FEATURE_COMBINATION_ISP_HIDL_SOURCE_COMMON (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE)
#define MTK_FEATURE_COMBINATION_ISP_HIDL_SOURCE_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE)
#define MTK_FEATURE_COMBINATION_ISP_HIDL_SOURCE_AINR (MTK_FEATURE_AINR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE)
// dual cam capture feature combination
// the VSDOF means the combination of Bokeh feature and Depth feature
#define MTK_FEATURE_COMBINATION_MTK_VSDOF (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| MTK_FEATURE_VSDOF| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_MTK_VSDOF_HDR (TP_FEATURE_HDR_DC | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| MTK_FEATURE_VSDOF| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_MTK_VSDOF_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| MTK_FEATURE_VSDOF| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_MTK_VSDOF_AINR (MTK_FEATURE_AINR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| MTK_FEATURE_AINR_YUV| MTK_FEATURE_VSDOF)
// zoom fusion combination, need TP_FEATURE_ZOOM_FUSION when sensor nums >= 2 && has tp fusion plugin
#define MTK_FEATURE_COMBINATION_MTK_ZOOM (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_ZOOM_FUSION)
#define MTK_FEATURE_COMBINATION_MTK_ZOOM_HDR (TP_FEATURE_HDR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_ZOOM_FUSION)
#define MTK_FEATURE_COMBINATION_MTK_ZOOM_AINR (MTK_FEATURE_AINR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_ZOOM_FUSION)
#define MTK_FEATURE_COMBINATION_MTK_ZOOM_AIHDR (MTK_FEATURE_AIHDR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_ZOOM_FUSION)
#define MTK_FEATURE_COMBINATION_MTK_ZOOM_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_ZOOM_FUSION)
#define MTK_FEATURE_COMBINATION_MTK_ZOOM_REMOSAIC (MTK_FEATURE_REMOSAIC| MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_ZOOM_FUSION)
// physical stream
// single cam capture feature combination
#define MTK_FEATURE_COMBINATION_MASTER (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_SLAVE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_REMOSAIC_MASTER (MTK_FEATURE_REMOSAIC| MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_REMOSAIC_SLAVE (MTK_FEATURE_REMOSAIC| MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_MULTICAM_MASTER (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_MULTICAM_SLAVE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
//
#define MTK_FEATURE_COMBINATION_VSDOF_MASTER (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_VSDOF_SLAVE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_ZOOM_MASTER (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_ZOOM_SLAVE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_TP_MFNR (TP_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| MTK_FEATURE_MFNR)
// request source frame from camerahalserver.
// no feature pure image quality for processing, the full image processing will be process in isp hidl.
#define MTK_FEATURE_COMBINATION_YUV_REPROCESS_MASTER (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_RAW_REPROCESS_MASTER (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_YUV_REPROCESS_SLAVE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_FB)
#define MTK_FEATURE_COMBINATION_RAW_REPROCESS_SLAVE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB)
// streaming feature combination (TODO: it should be refined by streaming scenario feature)
#define MTK_FEATURE_COMBINATION_VIDEO_NORMAL (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|MTK_FEATURE_FOVA|TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_VIDEO_NORMAL_VIDEO (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|MTK_FEATURE_FOVA)
#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_YUV (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|MTK_FEATURE_DUAL_YUV|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|TP_FEATURE_DUAL_YUV|TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWDEPTH (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|MTK_FEATURE_DUAL_HWDEPTH|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|TP_FEATURE_DUAL_HWDEPTH|TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWVSDOF (MTK_FEATURE_FB|TP_FEATURE_FB|TP_FEATURE_WATERMARK)
// ======================================================================================================
//
// add scenario/feature set for logical camera scenario
const std::vector<std::unordered_map<int32_t, ScenarioFeatures>> gCustomerScenarioFeaturesMaps =
{
{
// capture
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_NORMAL)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AIHDR, MTK_FEATURE_COMBINATION_AIHDR)
ADD_CAMERA_FEATURE_SET(TP_FEATURE_HDR, MTK_FEATURE_COMBINATION_HDR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_AINR)
//ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC_MFNR, MTK_FEATURE_COMBINATION_REMOSAIC_MFNR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MFNR)
ADD_CAMERA_FEATURE_SET(TP_FEATURE_MFNR, MTK_FEATURE_COMBINATION_TP_MFNR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_VSDOF)
ADD_CAMERA_FEATURE_SET(TP_FEATURE_HDR_DC, MTK_FEATURE_COMBINATION_MTK_VSDOF_HDR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MTK_VSDOF_MFNR)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_MTK_VSDOF)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_MULTICAM)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AIHDR, MTK_FEATURE_COMBINATION_AIHDR)
ADD_CAMERA_FEATURE_SET(TP_FEATURE_HDR, MTK_FEATURE_COMBINATION_HDR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_AINR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MFNR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_MULTICAM)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_ZOOM)
ADD_CAMERA_FEATURE_SET(TP_FEATURE_HDR, MTK_FEATURE_COMBINATION_MTK_ZOOM_HDR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_MTK_ZOOM_AINR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MTK_ZOOM_MFNR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_MTK_ZOOM_REMOSAIC)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_MTK_ZOOM)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_CSHOT)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_CSHOT)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_DNG_OPAQUE_RAW)
/* not support multiframe features with dng capture yet */
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_YUV_REPROCESS)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_YUV_REPROCESS)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_RAW_REPROCESS)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_RAW_REPROCESS)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(CUSTOMER_CAMERA_SCENARIO_CAPTURE_SUPER_NIGHT)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_AINR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MFNR)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(CUSTOMER_CAMERA_SCENARIO_CAPTURE_SUPER_NIGHT_RAW_REPROCESS)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SUPER_NIGHT_RAW_REPROCESS)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_REQUEST_FRAME_FOR_ISP_HIDL_YUV)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_ISP_HIDL_SOURCE_COMMON)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_REQUEST_FRAME_FOR_ISP_HIDL_RAW)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_ISP_HIDL_SOURCE_AINR)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_ISP_HIDL_SOURCE_MFNR)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_ISP_HIDL_SOURCE_COMMON)
CAMERA_SCENARIO_END
//
// streaming
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_NORMAL)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_NORMAL)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_NORMAL_VIDEO)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_NORMAL_VIDEO)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_YUV)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_YUV)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_HWDEPTH)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWDEPTH)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_HWVSDOF)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWVSDOF)
CAMERA_SCENARIO_END
},
};
// add scenario/feature set for master physical camera scenario
const std::vector<std::unordered_map<int32_t, ScenarioFeatures>> gCustomerScenarioFeaturesMapsPhyMaster =
{
{
// capture physical master
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_NORMAL)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_MASTER)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_MASTER)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_VSDOF)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_MASTER)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VSDOF_MASTER)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_MULTICAM)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_MASTER)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_MULTICAM_MASTER)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_ZOOM)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_MASTER)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_ZOOM_MASTER)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_YUV_REPROCESS)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_YUV_REPROCESS_MASTER)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_RAW_REPROCESS)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_RAW_REPROCESS_MASTER)
CAMERA_SCENARIO_END
//
// streaming
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_NORMAL)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_NORMAL)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_NORMAL_VIDEO)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_NORMAL_VIDEO)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_YUV)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_YUV)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_HWDEPTH)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWDEPTH)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_HWVSDOF)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWVSDOF)
CAMERA_SCENARIO_END
},
};
// add scenario/feature set for slave physical camera scenario
const std::vector<std::unordered_map<int32_t, ScenarioFeatures>> gCustomerScenarioFeaturesMapsPhySlave =
{
{
// capture physical slave
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_NORMAL)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_SLAVE)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SLAVE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_VSDOF)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_SLAVE)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VSDOF_SLAVE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_MULTICAM)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_SLAVE)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_MULTICAM_SLAVE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_ZOOM)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_REMOSAIC, MTK_FEATURE_COMBINATION_REMOSAIC_SLAVE)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_ZOOM_SLAVE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_YUV_REPROCESS)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_YUV_REPROCESS_SLAVE)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_CAPTURE_RAW_REPROCESS)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_RAW_REPROCESS_SLAVE)
CAMERA_SCENARIO_END
//
// streaming
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_NORMAL)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_NORMAL)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_NORMAL_VIDEO)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_NORMAL_VIDEO)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_YUV)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_YUV)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_HWDEPTH)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWDEPTH)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_CAMERA_SCENARIO_STREAMING_DUAL_HWVSDOF)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWVSDOF)
CAMERA_SCENARIO_END
},
};
// ======================================================================================================
// For ISP HIDL only
// ======================================================================================================
// TODO: Feature Combinations for MTK ISP Device HIDL
// #define <feature combination> (key feature | post-processing features | ...)
//
// isp hidl feature combination
#define MTK_FEATURE_COMBINATION_SINGLE_FULL (NO_FEATURE_NORMAL | MTK_FEATURE_DCE| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
#define MTK_FEATURE_COMBINATION_AINR_FULL (MTK_FEATURE_AINR | MTK_FEATURE_DCE| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
#define MTK_FEATURE_COMBINATION_MFNR_FULL (MTK_FEATURE_MFNR | MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
// single frame in
#define MTK_FEATURE_COMBINATION_SINGLE_RAW_TO_YUV (NO_FEATURE_NORMAL | MTK_FEATURE_DCE| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
#define MTK_FEATURE_COMBINATION_SINGLE_RAW_TO_JPEG (NO_FEATURE_NORMAL | MTK_FEATURE_DCE| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
#define MTK_FEATURE_COMBINATION_SINGLE_YUV_TO_YUV (NO_FEATURE_NORMAL) // image transform and crop/resize only
#define MTK_FEATURE_COMBINATION_SINGLE_YUV_TO_JPEG (NO_FEATURE_NORMAL) // encode yuv to jpeg only.
// multiple frame in
#define MTK_FEATURE_COMBINATION_AINR_RAW_TO_RAW (MTK_FEATURE_AINR) // output AINR RAW only
#define MTK_FEATURE_COMBINATION_AINR_RAW_TO_YUV (MTK_FEATURE_AINR | MTK_FEATURE_DCE| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
#define MTK_FEATURE_COMBINATION_AINR_RAW_TO_JPEG (MTK_FEATURE_AINR | MTK_FEATURE_DCE| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
#define MTK_FEATURE_COMBINATION_MFNR_RAW_TO_YUV (MTK_FEATURE_MFNR | MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
#define MTK_FEATURE_COMBINATION_MFNR_RAW_TO_JPEG (MTK_FEATURE_MFNR | MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_NR| MTK_FEATURE_CZ)
// ======================================================================================================
//
const std::vector<std::unordered_map<int32_t, ScenarioFeatures>> gCustomerIspHidlScenarioFeaturesMaps =
{
{
// capture
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_ALL)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_AINR_FULL)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MFNR_FULL)
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE_FULL)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_SINGLE_RAW_TO_YUV) // encode single raw to yuv
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE_RAW_TO_YUV)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_SINGLE_RAW_TO_JPEG) // encode single raw to yuv and encode to jepg
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE_RAW_TO_JPEG)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_SINGLE_YUV_TO_YUV) // single yuv reprocessing
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE_YUV_TO_YUV)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_SINGLE_YUV_TO_JPEG) // encode single yuv to jpeg
ADD_CAMERA_FEATURE_SET(NO_FEATURE_NORMAL, MTK_FEATURE_COMBINATION_SINGLE_YUV_TO_JPEG)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_MULTIPLE_RAW_TO_RAW) // multiframe raw to single raw
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_AINR_RAW_TO_RAW)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_MULTIPLE_RAW_TO_YUV) // multiframe raw to single yuv
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_AINR_RAW_TO_YUV)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MFNR_RAW_TO_YUV)
CAMERA_SCENARIO_END
//
CAMERA_SCENARIO_START(MTK_ISP_HIDL_SCENARIO_CAPTURE_MULTIPLE_RAW_TO_JPEG) // multiframe raw to jpeg
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_AINR, MTK_FEATURE_COMBINATION_AINR_RAW_TO_JPEG)
ADD_CAMERA_FEATURE_SET(MTK_FEATURE_MFNR, MTK_FEATURE_COMBINATION_MFNR_RAW_TO_JPEG)
CAMERA_SCENARIO_END
},
};
vendor/mediatek/proprietary/packages/apps/Camera2/camerapostalgo/main/3rdparty/mtk/mtk_scenario_mgr.cpp
@@ -80,31 +80,31 @@ using namespace NSCam::v3::pipeline::policy::scenariomgr;
// #define <feature combination> (key feature | post-processing features | ...)
//
// single cam capture feature combination
-#define MTK_FEATURE_COMBINATION_SINGLE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
-#define MTK_FEATURE_COMBINATION_HDR (TP_FEATURE_HDR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
-#define MTK_FEATURE_COMBINATION_AINR (MTK_FEATURE_AINR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
+#define MTK_FEATURE_COMBINATION_SINGLE (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_HDR (TP_FEATURE_HDR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_AINR (MTK_FEATURE_AINR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| T
P_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_AINR_HDR (MTK_FEATURE_AINR_YHDR| MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
-#define MTK_FEATURE_COMBINATION_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
-#define MTK_FEATURE_COMBINATION_REMOSAIC (MTK_FEATURE_REMOSAIC| MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB)
+#define MTK_FEATURE_COMBINATION_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| T
P_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_REMOSAIC (MTK_FEATURE_REMOSAIC| MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_FB| T
P_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_CSHOT (NO_FEATURE_NORMAL | MTK_FEATURE_CZ| MTK_FEATURE_HFG)
#define MTK_FEATURE_COMBINATION_MULTICAM (NO_FEATURE_NORMAL)
-#define MTK_FEATURE_COMBINATION_YUV_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_FB)
-#define MTK_FEATURE_COMBINATION_RAW_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB)
-#define MTK_FEATURE_COMBINATION_SUPER_NIGHT_RAW_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB)
+#define MTK_FEATURE_COMBINATION_YUV_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_FB| TP_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_RAW_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB| TP_FEATURE_WATERMARK
)
+#define MTK_FEATURE_COMBINATION_SUPER_NIGHT_RAW_REPROCESS (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE| TP_FEATURE_FB| TP_FEATURE_
WATERMARK)
// dual cam capture feature combination
// the VSDOF means the combination of Bokeh feature and Depth feature
-#define MTK_FEATURE_COMBINATION_MTK_VSDOF (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_F
B| MTK_FEATURE_VSDOF)
-#define MTK_FEATURE_COMBINATION_MTK_VSDOF_HDR (TP_FEATURE_HDR_DC | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_F
B| MTK_FEATURE_VSDOF)
-#define MTK_FEATURE_COMBINATION_MTK_VSDOF_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_F
B| MTK_FEATURE_VSDOF)
+#define MTK_FEATURE_COMBINATION_MTK_VSDOF (NO_FEATURE_NORMAL | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_F
B| MTK_FEATURE_VSDOF| TP_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_MTK_VSDOF_HDR (TP_FEATURE_HDR_DC | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_F
B| MTK_FEATURE_VSDOF| TP_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_MTK_VSDOF_MFNR (MTK_FEATURE_MFNR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_F
B| MTK_FEATURE_VSDOF| TP_FEATURE_WATERMARK)
#define MTK_FEATURE_COMBINATION_MTK_VSDOF_AINR (MTK_FEATURE_AINR | MTK_FEATURE_NR| MTK_FEATURE_ABF| MTK_FEATURE_CZ| MTK_FEATURE_DRE| MTK_FEATURE_HFG| MTK_FEATURE_DCE | MTK_FEATURE_F
B| MTK_FEATURE_AINR_YUV| MTK_FEATURE_VSDOF)
// streaming feature combination (TODO: it should be refined by streaming scenario feature)
-#define MTK_FEATURE_COMBINATION_VIDEO_NORMAL (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|MTK_FEATURE_FOVA)
+#define MTK_FEATURE_COMBINATION_VIDEO_NORMAL (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|MTK_FEATURE_FOVA|TP_FEATURE_WATERMA
RK)
#define MTK_FEATURE_COMBINATION_VIDEO_NORMAL_VIDEO (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|MTK_FEATURE_FOVA)
-#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_YUV (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|MTK_FEATURE_DUAL_YUV|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|TP_FEATURE_DUA
L_YUV)
-#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWDEPTH (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|MTK_FEATURE_DUAL_HWDEPTH|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|TP_FEATU
RE_DUAL_HWDEPTH)
-#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWVSDOF (MTK_FEATURE_FB|TP_FEATURE_FB)
+#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_YUV (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|MTK_FEATURE_DUAL_YUV|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|TP_FEATURE_DUA
L_YUV|TP_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWDEPTH (MTK_FEATURE_FB|MTK_FEATURE_ASYNC_ASD|MTK_FEATURE_EIS|MTK_FEATURE_DUAL_HWDEPTH|TP_FEATURE_FB|TP_FEATURE_ASYNC_ASD|TP_FEATURE_EIS|TP_FEATU
RE_DUAL_HWDEPTH|TP_FEATURE_WATERMARK)
+#define MTK_FEATURE_COMBINATION_VIDEO_DUAL_HWVSDOF (MTK_FEATURE_FB|TP_FEATURE_FB|TP_FEATURE_WATERMARK)
4.3 为算法选择plugin
MTK HAL3在vendor/mediatek/proprietary/hardware/mtkcam3/include/mtkcam3/3rdparty/plugin/PipelinePluginType.h 中将三方算法的挂载点大致分为以下几类:
BokehPlugin: Bokeh算法挂载点,双摄景深算法的虚化部分。
DepthPlugin: Depth算法挂载点,双摄景深算法的计算深度部分。
FusionPlugin: Depth和Bokeh放在1个算法中,即合并的双摄景深算法挂载点。
JoinPlugin: Streaming相关算法挂载点,预览算法都挂载在这里。
MultiFramePlugin: 多帧算法挂载点,包括YUV与RAW,例如MFNR/HDR
RawPlugin: RAW算法挂载点,例如remosaic
YuvPlugin: Yuv单帧算法挂载点,例如美颜、广角镜头畸变校正等
对号入座,将要集成的算法选择相应的plugin。
单帧水印算法,所以预览我们选择JoinPlugin,拍照选择YuvPlugin。
多帧算法,只能选择MultiFramePlugin。并且,一般情况下多帧算法只用于拍照,不用于预览。
4.4 编写算法集成文件
水印算法目录结构
参照 FBImpl.cpp 和 sample_streaming_fb.cpp 中分别实现拍照和预览。目录结构如下: vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/ ├── Android.mk ├── include │ └── watermark.h ├── lib │ ├── arm64-v8a │ │ └── libwatermark.so │ └── armeabi-v7a │ └── libwatermark.so ├── res │ └── watermark.rgba ├── WatermarkCapture.cpp └── WatermarkPreview.cpp
文件说明:
Android.mk中配置算法库、头文件、集成的源代码CPP文件编译成库libmtkcam.plugin.tp_watermark,供libmtkcam_3rdparty.customer依赖调用。 集成的源代码CPP文件,WatermarkCapture.cpp用于拍照,WatermarkPreview.cpp用于预览。 libwatermark.so实现了添加水印的功能,libwatermark.so用来模拟需要接入的第三方算法库。watermark.h是头文件。 watermark.rgba是对应的水印文件。
多帧算法目录结构
参照mfnr/MFNRImpl.cpp中实现MFNR拍照。目录结构如下: vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/cp_tp_mfnr/ ├── Android.mk ├── include │ └── mf_processor.h ├── lib │ ├── arm64-v8a │ │ └── libmultiframe.so │ └── armeabi-v7a │ └── libmultiframe.so └── MFNRImpl.cpp
文件说明:
Android.mk中配置算法库、头文件、集成的源代码MFNRImpl.cpp文件,将它们编译成库libmtkcam.plugin.tp_mfnr,供libmtkcam_3rdparty.customer依赖调用。
libmultiframe.so实现了将连续4帧图像缩小,并拼接成一张图的功能,libmultiframe.so用来模拟需要接入的第三方多帧算法库。mf_processor.h是头文件。
MFNRImpl.cpp是集成的源代码CPP文件。
4.5 开撸代码
添加全局宏控,是否编译三方算法
device/mediateksample/[platform]/ProjectConfig.mk
@@ -5,6 +5,8 @@ AUTO_ADD_GLOBAL_DEFINE_BY_VALUE = BOOT_LOGO MTK_PLATFORM CUSTOM_KERNEL_MAIN_IMGS
BUILD_KERNEL = yes
+QXT_MFNR_SUPPORT = yes
+QXT_WATERMARK_SUPPORT = yes
BUILD_LK = yes
新增 vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/ 文件夹
vendor\mediatek\proprietary\hardware\mtkcam3\3rdparty\customer\tp_watermark\Android.mk
ifeq ($(QXT_WATERMARK_SUPPORT),yes)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libwatermark
LOCAL_SRC_FILES_32 := lib/armeabi-v7a/libwatermark.so
LOCAL_SRC_FILES_64 := lib/arm64-v8a/libwatermark.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_PROPRIETARY_MODULE := true
LOCAL_CHECK_ELF_FILES := false
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT)
################################################################################
################################################################################
include $(CLEAR_VARS)
#-----------------------------------------------------------
include $(TOP)/$(MTK_PATH_SOURCE)/hardware/mtkcam/mtkcam.mk
#-----------------------------------------------------------
LOCAL_SRC_FILES += WatermarkCapture.cpp
LOCAL_SRC_FILES += WatermarkPreview.cpp
#-----------------------------------------------------------
LOCAL_C_INCLUDES += $(MTKCAM_C_INCLUDES)
LOCAL_C_INCLUDES += $(TOP)/$(MTK_PATH_SOURCE)/hardware/mtkcam3/include
LOCAL_C_INCLUDES += $(TOP)/$(MTK_PATH_SOURCE)/hardware/mtkcam/include
#
LOCAL_C_INCLUDES += system/media/camera/include
LOCAL_C_INCLUDES += $(TOP)/external/libyuv/files/include/
LOCAL_C_INCLUDES += $(TOP)/$(MTK_PATH_SOURCE)/hardware/mtkcam3/3rdparty/customer/tp_watermark/include
#-----------------------------------------------------------
LOCAL_CFLAGS += $(MTKCAM_CFLAGS)
#
#-----------------------------------------------------------
LOCAL_STATIC_LIBRARIES +=
#
LOCAL_WHOLE_STATIC_LIBRARIES +=
#-----------------------------------------------------------
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_SHARED_LIBRARIES += libutils
LOCAL_SHARED_LIBRARIES += libcutils
LOCAL_SHARED_LIBRARIES += libmtkcam_modulehelper
LOCAL_SHARED_LIBRARIES += libmtkcam_stdutils
LOCAL_SHARED_LIBRARIES += libmtkcam_pipeline
LOCAL_SHARED_LIBRARIES += libmtkcam_metadata
LOCAL_SHARED_LIBRARIES += libmtkcam_metastore
LOCAL_SHARED_LIBRARIES += libmtkcam_streamutils
LOCAL_SHARED_LIBRARIES += libmtkcam_imgbuf
LOCAL_SHARED_LIBRARIES += libyuv.vendor
#-----------------------------------------------------------
LOCAL_HEADER_LIBRARIES := libutils_headers liblog_headers libhardware_headers
#-----------------------------------------------------------
LOCAL_MODULE := libmtkcam.plugin.tp_watermark
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_OWNER := mtk
LOCAL_MODULE_TAGS := optional
include $(MTK_STATIC_LIBRARY)
################################################################################
include $(call all-makefiles-under,$(LOCAL_PATH))
endif
新增 vendor\mediatek\proprietary\hardware\mtkcam3\3rdparty\customer\tp_watermark\include\watermark.h
#include <stdio.h>
#include <string.h>
// #include <android/log.h>
namespace Watermark
{
void add(unsigned char* src, int srcWidth, int srcHeight, unsigned char* watermark,
int watermarkWidth, int watermarkHeight, int x, int y);
}
新增 vendor\mediatek\proprietary\hardware\mtkcam3\3rdparty\customer\tp_watermark\WatermarkCapture.cpp
主要函数介绍:
在property函数中feature类型设置我们在第三步中添加的TP_FEATURE_WATERMARK,并设置名称、优先级等等属性。
在negotiate函数中配置算法需要的输入、输出图像的格式、尺寸。
在negotiate函数或者process函数中获取上层传下来的metadata参数,根据参数决定算法是否运行,或者将参数传给算法。
在process函数中接入算法。
#define LOG_TAG "WatermarkCapture"
//
#include <mtkcam/utils/std/Log.h>
//
#include <stdlib.h>
#include <utils/Errors.h>
#include <utils/List.h>
#include <utils/RefBase.h>
#include <sstream>
//
#include <mtkcam/utils/metadata/client/mtk_metadata_tag.h>
#include <mtkcam/utils/metadata/hal/mtk_platform_metadata_tag.h>
//
//
#include <mtkcam/utils/imgbuf/IIonImageBufferHeap.h>
//
#include <mtkcam/drv/IHalSensor.h>
#include <mtkcam/utils/std/Format.h>
//
#include <mtkcam3/pipeline/hwnode/NodeId.h>
#include <mtkcam/utils/metastore/ITemplateRequest.h>
#include <mtkcam/utils/metastore/IMetadataProvider.h>
#include <mtkcam3/3rdparty/plugin/PipelinePlugin.h>
#include <mtkcam3/3rdparty/plugin/PipelinePluginType.h>
#include <stdlib.h>
#include <watermark.h>
#include <mtkcam/utils/std/Time.h>
#include <time.h>
#include <libyuv.h>
//
using namespace NSCam;
using namespace android;
using namespace std;
using namespace NSCam::NSPipelinePlugin;
/******************************************************************************
*
******************************************************************************/
#define MY_LOGV(fmt, arg...) CAM_LOGV("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGD(fmt, arg...) CAM_LOGD("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGI(fmt, arg...) CAM_LOGI("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGW(fmt, arg...) CAM_LOGW("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGE(fmt, arg...) CAM_LOGE("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
//
#define FUNCTION_IN MY_LOGD("%s +", __FUNCTION__)
#define FUNCTION_OUT MY_LOGD("%s -", __FUNCTION__)
//systrace
#if 1
#ifndef ATRACE_TAG
#define ATRACE_TAG ATRACE_TAG_CAMERA
#endif
#include <utils/Trace.h>
#define WATERMARK_TRACE_CALL() ATRACE_CALL()
#define WATERMARK_TRACE_NAME(name) ATRACE_NAME(name)
#define WATERMARK_TRACE_BEGIN(name) ATRACE_BEGIN(name)
#define WATERMARK_TRACE_END() ATRACE_END()
#else
#define WATERMARK_TRACE_CALL()
#define WATERMARK_TRACE_NAME(name)
#define WATERMARK_TRACE_BEGIN(name)
#define WATERMARK_TRACE_END()
#endif
template <class T>
inline bool
tryGetMetadata(IMetadata const *pMetadata, MUINT32 tag, T& rVal)
{
if(pMetadata == nullptr) return MFALSE;
IMetadata::IEntry entry = pMetadata->entryFor(tag);
if(!entry.isEmpty())
{
rVal = entry.itemAt(0,Type2Type<T>());
return true;
}
else
{
#define var(v) #v
#define type(t) #t
MY_LOGW("no metadata %s in %s", var(tag), type(pMetadata));
#undef type
#undef var
}
return false;
}
/******************************************************************************
*
******************************************************************************/
class WatermarkCapture : public YuvPlugin::IProvider {
public:
typedef YuvPlugin::Property Property;
typedef YuvPlugin::Selection Selection;
typedef YuvPlugin::Request::Ptr RequestPtr;
typedef YuvPlugin::RequestCallback::Ptr RequestCallbackPtr;
private:
int mOpenid;
MBOOL mEnable = 1;
MBOOL mDump = 0;
unsigned char *mSrcRGBA = nullptr;
unsigned char *mWatermarkRGBA = nullptr;
int mWatermarkWidth = 0;
int mWatermarkHeight = 0;
public:
WatermarkCapture();
~WatermarkCapture();
void init();
void uninit();
void abort(vector <RequestPtr> &pRequests);
void set(MINT32 iOpenId, MINT32 iOpenId2);
const Property &property();
MERROR negotiate(Selection &sel);
MERROR process(RequestPtr pRequest, RequestCallbackPtr pCallback);
};
WatermarkCapture::WatermarkCapture() : mOpenid(-1) {
FUNCTION_IN;
mEnable = property_get_bool("vendor.debug.camera.watermark.capture.enable", 1);
mDump = property_get_bool("vendor.debug.camera.watermark.capture.dump", 0);
FUNCTION_OUT;
}
WatermarkCapture::~WatermarkCapture() {
FUNCTION_IN;
FUNCTION_OUT;
}
void WatermarkCapture::init() {
FUNCTION_IN;
mWatermarkWidth = 180;
mWatermarkHeight = 640;
int watermarkSize = mWatermarkWidth * mWatermarkHeight * 4;
mWatermarkRGBA = (unsigned char *) malloc(watermarkSize);
FILE *fp;
char path[256];
snprintf(path, sizeof(path), "/vendor/res/images/watermark.rgba");
if ((fp = fopen(path, "r")) == NULL) {
MY_LOGE("Failed to open /vendor/res/images/watermark.rgba");
}
fread(mWatermarkRGBA, 1, watermarkSize, fp);
fclose(fp);
FUNCTION_OUT;
}
void WatermarkCapture::uninit() {
FUNCTION_IN;
free(mWatermarkRGBA);
FUNCTION_OUT;
}
void WatermarkCapture::abort(vector <RequestPtr> &pRequests) {
FUNCTION_IN;
(void)pRequests;
FUNCTION_OUT;
}
void WatermarkCapture::set(MINT32 iOpenId, MINT32 iOpenId2) {
FUNCTION_IN;
MY_LOGD("set openId:%d openId2:%d", iOpenId, iOpenId2);
mOpenid = iOpenId;
FUNCTION_OUT;
}
const WatermarkCapture::Property &WatermarkCapture::property() {
FUNCTION_IN;
static Property prop;
static bool inited;
if (!inited) {
prop.mName = "TP_WATERMARK";
prop.mFeatures = TP_FEATURE_WATERMARK;
prop.mInPlace = MTRUE;
prop.mFaceData = eFD_Current;
prop.mPosition = 0;
inited = true;
}
FUNCTION_OUT;
return prop;
}
MERROR WatermarkCapture::negotiate(Selection &sel) {
FUNCTION_IN;
if (!mEnable) {
MY_LOGD("Force off TP_WATERMARK");
FUNCTION_OUT;
return -EINVAL;
}
sel.mIBufferFull
.setRequired(MTRUE)
.addAcceptedFormat(eImgFmt_I420)
.addAcceptedSize(eImgSize_Full);
sel.mIMetadataDynamic.setRequired(MTRUE);
sel.mIMetadataApp.setRequired(MTRUE);
sel.mIMetadataHal.setRequired(MTRUE);
sel.mOMetadataApp.setRequired(MTRUE);
sel.mOMetadataHal.setRequired(MTRUE);
FUNCTION_OUT;
return OK;
}
MERROR WatermarkCapture::process(RequestPtr pRequest,
RequestCallbackPtr pCallback = nullptr) {
FUNCTION_IN;
WATERMARK_TRACE_CALL();
MBOOL needRun = MFALSE;
if (pRequest->mIBufferFull != nullptr && pRequest->mOBufferFull != nullptr) {
IImageBuffer *pIBufferFull = pRequest->mIBufferFull->acquire();
IImageBuffer *pOBufferFull = pRequest->mOBufferFull->acquire();
if (pRequest->mIMetadataDynamic != nullptr) {
IMetadata *meta = pRequest->mIMetadataDynamic->acquire();
if (meta != NULL)
MY_LOGD("[IN] Dynamic metadata count: %d", meta->count());
else
MY_LOGD("[IN] Dynamic metadata empty");
}
int frameNo = 0, requestNo = 0;
if (pRequest->mIMetadataHal != nullptr) {
IMetadata *pIMetataHAL = pRequest->mIMetadataHal->acquire();
if (pIMetataHAL != NULL) {
MY_LOGD("[IN] HAL metadata count: %d", pIMetataHAL->count());
if (!tryGetMetadata<int>(pIMetataHAL, MTK_PIPELINE_FRAME_NUMBER, frameNo)) {
frameNo = 0;
}
if (!tryGetMetadata<int>(pIMetataHAL, MTK_PIPELINE_REQUEST_NUMBER, requestNo)) {
requestNo = 0;
}
MY_LOGD("frameNo: %d, requestNo: %d", frameNo, requestNo);
} else {
MY_LOGD("[IN] HAL metadata empty");
}
}
if (pRequest->mIMetadataApp != nullptr) {
IMetadata *pIMetadataApp = pRequest->mIMetadataApp->acquire();
MINT32 mode = 0;
if (!tryGetMetadata<MINT32>(pIMetadataApp, QXT_FEATURE_WATERMARK, mode)) {
mode = 0;
}
needRun = mode == 1 ? 1 : 0;
}
MY_LOGD("needRun: %d", needRun);
int width = pIBufferFull->getImgSize().w;
int height = pIBufferFull->getImgSize().h;
MINT inFormat = pIBufferFull->getImgFormat();
if (needRun && inFormat == NSCam::eImgFmt_I420) {
uint32_t currentTime = (NSCam::Utils::TimeTool::getReadableTime()) % 1000;
time_t timep;
time (&timep);
char currentDate[20];
strftime(currentDate, sizeof(currentDate), "%Y%m%d_%H%M%S", localtime(&timep));
//dump input I420
if (mDump) {
char path[256];
snprintf(path, sizeof(path), "/data/vendor/camera_dump/capture_in_frame%d_%dx%d_%s_%d.i420",
frameNo, width, height, currentDate, currentTime);
pIBufferFull->saveToFile(path);
}
nsecs_t t1 = systemTime(CLOCK_MONOTONIC);
if (mSrcRGBA == NULL) {
mSrcRGBA = (unsigned char *) malloc(width * height * 4);
}
//convert I420 to RGBA
libyuv::I420ToABGR((unsigned char *) (pIBufferFull->getBufVA(0)), width,
(unsigned char *) (pIBufferFull->getBufVA(1)), width >> 1,
(unsigned char *) (pIBufferFull->getBufVA(2)), width >> 1,
mSrcRGBA, width * 4,
width, height);
nsecs_t t2 = systemTime(CLOCK_MONOTONIC);
MY_LOGD("Prepare src cost %02ld ms", ns2ms(t2 - t1));
Watermark::add(mSrcRGBA, width, height, mWatermarkRGBA, mWatermarkWidth, mWatermarkHeight, (width - mWatermarkWidth) / 2, (height - mWatermarkHeight) / 2);
nsecs_t t3 = systemTime(CLOCK_MONOTONIC);
MY_LOGD("Add watermark cost %02ld ms", ns2ms(t3 - t2));
//convert RGBA to I420
libyuv::ABGRToI420(mSrcRGBA, width * 4,
(unsigned char *) (pOBufferFull->getBufVA(0)), width,
(unsigned char *) (pOBufferFull->getBufVA(1)), width >> 1,
(unsigned char *) (pOBufferFull->getBufVA(2)), width >> 1,
width, height);
nsecs_t t4 = systemTime(CLOCK_MONOTONIC);
MY_LOGD("Copy in to out cost %02ld ms", ns2ms(t4 - t3));
//dump output I420
if (mDump) {
char path[256];
snprintf(path, sizeof(path), "/data/vendor/camera_dump/capture_out_frame%d_%dx%d_%s_%d.i420",
frameNo, width, height, currentDate, currentTime);
pOBufferFull->saveToFile(path);
}
free(mSrcRGBA);
} else {
if (!needRun) {
MY_LOGE("No need run, skip add watermark for capture.");
} else if (inFormat != NSCam::eImgFmt_YV12) {
MY_LOGE("Unsupported format, skip add watermark for capture.");
} else {
MY_LOGE("Unknown exception, skip add watermark for capture.");
}
memcpy((unsigned char *) (pOBufferFull->getBufVA(0)),
(unsigned char *) (pIBufferFull->getBufVA(0)),
pIBufferFull->getBufSizeInBytes(0));
memcpy((unsigned char *) (pOBufferFull->getBufVA(1)),
(unsigned char *) (pIBufferFull->getBufVA(1)),
pIBufferFull->getBufSizeInBytes(1));
memcpy((unsigned char *) (pOBufferFull->getBufVA(2)),
(unsigned char *) (pIBufferFull->getBufVA(2)),
pIBufferFull->getBufSizeInBytes(2));
}
pRequest->mIBufferFull->release();
pRequest->mOBufferFull->release();
if (pRequest->mIMetadataDynamic != nullptr) {
pRequest->mIMetadataDynamic->release();
}
if (pRequest->mIMetadataHal != nullptr) {
pRequest->mIMetadataHal->release();
}
if (pRequest->mIMetadataApp != nullptr) {
pRequest->mIMetadataApp->release();
}
}
if (pCallback != nullptr) {
MY_LOGD("callback request");
pCallback->onCompleted(pRequest, 0);
}
FUNCTION_OUT;
return OK;
}
REGISTER_PLUGIN_PROVIDER(Yuv, WatermarkCapture);
新增
vendor\mediatek\proprietary\hardware\mtkcam3\3rdparty\customer\tp_watermark\WatermarkPreview.cpp
#include <mtkcam3/3rdparty/plugin/PipelinePluginType.h>
#include <mtkcam/utils/metadata/hal/mtk_platform_metadata_tag.h>
#include <mtkcam/utils/metadata/client/mtk_metadata_tag.h>
#include <cutils/properties.h>
#include <watermark.h>
#include <mtkcam/utils/std/Time.h>
#include <time.h>
#include <libyuv.h>
#include <dlfcn.h>
using NSCam::NSPipelinePlugin::Interceptor;
using NSCam::NSPipelinePlugin::PipelinePlugin;
using NSCam::NSPipelinePlugin::PluginRegister;
using NSCam::NSPipelinePlugin::Join;
using NSCam::NSPipelinePlugin::JoinPlugin;
using namespace NSCam::NSPipelinePlugin;
using NSCam::MSize;
using NSCam::MERROR;
using NSCam::IImageBuffer;
using NSCam::IMetadata;
using NSCam::Type2Type;
#ifdef LOG_TAG
#undef LOG_TAG
#endif // LOG_TAG
#define LOG_TAG "WatermarkPreview"
#include <log/log.h>
#include <android/log.h>
#define MY_LOGI(fmt, arg...) ALOGI("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGD(fmt, arg...) ALOGD("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGW(fmt, arg...) ALOGW("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGE(fmt, arg...) ALOGE("[%s] " fmt, __FUNCTION__, ##arg)
#define FUNCTION_IN MY_LOGD("%s +", __FUNCTION__)
#define FUNCTION_OUT MY_LOGD("%s -", __FUNCTION__)
template <class T>
inline bool
tryGetMetadata(IMetadata const *pMetadata, MUINT32 tag, T& rVal)
{
if(pMetadata == nullptr) return MFALSE;
IMetadata::IEntry entry = pMetadata->entryFor(tag);
if(!entry.isEmpty())
{
rVal = entry.itemAt(0,Type2Type<T>());
return true;
}
else
{
#define var(v) #v
#define type(t) #t
MY_LOGW("no metadata %s in %s", var(tag), type(pMetadata));
#undef type
#undef var
}
return false;
}
class WatermarkPreview : public JoinPlugin::IProvider {
public:
typedef JoinPlugin::Property Property;
typedef JoinPlugin::Selection Selection;
typedef JoinPlugin::Request::Ptr RequestPtr;
typedef JoinPlugin::RequestCallback::Ptr RequestCallbackPtr;
private:
bool mDisponly = false;
bool mInplace = false;
int mOpenID1 = 0;
int mOpenID2 = 0;
MBOOL mEnable = 1;
MBOOL mDump = 0;
unsigned char *mSrcRGBA = nullptr;
unsigned char *mWatermarkRGBA = nullptr;
int mWatermarkWidth = 0;
int mWatermarkHeight = 0;
public:
WatermarkPreview();
~WatermarkPreview();
void init();
void uninit();
void abort(std::vector <RequestPtr> &pRequests);
void set(MINT32 openID1, MINT32 openID2);
const Property &property();
MERROR negotiate(Selection &sel);
MERROR process(RequestPtr pRequest, RequestCallbackPtr pCallback);
private:
MERROR getConfigSetting(Selection &sel);
MERROR getP1Setting(Selection &sel);
MERROR getP2Setting(Selection &sel);
};
WatermarkPreview::WatermarkPreview() {
FUNCTION_IN;
mEnable = property_get_bool("vendor.debug.camera.watermark.preview.enable", 1);
mDump = property_get_bool("vendor.debug.camera.watermark.preview.dump", 0);
FUNCTION_OUT;
}
WatermarkPreview::~WatermarkPreview() {
FUNCTION_IN;
FUNCTION_OUT;
}
void WatermarkPreview::init() {
FUNCTION_IN;
mWatermarkWidth = 180;
mWatermarkHeight = 640;
int watermarkSize = mWatermarkWidth * mWatermarkHeight * 4;
mWatermarkRGBA = (unsigned char *) malloc(watermarkSize);
FILE *fp;
char path[256];
snprintf(path, sizeof(path), "/vendor/res/images/watermark.rgba");
if ((fp = fopen(path, "r")) == NULL) {
MY_LOGE("Failed to open /vendor/res/images/watermark.rgba");
}
fread(mWatermarkRGBA, 1, watermarkSize, fp);
fclose(fp);
FUNCTION_OUT;
}
void WatermarkPreview::uninit() {
FUNCTION_IN;
free(mSrcRGBA);
free(mWatermarkRGBA);
FUNCTION_OUT;
}
void WatermarkPreview::abort(std::vector <RequestPtr> &pRequests) {
FUNCTION_IN;
(void)pRequests;
FUNCTION_OUT;
}
void WatermarkPreview::set(MINT32 openID1, MINT32 openID2) {
FUNCTION_IN;
MY_LOGD("set openID1:%d openID2:%d", openID1, openID2);
mOpenID1 = openID1;
mOpenID2 = openID2;
FUNCTION_OUT;
}
const WatermarkPreview::Property &WatermarkPreview::property() {
FUNCTION_IN;
static Property prop;
static bool inited;
if (!inited) {
prop.mName = "TP_WATERMARK";
prop.mFeatures = TP_FEATURE_WATERMARK;
//prop.mInPlace = MTRUE;
//prop.mFaceData = eFD_Current;
//prop.mPosition = 0;
inited = true;
}
FUNCTION_OUT;
return prop;
}
MERROR WatermarkPreview::negotiate(Selection &sel) {
FUNCTION_IN;
MERROR ret = OK;
if (sel.mSelStage == eSelStage_CFG) {
ret = getConfigSetting(sel);
} else if (sel.mSelStage == eSelStage_P1) {
ret = getP1Setting(sel);
} else if (sel.mSelStage == eSelStage_P2) {
ret = getP2Setting(sel);
}
FUNCTION_OUT;
return ret;
}
MERROR WatermarkPreview::process(RequestPtr pRequest, RequestCallbackPtr pCallback) {
FUNCTION_IN;
(void) pCallback;
MERROR ret = -EINVAL;
MBOOL needRun = MFALSE;
IImageBuffer *in = NULL, *out = NULL;
if (pRequest->mIBufferMain1 != NULL && pRequest->mOBufferMain1 != NULL) {
in = pRequest->mIBufferMain1->acquire();
out = pRequest->mOBufferMain1->acquire();
int frameNo = 0, requestNo = 0;
if (pRequest->mIMetadataHal1 != nullptr) {
IMetadata *pIMetataHAL1 = pRequest->mIMetadataHal1->acquire();
if (pIMetataHAL1 != NULL) {
if (!tryGetMetadata<int>(pIMetataHAL1, MTK_PIPELINE_FRAME_NUMBER, frameNo)) {
frameNo = 0;
}
if (!tryGetMetadata<int>(pIMetataHAL1, MTK_PIPELINE_REQUEST_NUMBER, requestNo)) {
requestNo = 0;
}
pRequest->mIMetadataHal1->release();
MY_LOGD("frameNo: %d, requestNo: %d", frameNo, requestNo);
} else {
MY_LOGD("HAL metadata empty");
}
}
MY_LOGD("in[%d](%dx%d)=%p out[%d](%dx%d)=%p",
in->getPlaneCount(), in->getImgSize().w, in->getImgSize().h, in,
out->getPlaneCount(), out->getImgSize().w, out->getImgSize().h, out);
if (pRequest->mIMetadataApp != nullptr) {
IMetadata *pIMetadataApp = pRequest->mIMetadataApp->acquire();
MINT32 mode = 0;
if (!tryGetMetadata<MINT32>(pIMetadataApp, QXT_FEATURE_WATERMARK, mode)) {
mode = 0;
}
needRun = mode == 1 ? 1 : 0;
pRequest->mIMetadataApp->release();
}
MY_LOGD("needRun: %d", needRun);
int width = in->getImgSize().w;
int height = in->getImgSize().h;
MINT inFormat = in->getImgFormat();
if (needRun && inFormat == NSCam::eImgFmt_YV12) {
uint32_t currentTime = (NSCam::Utils::TimeTool::getReadableTime()) % 1000;
time_t timep;
time (&timep);
char currentDate[20];
strftime(currentDate, sizeof(currentDate), "%Y%m%d_%H%M%S", localtime(&timep));
//dump input YV12
if (mDump) {
char path[256];
snprintf(path, sizeof(path), "/data/vendor/camera_dump/preview_in_frame%d_%dx%d_%s_%d.yv12",
frameNo, width, height, currentDate, currentTime);
in->saveToFile(path);
}
nsecs_t t1 = systemTime(CLOCK_MONOTONIC);
if (mSrcRGBA == NULL) {
mSrcRGBA = (unsigned char *) malloc(width * height * 4);
}
//convert YV12 to RGBA
libyuv::I420ToABGR((unsigned char *)(in->getBufVA(0)), width,
(unsigned char *)(in->getBufVA(2)), width >> 1,
(unsigned char *)(in->getBufVA(1)), width >> 1,
mSrcRGBA, width * 4,
width, height);
nsecs_t t2 = systemTime(CLOCK_MONOTONIC);
MY_LOGD("Prepare src cost %02ld ms", ns2ms(t2 - t1));
Watermark::add(mSrcRGBA, width, height, mWatermarkRGBA, mWatermarkWidth, mWatermarkHeight, (width - mWatermarkWidth) / 2, (height - mWatermarkHeight) / 2);
nsecs_t t3 = systemTime(CLOCK_MONOTONIC);
MY_LOGD("Add watermark cost %02ld ms", ns2ms(t3 - t2));
//convert RGBA to YV12
libyuv::ABGRToI420(mSrcRGBA, width * 4,
(unsigned char *)(out->getBufVA(0)), width,
(unsigned char *)(out->getBufVA(2)), width >> 1,
(unsigned char *)(out->getBufVA(1)), width >> 1,
width, height);
nsecs_t t4 = systemTime(CLOCK_MONOTONIC);
MY_LOGD("Copy in to out cost %02ld ms", ns2ms(t4 - t3));
//dump output YV12
if (mDump) {
char path[256];
snprintf(path, sizeof(path), "/data/vendor/camera_dump/preview_out_frame%d_%dx%d_%s_%d.yv12",
frameNo, width, height, currentDate, currentTime);
out->saveToFile(path);
}
} else {
if (!needRun) {
MY_LOGE("No need run, skip add watermark for preview.");
} else if (inFormat != NSCam::eImgFmt_YV12) {
MY_LOGE("Unsupported format, skip add watermark for preview.");
} else {
MY_LOGE("Unknown exception, skip add watermark for preview.");
}
memcpy((unsigned char *) (out->getBufVA(0)),
(unsigned char *)(in->getBufVA(0)),
in->getBufSizeInBytes(0));
memcpy((unsigned char *) (out->getBufVA(1)),
(unsigned char *)(in->getBufVA(1)),
in->getBufSizeInBytes(1));
memcpy((unsigned char *) (out->getBufVA(2)),
(unsigned char *)(in->getBufVA(2)),
in->getBufSizeInBytes(2));
}
pRequest->mIBufferMain1->release();
pRequest->mOBufferMain1->release();
ret = OK;
}
FUNCTION_OUT;
return ret;
}
MERROR WatermarkPreview::getConfigSetting(Selection &sel) {
MY_LOGI("max out size(%dx%d)",
sel.mCfgInfo.mMaxOutSize.w, sel.mCfgInfo.mMaxOutSize.h);
mDisponly = property_get_bool("vendor.debug.tpi.s.fb.disponly", 0);
mInplace = mDisponly || property_get_bool("vendor.debug.tpi.s.fb.inplace", 0);
sel.mCfgOrder = 3;
sel.mCfgJoinEntry = eJoinEntry_S_YUV;
sel.mCfgInplace = mInplace;
sel.mCfgEnableFD = MTRUE;
sel.mCfgRun = mEnable;
sel.mIBufferMain1.setRequired(MTRUE);
if (!mDisponly && property_get_bool("vendor.debug.tpi.s.fb.nv21", 0)) {
sel.mIBufferMain1.addAcceptedFormat(NSCam::eImgFmt_NV21);
}
if (!mDisponly && property_get_bool("vendor.debug.tpi.s.fb.size", 0)) {
sel.mIBufferMain1.setSpecifiedSize(sel.mCfgInfo.mMaxOutSize);
}
sel.mOBufferMain1.setRequired(MTRUE);
sel.mIBufferMain1.addAcceptedFormat(NSCam::eImgFmt_YV12);
sel.mIBufferMain1.addAcceptedSize(eImgSize_Full);
IMetadata *meta = sel.mIMetadataApp.getControl().get();
MY_LOGD("sessionMeta=%p", meta);
return OK;
}
MERROR WatermarkPreview::getP1Setting(Selection &sel) {
(void) sel;
return OK;
}
MERROR WatermarkPreview::getP2Setting(Selection &sel) {
MBOOL run = MTRUE;
sel.mP2Run = run;
return OK;
}
REGISTER_PLUGIN_PROVIDER(Join, WatermarkPreview);
将上面编译得到的 libwatermark.so 拷贝到对应文件夹
至此水印算法相关代码增加完成,接下来是多帧算法相关源码
新增 vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/cp_tp_mfnr/ 文件夹
新增
vendor\mediatek\proprietary\hardware\mtkcam3\3rdparty\customer\cp_tp_mfnr\Android.mk
ifeq ($(QXT_MFNR_SUPPORT),yes)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libmultiframe
LOCAL_SRC_FILES_32 := lib/armeabi-v7a/libmultiframe.so
LOCAL_SRC_FILES_64 := lib/arm64-v8a/libmultiframe.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_PROPRIETARY_MODULE := true
LOCAL_CHECK_ELF_FILES := false
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT)
################################################################################
################################################################################
include $(CLEAR_VARS)
#-----------------------------------------------------------
include $(TOP)/$(MTK_PATH_SOURCE)/hardware/mtkcam/mtkcam.mk
#-----------------------------------------------------------
LOCAL_SRC_FILES += MFNRImpl.cpp
#-----------------------------------------------------------
LOCAL_C_INCLUDES += $(MTKCAM_C_INCLUDES)
LOCAL_C_INCLUDES += $(TOP)/$(MTK_PATH_SOURCE)/hardware/mtkcam3/include $(MTK_PATH_SOURCE)/hardware/mtkcam/include
LOCAL_C_INCLUDES += $(TOP)/$(MTK_PATH_COMMON)/hal/inc
LOCAL_C_INCLUDES += $(TOP)/$(MTK_PATH_CUSTOM_PLATFORM)/hal/inc
LOCAL_C_INCLUDES += $(TOP)/external/libyuv/files/include/
LOCAL_C_INCLUDES += $(TOP)/$(MTK_PATH_SOURCE)/hardware/mtkcam3/3rdparty/customer/cp_tp_mfnr/include
#
LOCAL_C_INCLUDES += system/media/camera/include
#-----------------------------------------------------------
LOCAL_CFLAGS += $(MTKCAM_CFLAGS)
#
#-----------------------------------------------------------
LOCAL_STATIC_LIBRARIES +=
#
LOCAL_WHOLE_STATIC_LIBRARIES +=
#-----------------------------------------------------------
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_SHARED_LIBRARIES += libutils
LOCAL_SHARED_LIBRARIES += libcutils
LOCAL_SHARED_LIBRARIES += libmtkcam_modulehelper
LOCAL_SHARED_LIBRARIES += libmtkcam_stdutils
LOCAL_SHARED_LIBRARIES += libmtkcam_pipeline
LOCAL_SHARED_LIBRARIES += libmtkcam_metadata
LOCAL_SHARED_LIBRARIES += libmtkcam_metastore
LOCAL_SHARED_LIBRARIES += libmtkcam_streamutils
LOCAL_SHARED_LIBRARIES += libmtkcam_imgbuf
LOCAL_SHARED_LIBRARIES += libmtkcam_exif
#LOCAL_SHARED_LIBRARIES += libmtkcam_3rdparty
#-----------------------------------------------------------
LOCAL_HEADER_LIBRARIES := libutils_headers liblog_headers libhardware_headers
#-----------------------------------------------------------
LOCAL_MODULE := libmtkcam.plugin.tp_mfnr
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_OWNER := mtk
LOCAL_MODULE_TAGS := optional
include $(MTK_STATIC_LIBRARY)
################################################################################
#
################################################################################
include $(call all-makefiles-under,$(LOCAL_PATH))
endif
新增
vendor\mediatek\proprietary\hardware\mtkcam3\3rdparty\customer\cp_tp_mfnr\include\mf_processor.h
头文件中的接口函数介绍:
setFrameCount: 没有实际作用,用于模拟设置第三方多帧算法的帧数。因为部分第三方多帧算法在不同场景下需要的帧数可能是不同的。
setParams: 也没有实际作用,用于模拟设置第三方多帧算法所需的参数。
addFrame: 用于添加一帧图像数据,用于模拟第三方多帧算法添加图像数据。
process: 将前面添加的4帧图像数据,缩小并拼接成一张原大小的图。
createInstance: 创建接口类对象。
#ifndef QXT_MULTI_FRAME_H
#define QXT_MULTI_FRAME_H
class MFProcessor {
public:
virtual ~MFProcessor() {}
virtual void setFrameCount(int num) = 0;
virtual void setParams() = 0;
virtual void addFrame(unsigned char *src, int srcWidth, int srcHeight) = 0;
virtual void addFrame(unsigned char *srcY, unsigned char *srcU, unsigned char *srcV,
int srcWidth, int srcHeight) = 0;
virtual void scale(unsigned char *src, int srcWidth, int srcHeight,
unsigned char *dst, int dstWidth, int dstHeight) = 0;
virtual void process(unsigned char *output, int outputWidth, int outputHeight) = 0;
virtual void process(unsigned char *outputY, unsigned char *outputU, unsigned char *outputV,
int outputWidth, int outputHeight) = 0;
static MFProcessor* createInstance(int width, int height);
};
#endif //QXT_MULTI_FRAME_H
新增
vendor\mediatek\proprietary\hardware\mtkcam3\3rdparty\customer\cp_tp_mfnr\MFNRImpl.cpp
主要函数介绍:
在property函数中feature类型设置成TP_FEATURE_MFNR,并设置名称、优先级、最大帧数等等属性。尤其注意mNeedRrzoBuffer属性,一般情况下,多帧算法必须要设置为MTRUE。
在negotiate函数中配置算法需要的输入、输出图像的格式、尺寸。注意,多帧算法有多帧输入,但是只需要一帧输出。因此这里设置了mRequestIndex == 0时才需要mOBufferFull。也就是只有第一帧才有输入和输出,其它帧只有输入。 另外,还在negotiate函数中获取上层传下来的metadata参数,根据参数决定算法是否运行。
在process函数中接入算法。第一帧时创建算法接口类对象,然后每一帧都调用算法接口函数addFrame加入,最后一帧再调用算法接口函数process进行处理并获取输出
#ifdef LOG_TAG
#undef LOG_TAG
#endif // LOG_TAG
#define LOG_TAG "MFNRProvider"
static const char *__CALLERNAME__ = LOG_TAG;
//
#include <mtkcam/utils/std/Log.h>
//
#include <stdlib.h>
#include <utils/Errors.h>
#include <utils/List.h>
#include <utils/RefBase.h>
#include <sstream>
#include <unordered_map> // std::unordered_map
//
#include <mtkcam/utils/metadata/client/mtk_metadata_tag.h>
#include <mtkcam/utils/metadata/hal/mtk_platform_metadata_tag.h>
//zHDR
#include <mtkcam/utils/hw/HwInfoHelper.h> // NSCamHw::HwInfoHelper
#include <mtkcam3/feature/utils/FeatureProfileHelper.h> //ProfileParam
#include <mtkcam/drv/IHalSensor.h>
//
#include <mtkcam/utils/imgbuf/IIonImageBufferHeap.h>
//
#include <mtkcam/utils/std/Format.h>
#include <mtkcam/utils/std/Time.h>
//
#include <mtkcam3/pipeline/hwnode/NodeId.h>
//
#include <mtkcam/utils/metastore/IMetadataProvider.h>
#include <mtkcam/utils/metastore/ITemplateRequest.h>
#include <mtkcam/utils/metastore/IMetadataProvider.h>
#include <mtkcam3/3rdparty/plugin/PipelinePlugin.h>
#include <mtkcam3/3rdparty/plugin/PipelinePluginType.h>
//
#include <isp_tuning/isp_tuning.h> //EIspProfile_T, EOperMode_*
//
#include <custom_metadata/custom_metadata_tag.h>
//
#include <libyuv.h>
#include <mf_processor.h>
using namespace NSCam;
using namespace android;
using namespace std;
using namespace NSCam::NSPipelinePlugin;
using namespace NSIspTuning;
/******************************************************************************
*
******************************************************************************/
#define MY_LOGV(fmt, arg...) CAM_LOGV("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGD(fmt, arg...) CAM_LOGD("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGI(fmt, arg...) CAM_LOGI("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGW(fmt, arg...) CAM_LOGW("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
#define MY_LOGE(fmt, arg...) CAM_LOGE("(%d)[%s] " fmt, ::gettid(), __FUNCTION__, ##arg)
//
#define MY_LOGV_IF(cond, ...) do { if ( (cond) ) { MY_LOGV(__VA_ARGS__); } }while(0)
#define MY_LOGD_IF(cond, ...) do { if ( (cond) ) { MY_LOGD(__VA_ARGS__); } }while(0)
#define MY_LOGI_IF(cond, ...) do { if ( (cond) ) { MY_LOGI(__VA_ARGS__); } }while(0)
#define MY_LOGW_IF(cond, ...) do { if ( (cond) ) { MY_LOGW(__VA_ARGS__); } }while(0)
#define MY_LOGE_IF(cond, ...) do { if ( (cond) ) { MY_LOGE(__VA_ARGS__); } }while(0)
//
#define ASSERT(cond, msg) do { if (!(cond)) { printf("Failed: %s\n", msg); return; } }while(0)
#define __DEBUG // enable debug
#ifdef __DEBUG
#include <memory>
#define FUNCTION_SCOPE \
auto __scope_logger__ = [](char const* f)->std::shared_ptr<const char>{ \
CAM_LOGD("(%d)[%s] + ", ::gettid(), f); \
return std::shared_ptr<const char>(f, [](char const* p){CAM_LOGD("(%d)[%s] -", ::gettid(), p);}); \
}(__FUNCTION__)
#else
#define FUNCTION_SCOPE
#endif
template <typename T>
inline MBOOL
tryGetMetadata(
IMetadata* pMetadata,
MUINT32 const tag,
T & rVal
)
{
if (pMetadata == NULL) {
MY_LOGW("pMetadata == NULL");
return MFALSE;
}
IMetadata::IEntry entry = pMetadata->entryFor(tag);
if (!entry.isEmpty()) {
rVal = entry.itemAt(0, Type2Type<T>());
return MTRUE;
}
return MFALSE;
}
#define MFNR_FRAME_COUNT 4
/******************************************************************************
*
******************************************************************************/
class MFNRProviderImpl : public MultiFramePlugin::IProvider {
typedef MultiFramePlugin::Property Property;
typedef MultiFramePlugin::Selection Selection;
typedef MultiFramePlugin::Request::Ptr RequestPtr;
typedef MultiFramePlugin::RequestCallback::Ptr RequestCallbackPtr;
public:
virtual void set(MINT32 iOpenId, MINT32 iOpenId2) {
MY_LOGD("set openId:%d openId2:%d", iOpenId, iOpenId2);
mOpenId = iOpenId;
}
virtual const Property& property() {
FUNCTION_SCOPE;
static Property prop;
static bool inited;
if (!inited) {
prop.mName = "TP_MFNR";
prop.mFeatures = TP_FEATURE_MFNR;
prop.mThumbnailTiming = eTiming_P2;
prop.mPriority = ePriority_Highest;
prop.mZsdBufferMaxNum = 8; // maximum frames requirement
prop.mNeedRrzoBuffer = MTRUE; // rrzo requirement for BSS
inited = MTRUE;
}
return prop;
};
virtual MERROR negotiate(Selection& sel) {
FUNCTION_SCOPE;
IMetadata* appInMeta = sel.mIMetadataApp.getControl().get();
tryGetMetadata<MINT32>(appInMeta, QXT_FEATURE_MFNR, mEnable);
MY_LOGD("mEnable: %d", mEnable);
if (!mEnable) {
MY_LOGD("Force off TP_MFNR shot");
return BAD_VALUE;
}
sel.mRequestCount = MFNR_FRAME_COUNT;
MY_LOGD("mRequestCount=%d", sel.mRequestCount);
sel.mIBufferFull
.setRequired(MTRUE)
.addAcceptedFormat(eImgFmt_I420) // I420 first
.addAcceptedFormat(eImgFmt_YV12)
.addAcceptedFormat(eImgFmt_NV21)
.addAcceptedFormat(eImgFmt_NV12)
.addAcceptedSize(eImgSize_Full);
//sel.mIBufferSpecified.setRequired(MTRUE).setAlignment(16, 16);
sel.mIMetadataDynamic.setRequired(MTRUE);
sel.mIMetadataApp.setRequired(MTRUE);
sel.mIMetadataHal.setRequired(MTRUE);
if (sel.mRequestIndex == 0) {
sel.mOBufferFull
.setRequired(MTRUE)
.addAcceptedFormat(eImgFmt_I420) // I420 first
.addAcceptedFormat(eImgFmt_YV12)
.addAcceptedFormat(eImgFmt_NV21)
.addAcceptedFormat(eImgFmt_NV12)
.addAcceptedSize(eImgSize_Full);
sel.mOMetadataApp.setRequired(MTRUE);
sel.mOMetadataHal.setRequired(MTRUE);
} else {
sel.mOBufferFull.setRequired(MFALSE);
sel.mOMetadataApp.setRequired(MFALSE);
sel.mOMetadataHal.setRequired(MFALSE);
}
return OK;
};
virtual void init() {
FUNCTION_SCOPE;
mDump = property_get_bool("vendor.debug.camera.mfnr.dump", 0);
//nothing to do for MFNR
};
virtual MERROR process(RequestPtr pRequest, RequestCallbackPtr pCallback) {
FUNCTION_SCOPE;
MERROR ret = 0;
// restore callback function for abort API
if (pCallback != nullptr) {
m_callbackprt = pCallback;
}
//maybe need to keep a copy in member<sp>
IMetadata* pAppMeta = pRequest->mIMetadataApp->acquire();
IMetadata* pHalMeta = pRequest->mIMetadataHal->acquire();
IMetadata* pHalMetaDynamic = pRequest->mIMetadataDynamic->acquire();
MINT32 processUniqueKey = 0;
IImageBuffer* pInImgBuffer = NULL;
uint32_t width = 0;
uint32_t height = 0;
if (!IMetadata::getEntry<MINT32>(pHalMeta, MTK_PIPELINE_UNIQUE_KEY, processUniqueKey)) {
MY_LOGE("cannot get unique about MFNR capture");
return BAD_VALUE;
}
if (pRequest->mIBufferFull != nullptr) {
pInImgBuffer = pRequest->mIBufferFull->acquire();
width = pInImgBuffer->getImgSize().w;
height = pInImgBuffer->getImgSize().h;
MY_LOGD("[IN] Full image VA: 0x%p, Size(%dx%d), Format: %s",
pInImgBuffer->getBufVA(0), width, height, format2String(pInImgBuffer->getImgFormat()));
if (mDump) {
char path[256];
snprintf(path, sizeof(path), "/data/vendor/camera_dump/mfnr_capture_in_%d_%dx%d.%s",
pRequest->mRequestIndex, width, height, format2String(pInImgBuffer->getImgFormat()));
pInImgBuffer->saveToFile(path);
}
}
if (pRequest->mIBufferSpecified != nullptr) {
IImageBuffer* pImgBuffer = pRequest->mIBufferSpecified->acquire();
MY_LOGD("[IN] Specified image VA: 0x%p, Size(%dx%d)", pImgBuffer->getBufVA(0), pImgBuffer->getImgSize().w, pImgBuffer->getImgSize().h);
}
if (pRequest->mOBufferFull != nullptr) {
mOutImgBuffer = pRequest->mOBufferFull->acquire();
MY_LOGD("[OUT] Full image VA: 0x%p, Size(%dx%d)", mOutImgBuffer->getBufVA(0), mOutImgBuffer->getImgSize().w, mOutImgBuffer->getImgSize().h);
}
if (pRequest->mIMetadataDynamic != nullptr) {
IMetadata *meta = pRequest->mIMetadataDynamic->acquire();
if (meta != NULL)
MY_LOGD("[IN] Dynamic metadata count: ", meta->count());
else
MY_LOGD("[IN] Dynamic metadata Empty");
}
MY_LOGD("frame:%d/%d, width:%d, height:%d", pRequest->mRequestIndex, pRequest->mRequestCount, width, height);
if (pInImgBuffer != NULL && mOutImgBuffer != NULL) {
uint32_t yLength = pInImgBuffer->getBufSizeInBytes(0);
uint32_t uLength = pInImgBuffer->getBufSizeInBytes(1);
uint32_t vLength = pInImgBuffer->getBufSizeInBytes(2);
uint32_t yuvLength = yLength + uLength + vLength;
if (pRequest->mRequestIndex == 0) {//First frame
//When width or height changed, recreate multiFrame
if (mLatestWidth != width || mLatestHeight != height) {
if (mMFProcessor != NULL) {
delete mMFProcessor;
mMFProcessor = NULL;
}
mLatestWidth = width;
mLatestHeight = height;
}
if (mMFProcessor == NULL) {
MY_LOGD("create mMFProcessor %dx%d", mLatestWidth, mLatestHeight);
mMFProcessor = MFProcessor::createInstance(mLatestWidth, mLatestHeight);
mMFProcessor->setFrameCount(pRequest->mRequestCount);
}
}
mMFProcessor->addFrame((uint8_t *)pInImgBuffer->getBufVA(0),
(uint8_t *)pInImgBuffer->getBufVA(1),
(uint8_t *)pInImgBuffer->getBufVA(2),
mLatestWidth, mLatestHeight);
if (pRequest->mRequestIndex == pRequest->mRequestCount - 1) {//Last frame
if (mMFProcessor != NULL) {
mMFProcessor->process((uint8_t *)mOutImgBuffer->getBufVA(0),
(uint8_t *)mOutImgBuffer->getBufVA(1),
(uint8_t *)mOutImgBuffer->getBufVA(2),
mLatestWidth, mLatestHeight);
if (mDump) {
char path[256];
snprintf(path, sizeof(path), "/data/vendor/camera_dump/mfnr_capture_out_%d_%dx%d.%s",
pRequest->mRequestIndex, mOutImgBuffer->getImgSize().w, mOutImgBuffer->getImgSize().h,
format2String(mOutImgBuffer->getImgFormat()));
mOutImgBuffer->saveToFile(path);
}
} else {
memcpy((uint8_t *)mOutImgBuffer->getBufVA(0),
(uint8_t *)pInImgBuffer->getBufVA(0),
pInImgBuffer->getBufSizeInBytes(0));
memcpy((uint8_t *)mOutImgBuffer->getBufVA(1),
(uint8_t *)pInImgBuffer->getBufVA(1),
pInImgBuffer->getBufSizeInBytes(1));
memcpy((uint8_t *)mOutImgBuffer->getBufVA(2),
(uint8_t *)pInImgBuffer->getBufVA(2),
pInImgBuffer->getBufSizeInBytes(2));
}
mOutImgBuffer = NULL;
}
}
if (pRequest->mIBufferFull != nullptr) {
pRequest->mIBufferFull->release();
}
if (pRequest->mIBufferSpecified != nullptr) {
pRequest->mIBufferSpecified->release();
}
if (pRequest->mOBufferFull != nullptr) {
pRequest->mOBufferFull->release();
}
if (pRequest->mIMetadataDynamic != nullptr) {
pRequest->mIMetadataDynamic->release();
}
mvRequests.push_back(pRequest);
MY_LOGD("collected request(%d/%d)", pRequest->mRequestIndex, pRequest->mRequestCount);
if (pRequest->mRequestIndex == pRequest->mRequestCount - 1) {
for (auto req : mvRequests) {
MY_LOGD("callback request(%d/%d) %p", req->mRequestIndex, req->mRequestCount, pCallback.get());
if (pCallback != nullptr) {
pCallback->onCompleted(req, 0);
}
}
mvRequests.clear();
}
return ret;
};
virtual void abort(vector<RequestPtr>& pRequests) {
FUNCTION_SCOPE;
bool bAbort = false;
IMetadata *pHalMeta;
MINT32 processUniqueKey = 0;
for (auto req:pRequests) {
bAbort = false;
pHalMeta = req->mIMetadataHal->acquire();
if (!IMetadata::getEntry<MINT32>(pHalMeta, MTK_PIPELINE_UNIQUE_KEY, processUniqueKey)) {
MY_LOGW("cannot get unique about MFNR capture");
}
if (m_callbackprt != nullptr) {
MY_LOGD("m_callbackprt is %p", m_callbackprt.get());
/*MFNR plugin callback request to MultiFrameNode */
for (Vector<RequestPtr>::iterator it = mvRequests.begin() ; it != mvRequests.end(); it++) {
if ((*it) == req) {
mvRequests.erase(it);
m_callbackprt->onAborted(req);
bAbort = true;
break;
}
}
} else {
MY_LOGW("callbackptr is null");
}
if (!bAbort) {
MY_LOGW("Desire abort request[%d] is not found", req->mRequestIndex);
}
}
};
virtual void uninit() {
FUNCTION_SCOPE;
if (mMFProcessor != NULL) {
delete mMFProcessor;
mMFProcessor = NULL;
}
mLatestWidth = 0;
mLatestHeight = 0;
};
virtual ~MFNRProviderImpl() {
FUNCTION_SCOPE;
};
const char * format2String(MINT format) {
switch(format) {
case NSCam::eImgFmt_RGBA8888: return "rgba";
case NSCam::eImgFmt_RGB888: return "rgb";
case NSCam::eImgFmt_RGB565: return "rgb565";
case NSCam::eImgFmt_STA_BYTE: return "byte";
case NSCam::eImgFmt_YVYU: return "yvyu";
case NSCam::eImgFmt_UYVY: return "uyvy";
case NSCam::eImgFmt_VYUY: return "vyuy";
case NSCam::eImgFmt_YUY2: return "yuy2";
case NSCam::eImgFmt_YV12: return "yv12";
case NSCam::eImgFmt_YV16: return "yv16";
case NSCam::eImgFmt_NV16: return "nv16";
case NSCam::eImgFmt_NV61: return "nv61";
case NSCam::eImgFmt_NV12: return "nv12";
case NSCam::eImgFmt_NV21: return "nv21";
case NSCam::eImgFmt_I420: return "i420";
case NSCam::eImgFmt_I422: return "i422";
case NSCam::eImgFmt_Y800: return "y800";
case NSCam::eImgFmt_BAYER8: return "bayer8";
case NSCam::eImgFmt_BAYER10: return "bayer10";
case NSCam::eImgFmt_BAYER12: return "bayer12";
case NSCam::eImgFmt_BAYER14: return "bayer14";
case NSCam::eImgFmt_FG_BAYER8: return "fg_bayer8";
case NSCam::eImgFmt_FG_BAYER10: return "fg_bayer10";
case NSCam::eImgFmt_FG_BAYER12: return "fg_bayer12";
case NSCam::eImgFmt_FG_BAYER14: return "fg_bayer14";
default: return "unknown";
};
};
private:
MINT32 mUniqueKey;
MINT32 mOpenId;
MINT32 mRealIso;
MINT32 mShutterTime;
MBOOL mZSDMode;
MBOOL mFlashOn;
Vector<RequestPtr> mvRequests;
RequestCallbackPtr m_callbackprt;
MFProcessor* mMFProcessor = NULL;
IImageBuffer* mOutImgBuffer = NULL;
uint32_t mLatestWidth = 0;
uint32_t mLatestHeight = 0;
MINT32 mEnable = 0;
MINT32 mDump = 0;
// add end
};
REGISTER_PLUGIN_PROVIDER(MultiFrame, MFNRProviderImpl);
将上面编译得到的 libmultiframe.so 拷贝到对应文件夹
至此多帧算法相关代码增加完成
注意:
MTK原文: negotiate函数设置格式时,一个挂载点如果挂载多个同类型的plugin,则只有第一个 plugin 中的 negotiate 中的 input buffer 设定有效。 在YUVNode 下挂载单帧 YUV plugin时,一定要确保 MTK 平台的SWNR plugin 的 negotiate 直接返回不OK,不做任何 accepted format 等的设定。否则,可能会出现因 SWNR plugin和三方plugin negotiate时设定的 accepted format 不一致而导致的三方 plugin 拿不到它想要的 format 的buffer。
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/mtk/swnr/SWNRImpl.cpp
@@ -391,7 +391,8 @@ negotiate(Selection& sel)
sel.mOMetadataApp.setRequired(false);
sel.mOMetadataHal.setRequired(true);
- return OK;
+ //return OK;^M
+ return -EINVAL;//cczheng^M
}
最终vendor.img需要的目标共享库是libmtkcam_3rdparty.customer.so。因此,我们还需要修改Android.mk,
使模块 libmtkcam_3rdparty.customer 依赖 libmtkcam.plugin.tp_watermark
模块 libmtkcam_3rdparty.customer 依赖 libmtkcam.plugin.tp_mfnr
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/Android.mk
@@ -76,6 +76,19 @@ LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam.plugin.tp_zoomfusion
#
LOCAL_SHARED_LIBRARIES += libcam.iopipe
endif
+
+ifeq ($(QXT_WATERMARK_SUPPORT), yes)
+LOCAL_SHARED_LIBRARIES += libwatermark
+LOCAL_SHARED_LIBRARIES += libyuv.vendor
+LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam.plugin.tp_watermark
+endif
+
+ifeq ($(QXT_MFNR_SUPPORT), yes)
+LOCAL_SHARED_LIBRARIES += libmultiframe
+LOCAL_SHARED_LIBRARIES += libyuv.vendor
+LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam.plugin.tp_mfnr
+endif
+
#
LOCAL_SHARED_LIBRARIES += libfeature.stereo.provider
#
预置水印文件
device/mediateksample/k62v1_64_bsp/device.mk
+++ b/alps/device/mediateksample/k62v1_64_bsp/device.mk
@@ -43,6 +43,9 @@ endif
PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.usb.host.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.host.xml
+ifeq ($(QXT_WATERMARK_SUPPORT),yes)
+PRODUCT_COPY_FILES += vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/customer/tp_watermark/res/watermark.rgba::$(TARGET_COPY_OUT_VENDOR)/res/images/watermark.rgba
+endif
camera hal进程为mtk_camera_hal,它要读取/vendor/res/images/watermark.rgba,读取需要vendor_file SELinux权限。这里为mtk_camera_hal配置SELinux权限:
device/mediatek/sepolicy/bsp/non_plat/mtk_hal_camera.te
@@ -93,7 +93,7 @@ set_prop(mtk_hal_camera, vendor_mtk_camera_prop)
allow mtk_hal_camera teei_client_device:chr_file rw_file_perms;
allow mtk_hal_camera mdla_device:chr_file rw_file_perms;
-
+allow mtk_hal_camera vendor_file:file { read getattr open };
#Date: 2019/11/11
移除MTK示例的MFNR算法
一般情况下,MFNR 算法同一时间只允许运行一个。因此,需要移除 MTK 示例的 MFNR 算法。我们可以使用宏控来移除,这里就简单粗暴,直接注释掉了。
vendor/mediatek/proprietary/hardware/mtkcam3/3rdparty/mtk/Android.mk
@@ -146,7 +146,7 @@ LOCAL_SHARED_LIBRARIES += libfeature.stereo.provider
LOCAL_SHARED_LIBRARIES += liblpcnr
#-----------------------------------------------------------
ifneq ($(strip $(MTKCAM_HAVE_MFB_SUPPORT)),0)
-LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam.plugin.mfnr
+# LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam.plugin.mfnr
endif
#4 Cell
LOCAL_WHOLE_STATIC_LIBRARIES += libmtkcam.plugin.remosaic
自定义metadata
添加metadata是为了让APP层能够通过metadata传递相应的参数给HAL层。APP层是通过CaptureRequest.Builder.set(@NonNull Key key, T value)来设置参数的。 由于我们是自定义的feature,无法复用MTK提供的metadata,因此,我们需要自定义metadata。
vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/metadata/client/mtk_metadata_tag.h
@@ -94,6 +94,7 @@ typedef enum mtk_camera_metadata_section {
MTK_SMVR_FEATURE = 15,
MTK_SINGLEHW_SETTING = 16,
MTK_ABF_FEATURE = 17,
+ QXT_FEATURE = 18,//cczheng
MTK_VENDOR_SECTION_COUNT,
} mtk_camera_metadata_section_t;
@@ -155,6 +156,7 @@ typedef enum mtk_camera_metadata_section_start {
MTK_SMVR_FEATURE_START = (MTK_SMVR_FEATURE + MTK_VENDOR_TAG_SECTION) << 16,
MTK_SINGLEHW_SETTING_START = (MTK_SINGLEHW_SETTING + MTK_VENDOR_TAG_SECTION) << 16,
MTK_ABF_FEATURE_START = (MTK_ABF_FEATURE + MTK_VENDOR_TAG_SECTION) << 16,
+ QXT_FEATURE_START = (QXT_FEATURE + MTK_VENDOR_TAG_SECTION) << 16,//cczheng
} mtk_camera_metadata_section_start_t;
@@ -754,6 +756,10 @@ typedef enum mtk_camera_metadata_tag {
MTK_ABF_FEATURE_ABF_RESULT,
MTK_ABF_FEATURE_AVAILABLE_ABF_MODES,
MTK_ABF_FEATURE_END,
+
+ QXT_FEATURE_WATERMARK = QXT_FEATURE_START,
+ QXT_FEATURE_MFNR,//cczheng
+ QXT_FEATURE_END,//cczheng
} mtk_camera_metadata_tag_t;
/**
vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/metadata/client/mtk_metadata_tag_info.inl
@@ -92,6 +92,8 @@ _IMP_SECTION_INFO_(MTK_HEIC, "mtk.heic")
_IMP_SECTION_INFO_(MTK_HEIC_INFO, "mtk.heic.ifno")
_IMP_SECTION_INFO_(MTK_IOPIPE_INFO, "mtk.iopipe.info")
_IMP_SECTION_INFO_(MTK_HAL_INFO, "mtk.hal.info")
+_IMP_SECTION_INFO_(QXT_FEATURE, "com.qxt.camera")
+//cczheng
/******************************************************************************
*
@@ -106,6 +108,12 @@ _IMP_TAG_INFO_( MTK_COLOR_CORRECTION_ABERRATION_MODE,
MUINT8, "aberrationMode")
_IMP_TAG_INFO_( MTK_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
MUINT8, "availableAberrationModes")
+
+_IMP_TAG_INFO_( QXT_FEATURE_WATERMARK,
+ MINT32, "watermark")
+_IMP_TAG_INFO_( QXT_FEATURE_MFNR,
+ MINT32, "mfnr")
+
//
_IMP_TAG_INFO_( MTK_CONTROL_AE_ANTIBANDING_MODE,
MUINT8, "aeAntibandingMode")
vendor/mediatek/proprietary/hardware/mtkcam/utils/metadata/vendortag/VendorTagTable.h
@@ -547,6 +547,19 @@ static auto& _FlashFeature_()
//
return sInst;
}
+//cczheng
+static auto& _QxtFeature_()
+{
+ static const std::map<uint32_t, VendorTag_t>
+ sInst = {
+ _TAG_(QXT_FEATURE_WATERMARK,
+ "watermark", TYPE_INT32),
+ _TAG_(QXT_FEATURE_MFNR,
+ "mfnr", TYPE_INT32),
+ };
+ //
+ return sInst;
+}
static auto& _SingleHWSetting_()
{
@@ -668,6 +681,10 @@ static auto& getGlobalSections()
MTK_ABF_FEATURE_START,
MTK_ABF_FEATURE_END,
_ABFFeature_() ),
+ _SECTION_( "com.qxt.camera",
+ QXT_FEATURE_START,
+ QXT_FEATURE_END,
+ _QxtFeature_() ),
};
// append custom vendor tags sections to mtk sections
vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/metadataprovider/constructStaticMetadata.cpp
@@ -1325,6 +1325,20 @@ updateData(IMetadata &rMetadata)
rMetadata.update(availReqEntry.tag(), availReqEntry);
}
+//cczheng
+#if 1
+ {
+ IMetadata::IEntry qxtAvailRequestEntry = rMetadata.entryFor(MTK_REQUEST_AVAILABLE_REQUEST_KEYS);
+ qxtAvailRequestEntry.push_back(QXT_FEATURE_WATERMARK , Type2Type< MINT32 >());
+ qxtAvailRequestEntry.push_back(QXT_FEATURE_MFNR , Type2Type< MINT32 >());
+ rMetadata.update(qxtAvailRequestEntry.tag(), qxtAvailRequestEntry);
+
+ IMetadata::IEntry qxtAvailSessionEntry = rMetadata.entryFor(MTK_REQUEST_AVAILABLE_SESSION_KEYS);
+ qxtAvailSessionEntry.push_back(QXT_FEATURE_WATERMARK , Type2Type< MINT32 >());
+ qxtAvailSessionEntry.push_back(QXT_FEATURE_MFNR , Type2Type< MINT32 >());
+ rMetadata.update(qxtAvailSessionEntry.tag(), qxtAvailSessionEntry);
+ }
+#endif
+
// update multi-cam feature mode to static metadata
// vendor tag
{
好了,搞到这一步。大功告成了,先 make 一把,刷机看效果
最后
由于 watermark.rgba 没找到源文件,我从其它地方搞了个所以水印显示时宽高不太对,就没正确显示,具体效果我没仔细调整。
另外既然系统已经预制了这两个算法,所有 app 均可调用,那么可以在系统相机中也增加两按钮,加载这两算法,也算是丰富了
原始相机单一风格,有兴趣的朋友可以自己去加下,毕竟普通 app 的代码已经提供了。