void *svt_aom_motion_estimation_kernel(void *input_ptr) // 运动估计内核主函数,接收线程输入参数

{

// 从输入参数中获取线程上下文指针

EbThreadContext * thread_ctx = (EbThreadContext *)input_ptr;

// 从线程上下文中获取运动估计上下文指针

MotionEstimationContext_t *me_context_ptr = (MotionEstimationContext_t *)thread_ctx->priv;

// 输入结果包装器指针,用于接收来自上游的数据

EbObjectWrapper * in_results_wrapper_ptr;

// 输出结果包装器指针,用于向下游传递处理结果

EbObjectWrapper * out_results_wrapper;

for (;;) { // 无限循环,持续处理输入的图片数据

// 从输入FIFO队列中获取完整的图片决策结果对象

EB_GET_FULL_OBJECT(me_context_ptr->picture_decision_results_input_fifo_ptr,

&in_results_wrapper_ptr);

// 从包装器中提取图片决策结果指针

PictureDecisionResults *in_results_ptr = (PictureDecisionResults *)

in_results_wrapper_ptr->object_ptr;

// 从输入结果中获取图片父控制集指针,包含当前图片的所有控制信息

PictureParentControlSet *pcs = (PictureParentControlSet *)

in_results_ptr->pcs_wrapper->object_ptr;

// 获取序列控制集指针,包含编码序列的全局配置参数

SequenceControlSet *scs = pcs->scs;

// 根据输入任务类型设置相应的运动估计类型

if (in_results_ptr->task_type == TASK_TFME)

// 如果是时域滤波运动估计任务,设置为MCTF模式

me_context_ptr->me_ctx->me_type = ME_MCTF;

else if (in_results_ptr->task_type == TASK_PAME || in_results_ptr->task_type == TASK_SUPERRES_RE_ME)

// 如果是预分析运动估计或超分辨率重新运动估计任务,设置为开环模式

me_context_ptr->me_ctx->me_type = ME_OPEN_LOOP;

else if (in_results_ptr->task_type == TASK_DG_DETECTOR_HME)

// 如果是动态GOP检测分层运动估计任务,设置为检测器模式

me_context_ptr->me_ctx->me_type = ME_DG_DETECTOR;

// 运动估计内核信号推导:根据任务类型设置具体的ME参数

if ((in_results_ptr->task_type == TASK_PAME) ||

(in_results_ptr->task_type == TASK_SUPERRES_RE_ME))

// 对于预分析或超分辨率重新ME任务,推导标准运动估计信号

svt_aom_sig_deriv_me(scs, pcs, me_context_ptr->me_ctx);

else if (in_results_ptr->task_type == TASK_TFME)

// 对于时域滤波任务,推导特定的时域滤波运动估计信号

svt_aom_sig_deriv_me_tf(pcs, me_context_ptr->me_ctx);

// 处理预分析运动估计和超分辨率重新运动估计任务

if ((in_results_ptr->task_type == TASK_PAME) ||

(in_results_ptr->task_type == TASK_SUPERRES_RE_ME)) {

// 1/16分辨率图片缓冲区指针,用于粗粒度运动搜索

EbPictureBufferDesc *sixteenth_picture_ptr;

// 1/4分辨率图片缓冲区指针,用于中等粒度运动搜索

EbPictureBufferDesc *quarter_picture_ptr;

// 填充后的输入图片缓冲区指针,用于边界处理

EbPictureBufferDesc *input_padded_pic;

// 原始输入图片缓冲区指针

EbPictureBufferDesc *input_pic;

// 预分析引用对象指针,包含各种分辨率的图片数据

EbPaReferenceObject *pa_ref_obj_;

// 断言检查引用图片的生命周期计数 (调试版本使用)

//assert((int)pcs->pa_ref_pic_wrapper->live_count > 0);

// 从图片控制集中获取预分析引用对象

pa_ref_obj_ = (EbPaReferenceObject *)

pcs->pa_ref_pic_wrapper->object_ptr;

// 设置1/4和1/16分辨率的ME输入缓冲区,已经过滤或抽取

// 获取1/4分辨率下采样图片指针,用于分层运动估计的中层

quarter_picture_ptr = (EbPictureBufferDesc *)

pa_ref_obj_->quarter_downsampled_picture_ptr;

// 获取1/16分辨率下采样图片指针,用于分层运动估计的最粗层

sixteenth_picture_ptr = (EbPictureBufferDesc *)

pa_ref_obj_->sixteenth_downsampled_picture_ptr;

// 获取填充后的输入图片,确保边界像素可用于运动搜索

input_padded_pic = (EbPictureBufferDesc *)pa_ref_obj_->input_padded_pic;

// 获取增强后的输入图片,通常是经过预处理的原始图片

input_pic = pcs->enhanced_pic;

// 图片分段处理:将图片划分为多个段以支持并行处理

// 获取当前处理的段索引

uint32_t segment_index = in_results_ptr->segment_index;

// 计算图片宽度包含的64x64块数量(向上取整)

uint32_t pic_width_in_b64 = (pcs->aligned_width + scs->b64_size - 1) / scs->b64_size;

// 计算图片高度包含的64x64块数量(向上取整)

uint32_t picture_height_in_b64 = (pcs->aligned_height + scs->b64_size - 1) / scs->b64_size;

// Y方向段索引

uint32_t y_segment_index;

// X方向段索引

uint32_t x_segment_index;

// 将一维段索引转换为二维坐标(x,y)

SEGMENT_CONVERT_IDX_TO_XY(segment_index, x_segment_index, y_segment_index, pcs->me_segments_column_count);

// 计算当前段在X方向的起始64x64块索引

uint32_t x_b64_start_index = SEGMENT_START_IDX(x_segment_index, pic_width_in_b64, pcs->me_segments_column_count);

// 计算当前段在X方向的结束64x64块索引

uint32_t x_b64_end_index = SEGMENT_END_IDX(x_segment_index, pic_width_in_b64, pcs->me_segments_column_count);

// 计算当前段在Y方向的起始64x64块索引

uint32_t y_b64_start_index = SEGMENT_START_IDX(y_segment_index, picture_height_in_b64, pcs->me_segments_row_count);

// 计算当前段在Y方向的结束64x64块索引

uint32_t y_b64_end_index = SEGMENT_END_IDX(y_segment_index, picture_height_in_b64, pcs->me_segments_row_count);

// 初始化运动估计跳过标志

Bool skip_me = FALSE;

// 检查当前图片是否应该跳过运动估计(例如在多遍编码中)

if (svt_aom_is_pic_skipped(pcs)) //判断图片是否被跳过

skip_me = TRUE;

// 为第一遍编码跳过ME,因为ME已经执行过了

if (!skip_me) {

// 只对非I帧执行运动估计(I帧只有帧内预测)

if (pcs->slice_type != I_SLICE) {

// 如果引用图片的分辨率与输入不同,使用缩放的源引用

svt_aom_use_scaled_source_refs_if_needed(pcs,

input_pic,

pa_ref_obj_,

&input_padded_pic,

&quarter_picture_ptr,

&sixteenth_picture_ptr);

// 64x64块级运动估计循环:遍历当前段内的所有64x64块

// Y方向遍历当前段内的64x64块

for (uint32_t y_b64_index = y_b64_start_index; y_b64_index < y_b64_end_index; ++y_b64_index) {

// X方向遍历当前段内的64x64块

for (uint32_t x_b64_index = x_b64_start_index; x_b64_index < x_b64_end_index; ++x_b64_index) {

// 计算当前64x64块在整个图片中的线性索引

uint32_t b64_index = (uint16_t)(x_b64_index + y_b64_index * pic_width_in_b64);

// 计算当前64x64块在图片中的X坐标起始位置(像素单位)

uint32_t b64_origin_x = x_b64_index * scs->b64_size;

// 计算当前64x64块在图片中的Y坐标起始位置(像素单位)

uint32_t b64_origin_y = y_b64_index * scs->b64_size;

// 从输入图片加载64x64块到中间缓冲区

// 计算当前64x64块在输入图片缓冲区中的起始位置索引

uint32_t buffer_index = (input_pic->org_y + b64_origin_y) * input_pic->stride_y +

input_pic->org_x + b64_origin_x;

#ifdef ARCH_X86_64

// 获取当前64x64块在填充图片中的起始指针

uint8_t *src_ptr = &input_padded_pic->buffer_y[buffer_index];

// 计算实际的块高度(处理图片边界情况)

uint32_t b64_height = (pcs->aligned_height - b64_origin_y) < BLOCK_SIZE_64

? pcs->aligned_height - b64_origin_y : BLOCK_SIZE_64;

// 数据预取优化:提前加载数据到CPU缓存以提高访问速度

// 预取提示级别:_MM_HINT_T0(L1), _MM_HINT_T1(L2), _MM_HINT_T2(L3), _MM_HINT_NTA(非时间局部性)

for (uint32_t i = 0; i < b64_height; i++) {

// 计算每行数据的地址并预取到L3缓存

char const *p = (char const *)(src_ptr + i * input_padded_pic->stride_y);

_mm_prefetch(p, _MM_HINT_T2);

}

#endif

// 设置运动估计上下文中的64x64块源数据指针

me_context_ptr->me_ctx->b64_src_ptr = &input_padded_pic->buffer_y[buffer_index];

// 设置源数据的行步长(stride)

me_context_ptr->me_ctx->b64_src_stride = input_padded_pic->stride_y;

// 加载1/4分辨率抽取的超级块到1/4中间超级块缓冲区

if (me_context_ptr->me_ctx->enable_hme_level1_flag) {

// 计算1/4分辨率图片中对应位置的缓冲区索引(坐标右移1位即除以2)

buffer_index = (quarter_picture_ptr->org_y + (b64_origin_y >> 1)) * quarter_picture_ptr->stride_y +

quarter_picture_ptr->org_x + (b64_origin_x >> 1);

// 设置1/4分辨率64x64块缓冲区指针

me_context_ptr->me_ctx->quarter_b64_buffer = &quarter_picture_ptr->buffer_y[buffer_index];

// 设置1/4分辨率缓冲区的行步长

me_context_ptr->me_ctx->quarter_b64_buffer_stride = quarter_picture_ptr->stride_y;

}

// 加载1/16分辨率抽取的超级块到1/16中间超级块缓冲区

if (me_context_ptr->me_ctx->enable_hme_level0_flag) {

// 计算1/16分辨率图片中对应位置的缓冲区索引(坐标右移2位即除以4)

buffer_index = (sixteenth_picture_ptr->org_y + (b64_origin_y >> 2)) * sixteenth_picture_ptr->stride_y +

sixteenth_picture_ptr->org_x + (b64_origin_x >> 2);

// 设置1/16分辨率64x64块缓冲区指针

me_context_ptr->me_ctx->sixteenth_b64_buffer = &sixteenth_picture_ptr->buffer_y[buffer_index];

// 设置1/16分辨率缓冲区的行步长

me_context_ptr->me_ctx->sixteenth_b64_buffer_stride = sixteenth_picture_ptr->stride_y;

}

// 设置运动估计类型为开环模式

me_context_ptr->me_ctx->me_type = ME_OPEN_LOOP;

// 配置运动估计搜索参数(仅适用于PAME和超分辨率重新ME任务)

if ((in_results_ptr->task_type == TASK_PAME) || (in_results_ptr->task_type == TASK_SUPERRES_RE_ME)) {

// 设置要搜索的引用列表数量:P帧只搜索List0,B帧搜索List0+List1

me_context_ptr->me_ctx->num_of_list_to_search =

(pcs->slice_type == P_SLICE) ? 1 /*只搜索List 0*/

: 2 /*搜索List 0 + 1*/;

// 设置List0中要搜索的引用图片数量

me_context_ptr->me_ctx->num_of_ref_pic_to_search[0] = pcs->ref_list0_count_try;

// 对于B帧,设置List1中要搜索的引用图片数量

if (pcs->slice_type == B_SLICE)

me_context_ptr->me_ctx->num_of_ref_pic_to_search[1] = pcs->ref_list1_count_try;

// 设置当前图片的时域层索引

me_context_ptr->me_ctx->temporal_layer_index = pcs->temporal_layer_index;

// 设置当前图片是否为引用图片标志

me_context_ptr->me_ctx->is_ref = pcs->is_ref;

// 处理帧缩放(超分辨率或调整大小)情况下的引用图片配置

if (pcs->frame_superres_enabled || pcs->frame_resize_enabled) {

// 遍历所有引用列表(List0和List1)

for (int i = 0; i < me_context_ptr->me_ctx->num_of_list_to_search; i++) {

// 遍历当前列表中的所有引用图片

for (int j = 0; j < me_context_ptr->me_ctx->num_of_ref_pic_to_search[i]; j++) {

// 断言检查引用图片的生命周期计数(调试版本)

//assert((int)pcs->ref_pa_pic_ptr_array[i][j]->live_count > 0);

// 获取超分辨率分母索引

uint8_t sr_denom_idx = svt_aom_get_denom_idx(pcs->superres_denom);

// 获取调整大小分母索引

uint8_t resize_denom_idx = svt_aom_get_denom_idx(pcs->resize_denom);

// 获取引用对象指针

EbPaReferenceObject *ref_object =

(EbPaReferenceObject *)pcs->ref_pa_pic_ptr_array[i][j]->object_ptr;

// 设置缩放后的全分辨率引用图片指针

me_context_ptr->me_ctx->me_ds_ref_array[i][j].picture_ptr =

ref_object->downscaled_input_padded_picture_ptr[sr_denom_idx][resize_denom_idx];

// 设置缩放后的1/4分辨率引用图片指针

me_context_ptr->me_ctx->me_ds_ref_array[i][j].quarter_picture_ptr =

ref_object->downscaled_quarter_downsampled_picture_ptr[sr_denom_idx][resize_denom_idx];

// 设置缩放后的1/16分辨率引用图片指针

me_context_ptr->me_ctx->me_ds_ref_array[i][j].sixteenth_picture_ptr =

ref_object->downscaled_sixteenth_downsampled_picture_ptr[sr_denom_idx][resize_denom_idx];

// 设置引用图片的编号

me_context_ptr->me_ctx->me_ds_ref_array[i][j].picture_number =

ref_object->picture_number;

}

}

} else {

// 处理正常情况(无帧缩放)下的引用图片配置

// 遍历所有引用列表(List0和List1)

for (int i = 0; i < me_context_ptr->me_ctx->num_of_list_to_search; i++) {

// 遍历当前列表中的所有引用图片

for (int j = 0; j < me_context_ptr->me_ctx->num_of_ref_pic_to_search[i]; j++) {

// 断言检查引用图片的生命周期计数(调试版本)

//assert((int)pcs->ref_pa_pic_ptr_array[i][j]->live_count > 0);

// 获取引用对象指针

EbPaReferenceObject *ref_object =

(EbPaReferenceObject *)pcs->ref_pa_pic_ptr_array[i][j]->object_ptr;

// 设置原始全分辨率引用图片指针

me_context_ptr->me_ctx->me_ds_ref_array[i][j].picture_ptr =

ref_object->input_padded_pic;

// 设置原始1/4分辨率引用图片指针

me_context_ptr->me_ctx->me_ds_ref_array[i][j].quarter_picture_ptr =

ref_object->quarter_downsampled_picture_ptr;

// 设置原始1/16分辨率引用图片指针

me_context_ptr->me_ctx->me_ds_ref_array[i][j].sixteenth_picture_ptr =

ref_object->sixteenth_downsampled_picture_ptr;

// 设置引用图片的编号

me_context_ptr->me_ctx->me_ds_ref_array[i][j].picture_number =

ref_object->picture_number;

}

}

}

}

// 调用64x64块级运动估计核心函数

// 传入图片控制集、块索引、块坐标、ME上下文和输入图片

svt_aom_motion_estimation_b64(pcs,

b64_index,

b64_origin_x,

b64_origin_y,

me_context_ptr->me_ctx,

input_pic);

// 处理全局运动估计(仅适用于PAME和超分辨率重新ME任务)

if ((in_results_ptr->task_type == TASK_PAME) || (in_results_ptr->task_type == TASK_SUPERRES_RE_ME)) {

// 获取互斥锁,保护共享的已处理块计数器

svt_block_on_mutex(pcs->me_processed_b64_mutex);

// 增加已处理的64x64块计数

pcs->me_processed_b64_count++;

// 检查是否所有超级块的ME都已完成,以便执行全局运动估计

if (pcs->me_processed_b64_count == pcs->b64_total_count) {

// 如果启用了全局运动且满足条件,执行全局运动估计

if (pcs->gm_ctrls.enabled && (!pcs->gm_ctrls.pp_enabled || pcs->gm_pp_detected)) {

svt_aom_global_motion_estimation(pcs, input_pic);

} else {

// 当全局运动关闭时,初始化全局运动状态为OFF

memset(pcs->is_global_motion, FALSE, MAX_NUM_OF_REF_PIC_LIST * REF_LIST_MAX_DEPTH);

}

}

// 释放互斥锁

svt_release_mutex(pcs->me_processed_b64_mutex);

}

}

}

}

// 如果未启用环内最优帧内搜索且启用了时域预测布局,执行开环帧内搜索

if (scs->in_loop_ois == 0 && pcs->tpl_ctrls.enable)

// Y方向遍历当前段内的64x64块

for (uint32_t y_b64_index = y_b64_start_index; y_b64_index < y_b64_end_index; ++y_b64_index)

// X方向遍历当前段内的64x64块

for (uint32_t x_b64_index = x_b64_start_index; x_b64_index < x_b64_end_index; ++x_b64_index) {

// 计算当前64x64块的线性索引

uint32_t b64_index = (uint16_t)(x_b64_index + y_b64_index * pic_width_in_b64);

// 对当前块执行开环帧内搜索,为TPL(时域预测布局)提供信息

svt_aom_open_loop_intra_search_mb(pcs, b64_index, input_pic);

}

}

// 从输出FIFO队列获取空的结果对象

svt_get_empty_object(me_context_ptr->motion_estimation_results_output_fifo_ptr,

&out_results_wrapper);

// 从结果包装器中提取运动估计结果指针

MotionEstimationResults *out_results = (MotionEstimationResults *)

out_results_wrapper->object_ptr;

// 将输入的图片控制集包装器传递给输出结果

out_results->pcs_wrapper = in_results_ptr->pcs_wrapper;

// 传递段索引

out_results->segment_index = segment_index;

// 传递任务类型

out_results->task_type = in_results_ptr->task_type;

// 释放输入结果对象,表示已处理完成

svt_release_object(in_results_wrapper_ptr);

// 将完整的结果对象发送到输出队列,供下游模块使用

svt_post_full_object(out_results_wrapper);

} else if (in_results_ptr->task_type == TASK_TFME) {

// 处理时域滤波运动估计任务

// 全局运动预处理(仅针对基础B帧)

if (pcs->gm_ctrls.pp_enabled && pcs->gm_pp_enabled && in_results_ptr->segment_index==0)

// 执行全局运动预处理器,为时域滤波准备参数

svt_aom_gm_pre_processor(

pcs,

pcs->temp_filt_pcs_list);

// 开始时域滤波处理

// 设置运动估计类型为运动补偿时域滤波(MCTF)

me_context_ptr->me_ctx->me_type = ME_MCTF;

// 初始化时域滤波,处理指定段的数据

svt_av1_init_temporal_filtering(

pcs->temp_filt_pcs_list, pcs, me_context_ptr, in_results_ptr->segment_index);

// 释放输入结果对象

svt_release_object(in_results_wrapper_ptr);

} else if (in_results_ptr->task_type == TASK_DG_DETECTOR_HME) {

// 处理动态GOP检测分层运动估计任务

// 执行0级分层运动估计检测器,用于动态GOP结构优化

dg_detector_hme_level0(pcs, in_results_ptr->segment_index);

// 释放输入结果对象

svt_release_object(in_results_wrapper_ptr);

}

} // 主循环结束

// 函数返回NULL,表示线程正常退出

return NULL;

}

// clang-format on

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95691.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95691.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/95691.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于NET Core jwt Bearer Token 验证的大坑,浪费3个小时,给各位兄弟搭个桥。

net core 使用jwt Bearer Token 认证获取接口访问权限&#xff0c;前期一阵操作没任何问题&#xff0c;等认证接口写的好了&#xff0c;通过PostMan测试的时候&#xff0c;总是报一个 IDX14102: Unable to decode the header eyJhbGciOiJIUzI1NiIsInR5cCI6 &#xff0c;错误&a…

系统架构设计师备考第14天——业务处理系统(TPS)

一、TPS的核心概念与定位 1. 定义与演进 定义&#xff1a;TPS&#xff08;Transaction Processing System&#xff09;又称电子数据处理系统&#xff08;EDPS&#xff09;&#xff0c;是处理企业日常事务的信息系统&#xff0c;如财务、库存、销售等局部业务管理。历史地位&…

目标检测系列-Yolov5下载及运行

由于项目需要&#xff0c;最近一直在看目标检测相关的资料&#xff0c;不过纸上得来终觉浅&#xff0c;绝知此事要躬行啊。从今日起&#xff0c;将学习的过程记录一下&#xff0c;作为以后用来复习的材料吧。 我想最快的学习便是直接动手做项目&#xff0c;因此今天就将yolov5模…

Linux内核进程管理子系统有什么第四十二回 —— 进程主结构详解(38)

接前一篇文章&#xff1a;Linux内核进程管理子系统有什么第四十一回 —— 进程主结构详解&#xff08;37&#xff09; 本文内容参考&#xff1a; Linux内核进程管理专题报告_linux rseq-CSDN博客 《趣谈Linux操作系统 核心原理篇&#xff1a;第三部分 进程管理》—— 刘超 《…

基于飞算JavaAI的学生成绩综合统计分析系统

第一章&#xff1a;项目概述与背景 1.1 项目背景与意义 在教育信息化飞速发展的今天&#xff0c;学生成绩管理已成为学校教学管理的核心环节。传统的学生成绩管理多依赖于手工操作或基础的信息管理系统&#xff0c;存在数据处理效率低、统计分析功能薄弱、数据可视化缺失等问题…

C++程序员必懂:std::bad_function_call异常的真相与预防秘诀

std::bad_function_call 是 C++ 标准库在 <functional> 头文件中定义的一个异常类型。当程序试图调用一个未持有任何可调用目标(即处于“空状态”)的 std::function 对象时,此异常会被抛出。本文将深入探讨该异常的根本原因、详细的触发场景,并提供一套完整的预防与处…

Html重绘和重排

在网页渲染过程中&#xff0c;重绘&#xff08;repaint&#xff09;和重排&#xff08;reflow&#xff09;是两个重要的概念。理解它们的区别和优化方法对于提升网页性能至关重要。重排&#xff08;Reflow&#xff09;重排是指当页面元素的位置、尺寸等几何属性发生变化时&…

Redis 客户端与服务器:银行的 “客户服务系统” 全流程

目录 一、Redis 客户端&#xff1a;银行的 “客户档案” 二、客户端关闭&#xff1a;银行的 “终止服务规则” 三、命令处理流程&#xff1a;柜员办理业务的 “标准步骤” 1. 接收申请单&#xff08;读取命令请求&#xff09; 2. 确认业务类型&#xff08;查找命令&#x…

HTML图片标签及路径详解

图片是网页内容的重要组成部分&#xff0c;能够使页面更加生动直观。在HTML中&#xff0c;使用<img>标签插入图片&#xff0c;而正确设置图片路径则是确保图片能够正常显示的关键。一、图片标签&#xff08;<img>&#xff09;1. 图片标签的基本语法<img>标签…

【数据库通过日志恢复数据解读】

在数据库恢复机制中&#xff0c;日志文件是实现事务原子性、持久性和崩溃恢复的核心组件。以下通过具体示例和解读方法&#xff0c;结合主流数据库系统的实现细节&#xff0c;详细说明日志文件的内容与分析逻辑。 一、日志文件的核心作用与结构 日志文件通过**预写式日志&#…

【面试题】搜索准确性不高你怎么排查?

系统性排查框架&#xff1a;数据层检查 索引覆盖率&#xff1a;检查文档是否全部正确索引数据新鲜度&#xff1a;确认索引更新频率和延迟文档质量&#xff1a;分析被索引内容的质量和完整性查询理解层 分词分析&#xff1a;检查查询分词是否正确意图识别&#xff1a;验证意图分…

当AI开始“偷吃”用户数据并拼装功能模块:初级开发者的脑洞保卫战与老码农的灵魂蘸料

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录当AI开…

Flowable——流程定义与部署(RepositoryService)

文章目录 前言 参考资料 流程图的部署、查询与删除 流程图的准备 流程的部署 指定已部署流程信息查询 删除指定已部署流程 结语 前言 前篇博客具体说了怎么使用flowable去自动建表,以及搭建配置前端UI绘图的界面。本篇博客主要说明对于已绘制好的流程图如何去进行部署。 Flow…

采用基于模型的方法实现车辆SOA威胁分析自动化

摘要尽管采用面向服务架构&#xff08;SOA&#xff09;有助于实现自动驾驶、空中下载更新等功能&#xff0c;但同时也增加了车辆遭受攻击的风险&#xff0c;可能对道路使用者造成伤害。为解决这一问题&#xff0c;相关标准&#xff08;ISO 21434 / 联合国欧洲经济委员会&#x…

C++语言编程规范-常量

01 C还有搞头吗 02 常量 不变的值更易于理解、跟踪和分析&#xff0c;所以应该尽可能地使用常量代替变量&#xff0c;定义值的时候&#xff0c;应该把 const 作为默认的选项。使用 const 常量取代宏说明&#xff1a;宏是简单的文本替换&#xff0c;在预处理阶段时完成&#x…

【CS32L015C8T6】配置单片机PWM输出(内附完整代码及注释)

目录 前言&#xff1a; 一、CS32L015中定时器及PWM硬件资源介绍&#xff1a; 二、以CS32L015为例配置PWM步骤&#xff1a; 三、完整代码及注释 四、如果这篇文章能帮助到你&#xff0c;请点个赞鼓励一下吧ξ( ✿&#xff1e;◡❛)~ 前言&#xff1a; CS32L015 是一款内嵌 …

hive表不显示列注释column comment的问题解决

安装datasophon平台hive后&#xff0c;发现hive表的字段注释丢失了&#xff0c;表的注释没问题&#xff0c;csv格式的表没问题&#xff0c;只有parquet和orc的表有这个问题。查网上似乎没有这方面的问题。查看mysql表里面的中文注释也一切正常&#xff0c;后来经过多次研究才发…

【笔记】AI Agent发展趋势

前言 本章主要探讨了现在AI技术的发展趋势、大模型的一些局限性和小模型存在的必要性,然后引出了AI Agent的优势与发展趋势。 目标 学完本课程后,您将能够: 了解大模型的局限性; 了解小模型存在的必要性; 了解AI Agent的优势; 了解模型协同的技术。 目录 1.AI发…

ChatDOC工具测评:AI驱动PDF/Word文档处理,支持敏感内容隐私保护与表格提取分析

之前跟你们聊过用 Python 处理数据的 Pandas&#xff0c;今天换个更贴近日常办公的方向 —— 给你们安利一个 AI 文档处理工具「ChatDOC」&#xff0c;官网地址是https://www.chatdoc.com/&#xff0c;它能直接读取 PDF、Word 里的内容&#xff0c;你不用逐页翻文档找信息&…

Vue + fetchEventSource 使用 AbortController 遇到的“只能中止一次”问题解析与解决方案

前言 在前端项目中&#xff0c;使用 SSE&#xff08;Server-Sent Events&#xff09; 长连接去获取实时消息已经很常见了。像 fetchEventSource 这种封装好的工具&#xff0c;可以帮助我们轻松处理流式请求。 不过在实践中&#xff0c;我遇到了一个奇怪的问题&#xff1a;点击按…