Camera Hal OEM模块 ---- 3dnr算法流程

3dnr,即 多帧降噪,在暗环境下拍照,会触发此算法。
其设计思想是通过5张图片叠加去跑降噪算法,从而实现暗环境下拍照优化噪点。

我们之前介绍了 hal3_2v6 的内容,hal3_2v6是整个libcamera中最接近上层的部分,主要是管理参数、处理camera的公共操作(open、close)等。相当于是对camera参数及操作请求的上层解析及底层封装。
我们还介绍了位于hal_common\multiCamera下的SprdCamera3SinglePortrait.cpp,即人像模式算法的流程。hal_common\multiCamera 下面还有其他multiCamera的算法,比如双摄虚化,人脸解锁等等。

oem2V6 下面有预览、拍照的公共流程:cmr_preview.c、 cmr_snapshot.c,也有展锐平台自带的算法,比如人脸识别相关的 cmr_fd_sprd.c,hdr算法 cmr_hdr.c,以及我们本篇要讲的降噪算法的流程 cmr_3dnr_sw.c。

大家可能会有一个疑问,似乎 hal_common 和 oem2v6 下面都有关于算法的实现。那么两者主要有什么区别呢?

如果一定要说下区别的话,最明显的应该就是 hal_common 下的实现是cpp,而 oem2v6 下的实现是 c 文件,并且oem2v6 下面偏向的是camera基本的功能流程:预览、拍照、人脸识别、场景识别等等。hal_common 是要使用到 oem2v6 的内容的,比如 人像模式,人像模式支持美颜,那么美颜就肯定跑不了人脸识别功能,而人脸识别是在 oem2v6 下面的。

关于 hal_common 和 oem2v6 区别与关联,我的理解可能不够全面,欢迎大家的补充。

言归正传,回到我们本篇要介绍的 3dnr 算法上。

cmr_3dnr_sw.c 的内容并不多,2000来行。

函数声明

看一下文件顶部的函数声明

static cmr_int threednr_open(cmr_handle ipm_handle, struct ipm_open_in *in,struct ipm_open_out *out, cmr_handle *class_handle);
static cmr_int threednr_close(cmr_handle class_handle);
static cmr_int threednr_transfer_frame(cmr_handle class_handle,struct ipm_frame_in *in,struct ipm_frame_out *out);

static cmr_int threednr_open_prev(cmr_handle ipm_handle, struct ipm_open_in *in,struct ipm_open_out *out,cmr_handle *class_handle);
static cmr_int threednr_close_prev(cmr_handle class_handle);
static cmr_int threednr_transfer_prev_frame(cmr_handle class_handle,struct ipm_frame_in *in,struct ipm_frame_out *out);

可以看到是比较对称的 不带prev 和 带prev 的3个流程。不带prev的应该就是拍照的时候跑的,带prev的显然就是预览的时候跑的。按照之前的经验,3dnr是比较耗时的,我们一般是不在预览跑的,只在拍照阶段去跑。所以我们要关注上面那个函数。

threednr_open

1,申请 CAMERA_SNAPSHOT_3DNR 的空间
ret = cam_cxt->hal_malloc(
            CAMERA_SNAPSHOT_3DNR, &small_buf_size, &small_buf_num,
            (cmr_uint *)threednr_handle->small_buf_phy,
            (cmr_uint *)threednr_handle->small_buf_vir,
            threednr_handle->small_buf_fd, cam_cxt->client_data);
2,获取效果参数
    cmr_u32 param_3dnr_index = 0;
    sensor_id = ipm_cxt->init_in.sensor_id;
    param_3dnr_index = threednr_get_sns_match_index(sensor_id);
    cap_3dnr_param = sns_3dnr_param_tab[param_3dnr_index].cap_param;

threednr_get_sns_match_index 的实现在 sw_3dnr_param.h

const struct threednr_sns_match_tab sns_3dnr_param_tab[] = {
    {"default", &prev_default_3dnr_param, &cap_default_3dnr_param},
#ifdef OV13855
    {"ov13855", &ov13855_prev_3dnr_param, &ov13855_cap_3dnr_param},
#endif
#ifdef OV8856_SHINE
    {"ov8856_shine", &ov8856_shine_prev_3dnr_param, &ov8856_shine_cap_3dnr_param},
#endif
#ifdef OV5675
    {"ov5675", &ov5675_prev_3dnr_param, &ov5675_cap_3dnr_param},
#endif
    {"null", NULL, NULL}
};

本项目配置是 ov13855,对应的参数如下

#ifdef OV13855
static struct threednr_tuning_param ov13855_prev_3dnr_param = {
    {{0, 2, 2, 4, 9, 9}, {0, 1, 3, 5, 9, 9}, {0, 1, 3, 5, 9, 9}, {0, 1, 4, 6, 9, 9}},
    {{255, 5, 5, 6, 9, 9}, {255, 5, 5, 6, 9, 9}, {255, 5, 5, 6, 9, 9}, {255, 4, 5, 5, 9, 9}},
    {12, 24, 36, 64, 80, 96}, 11, 11, 1, 0, 12, 100, 5, 588, 435, {1,3,247,3342362,6684749,10027136,13369523,16711910}
};
static struct threednr_tuning_param ov13855_cap_3dnr_param = {
    {{3, 4, 6, 9, 9, 9}, {3, 5, 6, 9, 9, 9}, {3, 5, 6, 9, 9, 9}, {2, 6, 7, 9, 9, 9}},
    {{5, 6, 7, 9, 9, 9}, {5, 6, 7, 9, 9, 9}, {5, 6, 7, 9, 9, 9}, {5, 6, 6, 9, 9, 9}},
    {12, 24, 36, 64, 80, 96}, 11, 11, -1, 0, 12, 100, 6, 588, 435, {0}
};
#endif
3,赋值给 cap_3dnr_tuning_param
    cap_3dnr_tuning_param.SearchWindow_x = cap_3dnr_param->searchWindow_x;
    cap_3dnr_tuning_param.SearchWindow_y = cap_3dnr_param->searchWindow_y;
    cap_3dnr_tuning_param.threthold = cap_3dnr_param->threshold;
    cap_3dnr_tuning_param.slope = cap_3dnr_param->slope;
    cap_3dnr_tuning_param.recur_str = cap_3dnr_param->recur_str;
    cap_3dnr_tuning_param.match_ratio_sad = cap_3dnr_param->match_ratio_sad;
    cap_3dnr_tuning_param.match_ratio_pro = cap_3dnr_param->match_ratio_pro;
    cap_3dnr_tuning_param.feat_thr = cap_3dnr_param->feat_thr;
    cap_3dnr_tuning_param.luma_ratio_high = cap_3dnr_param->luma_ratio_high;
    cap_3dnr_tuning_param.luma_ratio_low = cap_3dnr_param->luma_ratio_low;
    cap_3dnr_tuning_param.zone_size = cap_3dnr_param->zone_size;
    memcpy(cap_3dnr_tuning_param.gain_thr, cap_3dnr_param->gain_thr, (6 * sizeof(int)));
    memcpy(cap_3dnr_tuning_param.reserved, cap_3dnr_param->reserverd, (16 * sizeof(int)));
4,通过 isp 获取参数
ret = ipm_in->ipm_isp_ioctl(oem_handle, COM_ISP_GET_MFNR_PARAM,&isp_cmd_parm);
5,在次赋值给 cap_3dnr_tuning_param
  cap_3dnr_tuning_param.SearchWindow_x = isp_cmd_parm.mfnr_param.searchWindow_x;
  cap_3dnr_tuning_param.SearchWindow_y = isp_cmd_parm.mfnr_param.searchWindow_y;
  cap_3dnr_tuning_param.recur_str = isp_cmd_parm.mfnr_param.recur_str;
  cap_3dnr_tuning_param.match_ratio_sad = isp_cmd_parm.mfnr_param.match_ratio_sad;
  cap_3dnr_tuning_param.match_ratio_pro = isp_cmd_parm.mfnr_param.match_ratio_pro;
  cap_3dnr_tuning_param.feat_thr = isp_cmd_parm.mfnr_param.feat_thr;
  cap_3dnr_tuning_param.luma_ratio_high = isp_cmd_parm.mfnr_param.luma_ratio_high;
  cap_3dnr_tuning_param.luma_ratio_low = isp_cmd_parm.mfnr_param.luma_ratio_low;
  cap_3dnr_tuning_param.zone_size = isp_cmd_parm.mfnr_param.zone_size;
  memcpy(cap_3dnr_tuning_param.reserved, isp_cmd_parm.mfnr_param.reserverd,(16 * sizeof(int)));
6,跑 sprd_mfnr_adpt_init
ret = sprd_mfnr_adpt_init((void **)&(threednr_handle->proc_handle),  &param, (void *)(&cap_3dnr_tuning_param));

7,在次获取 isp 参数,并赋值给 process_param
ret = ipm_in->ipm_isp_ioctl(oem_handle, COM_ISP_GET_MFNR_PARAM, &isp_cmd_parm);
memcpy(process_param.proc_param.setpara_param.thr, isp_cmd_parm.mfnr_param.threshold, (4*sizeof(int)));
memcpy(process_param.proc_param.setpara_param.slp, isp_cmd_parm.mfnr_param.slope, (4 * sizeof(int)));
8,跑 sprd_mfnr_adpt_ctrl

传入上一步的参数

ret = sprd_mfnr_adpt_ctrl((void *)(threednr_handle->proc_handle), SPRD_MFNR_PROC_SET_PARAMS_CMD, (void *)&process_param);

threednr_close

1,sprd_mfnr_adpt_deinit
ret = sprd_mfnr_adpt_deinit((void **)&(threednr_handle->proc_handle));
2,释放 CAMERA_SNAPSHOT_3DNR 空间
ret = cam_cxt->hal_free(
            CAMERA_SNAPSHOT_3DNR, (cmr_uint *)threednr_handle->small_buf_phy,
            (cmr_uint *)threednr_handle->small_buf_vir,
            threednr_handle->small_buf_fd, CAP_3DNR_NUM, cam_cxt->client_data);

open 与 close 的动作是相对的。

再来看 threednr_transfer_frame

threednr_transfer_frame 流程

threednr_transfer_frame 的逻辑涉及到一个调用流程,我们先直接把这个调用流程给出来。
在这里插入图片描述

1,threednr_transfer_frame 保存参数 in、out

保存参数 in、out 到 threednr_handle->g_info_3dnr[cur_num],然后调用 threadnr_scaler_process

	static cmr_int threednr_transfer_frame(cmr_handle class_handle,
					struct ipm_frame_in *in,struct ipm_frame_out *out) 
	
    if (threednr_handle->g_totalnum < CAP_3DNR_NUM) {
        threednr_handle->g_info_3dnr[cur_num].class_handle = class_handle;
        memcpy(&threednr_handle->g_info_3dnr[cur_num].in, in,
               sizeof(struct ipm_frame_in));
        memcpy(&threednr_handle->g_info_3dnr[cur_num].out, out,
               sizeof(struct ipm_frame_out));
        threednr_handle->g_info_3dnr[cur_num].cur_frame_num = cur_num;
        CMR_LOGD("fd 0x%x yaddr 0x%x", in->src_frame.fd, in->src_frame.addr_vir.addr_y);
        ret = req_3dnr_scaler_frame(threednr_handle,
                                    &threednr_handle->g_info_3dnr[cur_num]);
        if (ret) {
            CMR_LOGE("failed to sensor scaler frame");
        }
    } 
2,threadnr_scaler_process

src — in 参数
dst — threednr_handle->small_buf_phy,在 threednr_open 中通过 cam_cxt->hal_malloc 申请的

   src = &in->src_frame;
   src->addr_vir.addr_u = in->src_frame.addr_vir.addr_y + threednr_handle->width * threednr_handle->height;
   src->addr_vir.addr_v = src->addr_vir.addr_u;
   src->addr_phy.addr_u = in->src_frame.addr_phy.addr_y + threednr_handle->width * threednr_handle->height;
   src->addr_phy.addr_v = src->addr_vir.addr_u;

   dst.addr_phy.addr_y = threednr_handle->small_buf_phy[cur_frm];
   dst.addr_phy.addr_u = dst.addr_phy.addr_y + threednr_handle->small_width * threednr_handle->small_height;
   dst.addr_phy.addr_v = dst.addr_phy.addr_u;
   dst.addr_vir.addr_y = threednr_handle->small_buf_vir[cur_frm];
   dst.addr_vir.addr_u = dst.addr_vir.addr_y + threednr_handle->small_width * threednr_handle->small_height;
   dst.addr_vir.addr_v = dst.addr_vir.addr_u;
   dst.fd = threednr_handle->small_buf_fd[cur_frm];
//执行 scale
ret = threednr_start_scale(oem_handle, src, &dst);
3,threednr_process_frame 流程
3.1 构建 orig_image

使用 in 参数的地址

 orig_image.gpuHandle = out->private_data;
 orig_image.bufferY = (unsigned char *)in->src_frame.addr_vir.addr_y;
 orig_image.bufferU = orig_image.bufferY + threednr_handle->width * threednr_handle->height;
 orig_image.bufferV = orig_image.bufferU;
3.2 构建 small_image

使用 threednr_handle->small_buf_vir,即在 threednr_open 中通过 cam_cxt->hal_malloc 申请的,并且在 threadnr_scaler_process 中 作为scale的dst

small_image.cpu_buffer.bufferY = (unsigned char *)threednr_handle->small_buf_vir[cur_frm];
small_image.cpu_buffer.bufferU = small_image.cpu_buffer.bufferY + threednr_handle->small_width * threednr_handle->small_height;
small_image.cpu_buffer.bufferV = small_image.cpu_buffer.bufferU;
small_image.cpu_buffer.fd = threednr_handle->small_buf_fd[cur_frm];
3.3 构建 process_param

使用上面的 small_image 和 orig_image

process_param.proc_param.cap_new_param.small_image = &small_image;
process_param.proc_param.cap_new_param.orig_image = &orig_image;
process_param.callWay = 1;
3.4 跑 sprd_mfnr_adpt_ctrl

SPRD_MFNR_PROC_CAPTURE_CMD 是去执行降噪算法的指令,之前所有的准备工作都是为了这步

ret = sprd_mfnr_adpt_ctrl(threednr_handle->proc_handle, SPRD_MFNR_PROC_CAPTURE_CMD, (void *)&process_param);

到这里,3dnr的算法流程已经全部走完了,我们通过一个实际暗环境拍照的log来巩固下这个流程
open:

Line 292277: 06-03 17:36:53.171   467  7763 D cmr_3dnr_sw: 396, threednr_open: E
Line 292289: 06-03 17:36:53.174   467  7763 D cmr_3dnr_sw: 478, threednr_open: OK to malloc buffers for small image
Line 292290: 06-03 17:36:53.174   467  7763 D cmr_3dnr_sw: 501, threednr_open: af_roi: x=1314, y=1065, w=1430, h=987
Line 292291: 06-03 17:36:53.174   467  7763 D cmr_3dnr_sw: 128, threednr_get_sns_match_index: sensor 3dnr param sum is 1
Line 292292: 06-03 17:36:53.174   467  7763 D cmr_3dnr_sw: 550, threednr_open: auto3dnr_flag 2 sprd_3dnr_type 8 sensor_id 0 index 0 search window 11x11 threthold[3][2] 7
Line 292341: 06-03 17:36:53.177   467  7763 D cmr_3dnr_sw: 611, threednr_open: ok to call threednr_init
Line 292347: 06-03 17:36:53.177   467  7763 D cmr_3dnr_sw: 639, threednr_open: X

处理第一帧

Line 292556: 06-03 17:36:53.285   467  7763 D cmr_3dnr_sw: 1929, threednr_transfer_frame: get one frame, num 0, 0
Line 292557: 06-03 17:36:53.285   467  7763 D cmr_3dnr_sw: 1937, threednr_transfer_frame: fd 0x1e yaddr 0xdc6c3000
Line 292559: 06-03 17:36:53.285   467  7999 D cmr_3dnr_sw: 1030, threadnr_scaler_process: fd 0x1e E. yaddr 0x dc6c3000 cur_frm: 0
Line 292562: 06-03 17:36:53.285   467  7999 D cmr_3dnr_sw: 1074, threadnr_scaler_process: Call the threednr_start_scale().src Y: 0xdc6c3000, 0x1e, dst Y: 0xd256a000, 0x81
Line 292671: 06-03 17:36:53.379   467  7998 D cmr_3dnr_sw: 957, threednr_process_thread_proc: CMR_EVT_3DNR_PROCESS
Line 292672: 06-03 17:36:53.379   467  7999 D cmr_3dnr_sw: 1124, threadnr_scaler_process: X cur_frm: 0
Line 292673: 06-03 17:36:53.380   467  7998 D cmr_3dnr_sw: 831, threednr_process_frame: Call the threednr_function() yaddr 0xdc6c3000 cur_frm: 0 run_type 0 sprd_3dnr_type 8
Line 292674: 06-03 17:36:53.380   467  7998 D cmr_3dnr_sw: 872, threednr_process_frame: Call the threednr_function().big Y: 0xdc6c3000, small 0xd256a000. ,threednr_handle->is_stop 0
Line 292675: 06-03 17:36:53.380   467  7998 D cmr_3dnr_sw: 879, threednr_process_frame: big_buf.fd=0x1e, vaddr=0xdc6c3000, gpu_buffer.handle 0xe5682530

处理第二帧

Line 292701: 06-03 17:36:53.390   467  7763 D cmr_3dnr_sw: 1929, threednr_transfer_frame: get one frame, num 1, 1
Line 292702: 06-03 17:36:53.390   467  7763 D cmr_3dnr_sw: 1937, threednr_transfer_frame: fd 0x23 yaddr 0xdb431000
Line 292703: 06-03 17:36:53.390   467  7999 D cmr_3dnr_sw: 1030, threadnr_scaler_process: fd 0x23 E. yaddr 0x db431000 cur_frm: 1
Line 292704: 06-03 17:36:53.390   467  7999 D cmr_3dnr_sw: 1074, threadnr_scaler_process: Call the threednr_start_scale().src Y: 0xdb431000, 0x23, dst Y: 0xd23a8000, 0x83
Line 292821: 06-03 17:36:53.487   467  7998 D cmr_3dnr_sw: 957, threednr_process_thread_proc: CMR_EVT_3DNR_PROCESS
Line 292822: 06-03 17:36:53.488   467  7999 D cmr_3dnr_sw: 1124, threadnr_scaler_process: X cur_frm: 1
Line 292823: 06-03 17:36:53.488   467  7998 D cmr_3dnr_sw: 831, threednr_process_frame: Call the threednr_function() yaddr 0xdb431000 cur_frm: 1 run_type 0 sprd_3dnr_type 8
Line 292824: 06-03 17:36:53.488   467  7998 D cmr_3dnr_sw: 872, threednr_process_frame: Call the threednr_function().big Y: 0xdb431000, small 0xd23a8000. ,threednr_handle->is_stop 0
Line 292825: 06-03 17:36:53.488   467  7998 D cmr_3dnr_sw: 879, threednr_process_frame: big_buf.fd=0x23, vaddr=0xdb431000, gpu_buffer.handle 0xe56832f0

处理第三帧

Line 292840: 06-03 17:36:53.495   467  7763 D cmr_3dnr_sw: 1929, threednr_transfer_frame: get one frame, num 2, 2
Line 292841: 06-03 17:36:53.495   467  7763 D cmr_3dnr_sw: 1937, threednr_transfer_frame: fd 0x28 yaddr 0xda19f000
Line 292842: 06-03 17:36:53.496   467  7999 D cmr_3dnr_sw: 1030, threadnr_scaler_process: fd 0x28 E. yaddr 0x da19f000 cur_frm: 2
Line 292843: 06-03 17:36:53.496   467  7999 D cmr_3dnr_sw: 1074, threadnr_scaler_process: Call the threednr_start_scale().src Y: 0xda19f000, 0x28, dst Y: 0xd21e6000, 0x85
Line 292961: 06-03 17:36:53.592   467  7998 D cmr_3dnr_sw: 957, threednr_process_thread_proc: CMR_EVT_3DNR_PROCESS
Line 292962: 06-03 17:36:53.592   467  7999 D cmr_3dnr_sw: 1124, threadnr_scaler_process: X cur_frm: 2
Line 292963: 06-03 17:36:53.592   467  7998 D cmr_3dnr_sw: 831, threednr_process_frame: Call the threednr_function() yaddr 0xda19f000 cur_frm: 2 run_type 0 sprd_3dnr_type 8
Line 292964: 06-03 17:36:53.592   467  7998 D cmr_3dnr_sw: 872, threednr_process_frame: Call the threednr_function().big Y: 0xda19f000, small 0xd21e6000. ,threednr_handle->is_stop 0
Line 292965: 06-03 17:36:53.592   467  7998 D cmr_3dnr_sw: 879, threednr_process_frame: big_buf.fd=0x28, vaddr=0xda19f000, gpu_buffer.handle 0xe5683a80

处理第四帧


Line 292981: 06-03 17:36:53.601   467  7763 D cmr_3dnr_sw: 1929, threednr_transfer_frame: get one frame, num 3, 3
Line 292982: 06-03 17:36:53.601   467  7763 D cmr_3dnr_sw: 1937, threednr_transfer_frame: fd 0x2d yaddr 0xd8f0d000
Line 292983: 06-03 17:36:53.601   467  7999 D cmr_3dnr_sw: 1030, threadnr_scaler_process: fd 0x2d E. yaddr 0x d8f0d000 cur_frm: 3
Line 292985: 06-03 17:36:53.601   467  7999 D cmr_3dnr_sw: 1074, threadnr_scaler_process: Call the threednr_start_scale().src Y: 0xd8f0d000, 0x2d, dst Y: 0xd2024000, 0x87
Line 293115: 06-03 17:36:53.697   467  7998 D cmr_3dnr_sw: 957, threednr_process_thread_proc: CMR_EVT_3DNR_PROCESS
Line 293116: 06-03 17:36:53.697   467  7998 D cmr_3dnr_sw: 831, threednr_process_frame: Call the threednr_function() yaddr 0xd8f0d000 cur_frm: 3 run_type 0 sprd_3dnr_type 8
Line 293117: 06-03 17:36:53.697   467  7998 D cmr_3dnr_sw: 872, threednr_process_frame: Call the threednr_function().big Y: 0xd8f0d000, small 0xd2024000. ,threednr_handle->is_stop 0
Line 293118: 06-03 17:36:53.698   467  7998 D cmr_3dnr_sw: 879, threednr_process_frame: big_buf.fd=0x2d, vaddr=0xd8f0d000, gpu_buffer.handle 0xe56839d0
Line 293119: 06-03 17:36:53.697   467  7999 D cmr_3dnr_sw: 1124, threadnr_scaler_process: X cur_frm: 3

处理第五帧

Line 293140: 06-03 17:36:53.708   467  7763 D cmr_3dnr_sw: 1929, threednr_transfer_frame: get one frame, num 4, 4
Line 293141: 06-03 17:36:53.708   467  7763 D cmr_3dnr_sw: 1937, threednr_transfer_frame: fd 0x32 yaddr 0xd7c7b000
Line 293145: 06-03 17:36:53.708   467  7999 D cmr_3dnr_sw: 1030, threadnr_scaler_process: fd 0x32 E. yaddr 0x d7c7b000 cur_frm: 4
Line 293146: 06-03 17:36:53.708   467  7999 D cmr_3dnr_sw: 1074, threadnr_scaler_process: Call the threednr_start_scale().src Y: 0xd7c7b000, 0x32, dst Y: 0xd1e62000, 0x89
Line 293235: 06-03 17:36:53.803   467  7998 D cmr_3dnr_sw: 957, threednr_process_thread_proc: CMR_EVT_3DNR_PROCESS
Line 293236: 06-03 17:36:53.803   467  7999 D cmr_3dnr_sw: 1124, threadnr_scaler_process: X cur_frm: 4
Line 293237: 06-03 17:36:53.803   467  7998 D cmr_3dnr_sw: 831, threednr_process_frame: Call the threednr_function() yaddr 0xd7c7b000 cur_frm: 4 run_type 0 sprd_3dnr_type 8
Line 293238: 06-03 17:36:53.803   467  7998 D cmr_3dnr_sw: 872, threednr_process_frame: Call the threednr_function().big Y: 0xd7c7b000, small 0xd1e62000. ,threednr_handle->is_stop 0
Line 293239: 06-03 17:36:53.803   467  7998 D cmr_3dnr_sw: 879, threednr_process_frame: big_buf.fd=0x32, vaddr=0xd7c7b000, gpu_buffer.handle 0xe5683240

Line 294093: 06-03 17:36:54.571   467  7998 D cmr_3dnr_sw: 913, threednr_process_frame: cur_frame 4
Line 294094: 06-03 17:36:54.571   467  7998 D cmr_3dnr_sw: 923, threednr_process_frame: 3dnr process done, addr 0x0   4160 3120

close:

Line 294906: 06-03 17:36:54.992   467  7740 D cmr_3dnr_sw: 657, threednr_close: E
Line 294907: 06-03 17:36:54.992   467  7740 D cmr_3dnr_sw: 662, threednr_close: OK to threednr_cancel
Line 294984: 06-03 17:36:55.034   467  7740 D cmr_3dnr_sw: 697, threednr_close: X

可以看到,log的流程与我们上述跟踪的代码流程是一致的。

关于 3dnr算法的流程,就介绍到这里,本系列后面会持续介绍oem2v6下面的其它算法流程。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值