libaom 源码分析线程结构

一 libaom线程启动函数

void av1_create_workers(AV1_PRIMARY *ppi, int num_workers)

{

PrimaryMultiThreadInfo *const p_mt_info = &ppu->p_mt_info;

const AVxWorkerInterface *const = winterface = aom_get_worker_interface();

for (int i = 0; i < num_workers; ++i) {

AVxWorker* const worker = &p_mt_info->workers[i];

EncWorkerData *const thread_data = &p_mt_info->tile_thr_data[i];

winterface->init(worker);

worker->thread_nae = "aom enc worker";

thread_data->thread_id = i;

thread_data->start = i;

if (i > 0) {

if (!winterface->reset(worker))

aom_internal_error(&ppi->error, AOM_CODEC_ERROR, "Tile encoder thread creation failed");

}

}

winterface->sync(worker);

++p_mt_info->num_workers;

}

二 libaom线程调用栈

#0 in full_pixel_diamond()

#1 0x000000000058ee91 in av1_full_pixel_search ()

firstpass_inter_prediction->first_pass_motion_search

#2 0x000000000057d22c in av1_first_pass_row ()

#3 0x0000000000571124 in fp_enc_row_mt_worker_hook ()

#4 0x0000000000be5ef7 in execute ()

#5 0x00000000005788c8 in av1_fp_encode_tiles_row_mt ()

#6 0x000000000057ea03 in av1_first_pass ()

#7 0x00000000005625c0 in av1_encode ()

#8 0x0000000000c8036f in av1_encode_strategy ()

#9 0x00000000005636eb in av1_get_compressed_data ()

#10 0x00000000004ff0fb in encoder_encode ()

#11 0x00000000004bca0a in aom_codec_encode ()

#12 0x000000000040af05 in encode_frame.isra ()

#13 0x000000000040786c in main ()

三 libaom 线程调用关系

void av1_first_pass_row(AV1_COMP *cpi, ThreadData *td, TileDataEnc *tile_data, const int unit_row, const BLOCK_SIZE fp_block_size) ->

firstpass_inter_prediction(cpi, td, last_frame, golden_frame, unit_row, unit_col, recon_yoffset, recon_uvoffset, src_yoffset, fp_block_size, this_intra_error, raw_motion_err_counts, raw_motion_err_list, best_ref_mv, &best_ref_mv, &last_mv, mb_stats);

firstpass_intra_prediction()

线程入口函数

//定义一个静态整型函数用于多线程编码工作钩子

static int fp_enc_row_mt_worker_hook(void *arg1, void *unused)

{

//传入arg1转换EncWorkerData类型这个结构包含了线程数据

EncWorkerData *const thread_data = (EncWorkerData*)arg1;

//线程数据中获取编码器上下文结构

AV1_COMP* const cpi = thread_data->cpi;

//获取当前线程ID

int thread_id = thread_data->thread_id;

//获取编码器多线程信息

AV1EncRowMultiThreadInfo *const enc_row_mt = &cpi->mt_info.enc_row_mt;

//如果配置多线程获取多线程互斥

//获取线程数据中内部错误信息结构体

struct aom_internal_error_info* const error_info = &thread_data->error_info;

//获取宏块解码器上下文

MACROBLOCK* const xd = &thread_data->td->mb.e_mbd;

//设置宏块解码器上下文的错误信息

xd->error_info = error_info;

//设置错误恢复环境只有调用setjmp()函数中才有效

//如果setjmp() 返回非零表示发生了错误跳转

if (setjmp(error_info->jmp)) {

error_info->setjmp = 0;

pthread_mutext_lock(enc_ro_mt_mutex_);

//设置firstpass_mt_exittrue, 表示第一个通过多线程退出

enc_row_mt->firstpass_mt_exit = true;

//解锁互斥

pthread_mutex_unlock(enc_row_mt_mutex_);

set_firstpass_encode_done(cpi);

return 0;

}

//设置setjmp字段1表示jmp_buf有效

error_info->setjmp = 1;

//获取AV1公共结构体

AV1_COMMON *const cm = *cpi->common;

//获取当前线程对应tile ID

int cur_tile_id = enc_row_mt->thread_id_to_tile_id[thread_id];

//断言当前tile ID不是-1

assert(cur_tile_id != -1);

//获取固定大小

const BLOCK_SIZE fp_block_size = cpi->fp_block_size;

//获取单位高度

const int unit_height = mi_size_high[fp_block_size];

//初始化end of frame0

int end_of_frame = 0;

while (1) {

//初始化当前MI

int current_mi_row = -1;

//获取firstpass_mt_exit状态

bool firstpass_mt_exit = enc_row_mt->firstpass_mt_exit;

//如果firstpass_mt_exitfalse并且没有当前tile工作查询其他tile状态获取下一个工作

if (!firstpass_mt_exit && !get_next_job(&cpi->tile_data[cur_tile_id],&current_mi_row, unit_height)) {// 没有当前tile的工作,查询其他tile的状态并获取下一个工作。switch_tile_and_get_next_job(cm, cpi->tile_data, &cur_tile_id,&current_mi_row, &end_of_frame, 1,
                                   fp_block_size);}

//如果firstpass mt exittrue, 或者其他工人不需要进一步工作跳出循环

if (firstpass_mt_exit || ned_of_frame) break;

//获取当前tile数据

TileDataEnc *const this_tile = &cpi->tile_data[cur_tile_id]

// 获取行多线程同步信息。
    AV1EncRowMultiThreadSync *const row_mt_sync = &this_tile->row_mt_sync;// 获取线程数据。
    ThreadData *td = thread_data->td;// 断言current_mi_row不是-1,并且小于当前tile的MI行结束。assert(current_mi_row != -1 &&
           current_mi_row < this_tile->tile_info.mi_row_end);// 获取单位高度的对数。const int unit_height_log2 = mi_size_high_log2[fp_block_size];// 调用av1_first_pass_row函数进行第一通过编码。av1_first_pass_row(cpi, td, this_tile, current_mi_row >> unit_height_log2,
                       fp_block_size);
#if CONFIG_MULTITHREAD// 如果配置了多线程,锁定互斥锁。pthread_mutex_lock(enc_row_mt_mutex_);
#endif// 减少正在工作的线程数。
    row_mt_sync->num_threads_working--;
#if CONFIG_MULTITHREAD// 解锁互斥锁。pthread_mutex_unlock(enc_row_mt_mutex_);
#endif}// 重置setjmp字段为0。
  error_info->setjmp = 0;// 返回1表示成功。return 1;

}

}

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

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

相关文章

前端使用Get传递数组形式的数据

前端使用Get传递数组形式的数据 前端后端接收 不能直接使用 JSON.stringify()传输参数&#xff0c;或者直接用json数据传输&#xff0c;后端均会应为包含了非法的符号 [与 ]而报错。 前端 主要在于对Array形式的数据进行转换&#xff0c;拼接成字符串&#xff0c;采用join方…

Centos 下安装 GitLab16.2.1

参考 https://blog.csdn.net/weixin_46059351/article/details/140649426 https://blog.csdn.net/qq_46028493/article/details/144993598 Centos 安装 GitLab 修改 yum 的配置 首先查看目前配置的 yum&#xff1a; cat /etc/yum.repos.d/CentOS-Base.repo应该是这个样子…

uniapp 微信小程序 自定义日历组件

效果图 功能&#xff1a;可以记录当天是否有某些任务或者某些记录 具体使用&#xff1a; 子组件代码 <template><view class"Accumulate"><view class"bx"><view class"bxx"><view class"plank"><…

刚体变换矩阵的逆

刚体运动中的变换矩阵为&#xff1a; 求得变换矩阵的逆矩阵为&#xff1a; opencv应用 cv::Mat R; cv::Mat t;R.t(), -R.t()*t

php反序列化 ctf例题演示 框架安全(TP,Yii,Laravel) phpggc生成框架利用pop

前言 php反序列化的框架的利用的pop是非常难写的 并且 我们不知道他的利用方法 所以PHPGGC是一个包含unserialize()有效载荷的库以及一个从命令行或以编程方式生成它们的工具。当在您没有代码的网站上遇到反序列化时&#xff0c;或者只是在尝试构建漏洞时&#xff0c;此工具…

【游戏设计原理】53 - 解决问题的障碍

1. 分析并总结原理 核心观点 游戏本质是一系列问题解决的过程&#xff0c;通过设计巧妙的问题和决策场景&#xff0c;游戏能激发玩家的兴趣和投入感。然而&#xff0c;当问题解决的过程被阻碍时&#xff0c;会降低玩家的体验甚至让他们放弃游戏。文中提到的四种障碍反映了玩家…

线性代数考研笔记

行列式 背景 分子行列式&#xff1a;求哪个未知数&#xff0c;就把b1&#xff0c;b2放在对应的位置 分母行列式&#xff1a;系数对应写即可 全排列与逆序数 1 3 2&#xff1a;逆序数为1 奇排列 1 2 3&#xff1a;逆序数为0 偶排列 将 1 3 2 只需将3 2交换1次就可以还原原…

LabVIEW四旋翼飞行器姿态监测系统

四旋翼飞行器姿态监测系统是一个集成了高度、速度、俯仰角与滚转角数据采集与分析的系统&#xff0c;提高飞行器在复杂环境中的操作精确度与安全性。系统利用LabVIEW平台与硬件传感器相结合&#xff0c;实现实时数据处理与显示&#xff0c;有效地提升了四旋翼飞行器的监测与控制…

STM32之CAN通讯(十一)

STM32F407 系列文章 - CAN通讯&#xff08;十一&#xff09; 目录 前言 一、CAN 二、CAN驱动电路 三、CAN软件设计 1.CAN状态初始化 2.头文件相关定义 3.接收中断服务函数 4.用户层使用 1.用户层相关定义 2.发送数据 3.接收数据 1.查询方式处理 2.中断方式处理 3…

添加系统级res资源包

//刚做完自定义res资源包的配置&#xff0c;这里做一下关于在配置过程中出现的问题和解决方法作一下记录。 资源的引用格式为&#xff1a; 包名&#xff1a;资源类型/资源名以framework资源为例&#xff1a; android:style/Theme.Holo.Light这次需要配置与framework同级的资…

LabVIEW计算机软件著作权

计算机软件著作权是指软件开发者对其创作的软件作品享有的法律保护权利&#xff0c;目的是防止他人未经授权复制、修改或传播该软件。软件著作权不仅包括软件的源代码&#xff0c;还包括文档、界面设计、功能模块、程序逻辑等内容。通过登记软件著作权&#xff0c;开发者可以获…

unity学习13:gameobject的组件component以及tag, layer 归类

目录 1 gameobject component 是unity的基础 1.1 类比 1.2 为什么要这么设计&#xff1f; 2 从空物体开始 2.1 创建2个物体 2.2 给 empty gameobject添加组件 3 各种组件和新建组件 3.1 点击 add component可以添加各种组件 3.2 新建组件 3.3 组件的操作 3.4 特别的…

Vue项目中的问题汇总(持续更新中)

1.vue 循环 span 标签产生了间隙 代码如下&#xff1a; <template><div class"box"><span v-for"(item,index) in items" ::key"index">{{ item }}</span><span>修改</span><span>删除</span>…

ffmpeg7.0 合并2个 aac 文件

ffmpeg7.0 将2个aac文件合并。 #include <stdio.h>// 之所以增加__cplusplus的宏定义&#xff0c;是为了同时兼容gcc编译器和g编译器 #ifdef __cplusplus extern "C" { #endif #include <libavformat/avformat.h> #include <libavcodec/avcodec.h>…

Midjourney 应用:框架总结

Midjourney 应用&#xff1a;框架总结 官方的模板很简单&#xff0c;分成四个部分&#xff1a; 主体细节 & 背景风格、媒介、艺术家参数 我的总结 其实按照官方模板写&#xff0c;你已经能超过 90% 的初学者&#xff0c;但根据我的实验&#xff0c;我细化了他们的模板的…

JVM实战—OOM的定位和解决

1.如何对系统的OOM异常进行监控和报警 (1)最佳的解决方案 最佳的OOM监控方案就是&#xff1a;建立一套监控平台&#xff0c;比如搭建Zabbix、Open-Falcon之类的监控平台。如果有监控平台&#xff0c;就可以接入系统异常的监控和报警&#xff0c;可以设置当系统出现OOM异常&…

JVM实战—13.OOM的生产案例

大纲 1.每秒仅上百请求的系统为何会OOM(RPC超时时间设置过长导致QPS翻几倍) 2.Jetty服务器的NIO机制如何导致堆外内存溢出(S区太小 禁NIO的显式GC) 3.一次微服务架构下的RPC调用引发的OOM故障排查实践(MAT案例) 4.一次没有WHERE条件的SQL语句引发的OOM问题排查实践(使用MA…

【银河麒麟高级服务器操作系统实例】tcp半链接数溢出分析及处理全过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…

visual studio 自动调整代码格式的问题:

1.取消自动调整格式 2.如果是想让代码显得更紧凑&#xff0c;上面的不动&#xff0c;按这个来&#xff1a;

javaEE-网络原理-1初识

目录 一.网络发展史 1.独立模式 2.网络互联 二.局域网LAN 1.基于网线直连&#xff1a; 2.基于集线器组件&#xff1a; 3.基于交换机组件&#xff1a; 4.基于交换机和路由器组件 ​编辑 三、广域网WAN 四、网络通信基础 1.ip地址 2.端口号&#xff1a; 3.协议 4.五…