- 博客(30)
- 收藏
- 关注

原创 视频编码中的算法、技术学习
编解码小白最近在学习视频编码中各种各样的技术,简单记录学习到的内容,希望大佬们指点指点不足之处。这里是大目录,会持续更新接触到的技术。
2024-12-27 16:23:55
542
原创 编码码率控制-ABR码控
5. 根据复杂度计算出I帧的qp,可能会出现这个qp计算过大或者过小(这对整个GOP码控都不太友好),因此可以添加GOP之间的I帧调控,用上一个GOP的情况来调控当前GOP的I帧的计算(例如可以使用上一个GOP平均qp来预测得到当前GOP的预测qp,然后对基于复杂度的计算出来的qp进行一个偏移)。3. P帧码率分配占比,原理来看,如果只参考前一帧,那么越靠近I帧的P帧它的质量应该给的越好,这样整体性能会更好(因为传递带来损失是累计的)。(总之最后得到最上面的公式)。可以分为GOP级的、帧级的、CU块级的。
2025-01-15 12:05:41
370
原创 编码滤波技术-SAO
五种模式再加上左邻居的merge信息和上邻居的merge信息这七种模式的cost,最终选择最优的模式进行SAO。),选择4个的区间(其中区间是两个连续的作为一组,这样也是为了节省编码bit),对处于这区间的像素点进行偏移(这里的4个区间是之前RDO得出来的,每个区间的偏移量offset也是RDO得出来的,都保存在最优sao参数里。就是当前块的SAO信息可以直接用相邻的块的SAO信息,这样可以节省编码bit。核心思想:就是根据c的值跟a、b的值的关系,来对c的值进行一个偏移。编码端的RDO:会比较当前块的。
2024-12-27 16:03:41
273
原创 编码滤波技术-去块滤波deblock
②当fs等于6且DeblockingFilterType 等于1时,如果 Abs(p0-p1) <= β/4且 Abs(q0-q1) <= β/4且Abs(p0-p3) <= β/2且 Abs(q0-q3) <= β/2且 Abs(p0-q0) < α,则 Bs = 4;简单理解:就是一个8*8的块,右边界和上边界,右边界的左右8个像素点需要平滑(左4个右4个,即垂直滤波),上边界的上下8个像素点需要平滑(水平滤波)。当前滤波块的垂直边界的滤波过程中修改的样值作为水平边界滤波过程的输入。
2024-12-27 10:52:08
1145
原创 编码技术-自适应qp
由于RD曲线的凹函数特性,一般自适应qp算法会带来主观性能的增益,客观性能(如BD-PSNR)的损失。上面两种方法的复杂度可以是梯度值(即在某一方向,像素值的变化累计量),也可以是帧内预测后得到的ssd、cost等等。如果当前CU块的复杂度超过累计平均复杂度的则减少qp,否则增加qp。低于平均值则分配更少的码率,即用大于当前帧的QP值的量化步长。S设置为2,act_cu为当前LCU的方差,act_f为整帧所有LCU的平均方差。自适应qp是在编码得到帧级qp后对每个CU块的qp再额外调整的一个技术。
2024-12-26 12:07:12
280
原创 编码技术-MCTF
假设有P1和P2两帧,P1编完后作为P2的参考帧。编码是想要P1编完后的重构recP1尽可能的接近原始orgP1,这样PSNR就更高。其中Io是原始样本的值,Ir(i) 是运动补偿图片 i 中相应样本的值,Wr(i,a)是当可用补偿图片的数量等于a时运动补偿图片I的权重。简单来说就是改变当前编码帧的原始值,让后续参考当前帧的帧更好的编码,是一种前处理技术。这样P2帧参考P1帧时预测会更准确,代价最小,从而到压缩码率的目的。通过运动估计技术,来更好的加权平滑当前帧。
2024-12-26 11:40:06
460
原创 编码技术-二次变换
注:只作用在coef系数数组的左上角4*4的块上面,变换矩阵如下,即简单的把dct变换后得到的系数数组左上角4*4,再×一次矩阵。(1)帧内预测模式是0~2,13~32,44~65,并且左相邻CU块信息可用,则使用水平二次变换。(2)帧内预测模式是0~23,34~57,并且上相邻CU块信息可用,则使用垂直二次变换。先进行二次变换逆变换再进行dct逆变换,然后再是逆量化。其中变换也只是简单的x逆二次变换矩阵。没有具体数据,做了简单测试只是码率变低了,psnr也相应变低,综合BDBR没有太大增益。
2024-12-26 11:27:52
133
原创 编码技术-RDOQ
简单理解就是在量化中对每个系数,看它量化成当前level还是level-1还是0,这3个哪个更好。进一步可以看一下把一组系数都量化成0的cost,再进一步还有最后一个非零系数位置。最后选择最优的系数输出。step3. 找到最优的最后一个非零系数的位置,尝试从最后一个非零位置开始将量化后的系数设置为0。RDOQ据说是一项非常好的技术,可以带来很多的性能增益,但是没找到具体的数据。通过比较所有量化级别的成本,选择成本最低的量化级别,作为该块的最终量化参数。对每个可能的量化级别,计算其对应的失真和码率。
2024-12-26 11:16:24
441
原创 编码技术-HMVP
针对skip/direct模式,采用基于历史的运动矢量预测(HMVP)方法,利用更多先前编码的块的运动信息进行预测,从已经解码的块推断所有的运动数据显著地简化了块方向的运动数据信号。如果当前编码单元的运动信息与FIFO中任意候选的运动信息均不相同,就会去掉FIFO中第一个候选,再将最新的运动信息加到FIFO末尾,保证FIFO中永远保留八个最新的运动候选。候选列表motion_cands_curr中存1个mvp,3个空域mv,8个hmvp)共12个mv,后续会有一系列的重复检查。
2024-12-26 11:03:52
254
原创 编码技术-UMVE
AVS中的UMVE:对skip和direct模式中导出的运动矢量进行偏移,进一步细化skip/direct模式的MV,以便更好地进行预测。top_mv保留一图像行的mv,left_mv保留一LCU列的mv,top_left_mv保留左上角一个mv,top_left_mv_save左上角mv的中间保存,map_mv保存当前LCU中所有的mv。LCU边界的CU块使用缓存的mv,LCU内部的CU块使用map_mv中当前LCU已经编码的CU块的mv。简单的理解就是,对得到的MV进一步修改,目的取得更好更准的MV。
2024-12-26 10:55:04
483
原创 使用内存池来优化X264编码
在win上使用ffmpeg调用X264编码4K的视频,突然发现每一帧内存的释放比较耗时(在linux上测试了发现并没有耗时,原因linux释放使用的是free函数,win上使用的是_aligned_free函数)。个人觉得是4K需要的内存很大(3840*2160*4+64),然后使用AVCIntraClass300的配置编码速度又很快,从而突出了内存释放的时间。
2024-03-11 15:22:04
590
原创 ffmpeg调用X264的线程处理
图中四边形代表ffmpeg会在那些位置创建一系列的线程,等待被唤醒。在打开编码器的时候,ff会帮X264把线程池和lookahead线程创建好。最下面那个大框就是主线程达到X264库做的事,最后主线程会唤醒X264的线程池叫工作线程来编码。值得关注的点是ff似乎是输入跟编码是并行的,猜测是编码一直循环,得到了输入才开始编码否则又回去问有没有输入。但具体还没看到相关的代码,后续再仔细研究。
2024-02-02 18:08:23
435
1
原创 X264AVCIntra Class300/480部分源码阅读
了解了一下AVCIntra其实就是调整X264里的一些编码参数,控制出一个快速稳定的CBR码控模式,可以实现固定输出码率,并且每帧的大小都相同。
2024-01-19 11:20:32
583
1
原创 如何在编解码器里更加准确的计算函数耗时
可以用到全局变量和外部变量,编码结束肯定是在main函数里,这样我们在结束前再输出累积的时间就可以解决这个问题了。但是在编解码器中,一个代码段、一个函数通常会被反复调用,这个时候该怎么得到我们想要的最终的累积时间消耗呢?上一篇文章有介绍如何使用VS来整体分析项目的各个函数耗时,但是这种方法也许不是特征精准会有其他的影响。方法就是使用C自带的一些计时工具,大佬博客总结了适合win和linux的各种方法。1.声明外部变量,在我们需要计算时间的函数文件里声明。找到main函数,结束前输出结果就可以了。
2023-12-26 11:55:01
600
1
原创 X264的ABR、CBR码率控制
图像本身的内容复杂度;与参考图像的相似程度(这里跟帧间编码有关,比较相似的话我们需要编码的数据就很少);编码的量化程度;简单来说图像越复杂,与参考帧的相似程度越小,编码量化程度越小,编码后生成的码流就越大;1和2都由原始视频源决定了的,编码器内部改变不了,似乎编码器唯一能做的只有通过控制量化程度来控制编码码率了。个人理解量化程度就是QP值,一个宏块,QP设置的越大,咱们丢弃的数据就越多,码流文件也就越小。所以简单理解,码控就是去设置每个块的QP值,让整体编码达到我们想要的结果。
2023-12-22 11:46:00
2339
原创 gitlab的使用
初步接触gitlab项目,记录几个有用的操作。个人感觉主要是本地库和远程库的区别,需要先在本地添加、提交,然后再往远程大家共享的地方推送。gitlab是一个共享的平台,感觉有以下几个操作就可以满足简单的项目合作了。git add 文件名 (或者 git add . 来添加全部修改)git config --global user.name 用户名。git config --global user.email 邮箱。git commit -m "日志信息" 文件名。
2023-12-21 18:06:19
361
原创 HEVCe轻量级帧内编码器阅读
把 CU(y= 8 x=24 size= 8) 分成4个PU, 对每个PU分别尝试35种预测模式, 4个最佳的预测模式={ 0,16,23, 3}, RDcost=1345, 小于当前最优RDcost (1404), 更新为当前最优方案。把 CU(y=16 x=16 size= 8) 分成4个PU, 对每个PU分别尝试35种预测模式, 4个最佳的预测模式={ 4, 5, 3, 0}, RDcost=1254, 小于当前最优RDcost (1332), 更新为当前最优方案。
2023-12-08 16:31:05
1984
原创 QT链接VS编译的库出现的问题
突然发现有篇文章说是QT跟VS的编译器的区别,VS编的库不适用QT,但是我们可以用QT+MSVC来适用VS的库,OK,重新安装一遍QT,自定义选择MSVC2019。因为要做界面开发,所以去学了一下QT,但是链接我之前在VS编译好的静态库报了一大堆错,各种各样的问题,很奇怪,之前我用VS调一点问题都没有呢。在网上找了一堆解决问题的方法,报错越来越少了但是最终还有一个重定义的问题。直接一个报错都没了,非常舒服。
2023-11-22 18:06:50
262
1
原创 Visual Studio链接库遇到的小问题
原来是链接到系统上的avformat-60.dll上去了,Visual Studio会优先去系统路径上找一找库,找到了就不会再找了,系统上为啥会莫名其妙有个这个dll。②觉得万一它有啥用的话,我们就可以把我们的dll直接放到工程生成文件里去,它的优先级比系统还要高,下面这个路径所有dll全丢进去就可以了。只能开始用宇宙编译器debug一下出现了什么情况,调试-窗口-模块看看我们链接的库是不是有问题。OK,似乎都没问题,那就是看看我的ffmpeg有没有--enable-libvpx。
2023-11-14 17:52:20
680
1
原创 Win下编译libvpx遇到的问题
因为想用VS来运行vpxdec解码,所以需要编译一下源码,直接按大佬的教程就可以编译出sln文件了。直接去运行yasm试一下,发现缺少了一个vs2010的dll动态库,导致yasm根本运行不了。瞅了瞅发现是跟asm有关,那就是跟yasm有关了,但是我win是装好了yasm的环境的呢。直接整一个修复,这个文件想要的可以直接私信我发给你。但是生成vpxdec工程的时候报错了。运行.exe文件后再去生成,就OK啦。
2023-11-10 10:21:51
278
1
原创 C++main函数输入
argc是自动计算你命令参数里有多少个字符串,argv里就保存命令参数里的输入字符串,用空格隔开,可以拿来使用。这里argv[0]一般代表应用程序的exe文件路径,所以我们输入的参数是从argv[1]开始的。下面就是改好的输入main函数了。c++的main函数也支持输入,一种比较常用的方法就是输入一个字符串数组和数组长度两个参数。
2023-11-08 13:55:46
402
1
原创 怎么用Visual Studio把自己写的代码封装成动态库给别人使用
头文件是最关键的地方,让其他人直接通过我们的头文件来访问我们的代码,这里就是接口处了。头文件要尽量简单,把类的定义丢上来就差不多了,其他的我们在cpp文件里再实现。而且头文件里除了系统库不要再去include其他自己定义的库啥的了,不然别人用的时候找不到include的东西。#else#endifprotected:public:private:这里还有一个很关键的地方,我们用的是动态库dll编译,要想得到静态库lib就得加上导出标志MYTRANSCODER_API。
2023-11-06 16:53:49
1586
1
原创 C++多线程实现解码、编码同步
最开始实现的格式转化,流程是输入解码一帧然后再编码这一帧再输出,发现输入解码和编码输出两个部分是互不干扰的,这样我们就可以设计两个线程来实现解码和编码同时进行提高效率。
2023-11-01 15:32:21
334
1
原创 用Scope Guard 范围守卫实现超方便的RAII
上一篇文章写了怎么构建一个类来实现RAII但是看起来还是挺麻烦的网上搜了一圈发现一个Scope Guard 范围守卫。
2023-10-27 15:28:53
246
1
原创 C++ RAII
上一篇文章里有写到很多的内存释放,而且这个会一直积累,程序写的越长就越多,所以想想有什么办法自动进行内存释放,在网上找到了RAII这个概念,很好用。
2023-10-26 17:48:43
71
原创 C++调用ffmpeg sdk开发
一开始我想直接就用输入源的参数,参数太多了懒得一个一个报错了再去改,谁知道错的离谱,代码里面我自己设定了几个参数,可能不太全,但是代码可以运行了,结果也是准确的,还是不错的,毕竟自己也是刚开始学习。首先整体的流程,在网上看到有大佬给出了基于ffmpeg格式转换的流程,如下图,是FLV转到AVI的,我只有几个MP4文件,所以就参考大佬的流程做一个MP4转AVI吧。...本来想通过实现各个格式的相互转换来熟悉ffmpeg的,但是发现内容有点多,就只实现了mp4转成avi格式。总体来说流程还不是太难。
2023-10-24 18:09:40
3963
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人