自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(76)
  • 资源 (1)
  • 收藏
  • 关注

原创 HEVC学习之去方块滤波

AVC中采取对4×4块的边界进行去方块滤波,HEVC采取的是对8×8块进行去方块滤波,这种改进减少了需要进行去方块滤波处理的边界数量,能更好适应高分辨率视频编码的需要。由于8×8块的边界可能存在图像的自然边界,若是对这些区域进行了滤波操作,则会出现模糊效应,因此先进行滤波决策,根据边界的实际情况,判断是否滤波以及采用何种滤波强度。对于色度滤波没有亮度滤波那么复杂,只要边界强度为2,且滤波开关打开,就对色度分量进行滤波,无须其他判断条件,且只有一种模式,修正边界两侧各1个像素,即p0与q0。

2023-05-10 19:15:32 892 1

原创 HEVC学习之率失真优化

由于引入了拉格朗日系数,不再给定码率RT,设D+λR=J,过(R,D)做一条斜率为λ的斜线,其于纵轴截距即为J,让J最小即让截距最小,此时让(R,D)逼近理论曲线的问题可转化为过(R,D)做一条斜率为λ的斜线,让其与y轴截距最小,通过数学推导可知,当该斜线于曲线相切时理论最小,寻找给(R,D)点的过程即HEVC中的率失真优化。在视频编码中的率失真理论为在给定码率RT的前提下最大限度的减少视频信息的失真,用数学描述为第一个式子所示,其中m*为取得最小码率时的编码方式,S为编码方式的集合。

2023-05-09 15:55:06 1433

原创 HEVC学习之CTU划分

在做完帧间预测后进行阵内预测,这是调用的函数是xCheckRDCostIntra,在xCompressCU函数的后续部分,还递归调用自身以实现对每个CU的编码。比如,帧内预测的方向、帧间预测的分割方式、运动矢量预测,以及帧间预测参考图像索引号都属于预测单元的范畴。可以看到figure1位为I帧,采用的全是帧内编码,figure2为P帧,其中0.02%的帧内编码,13.99%的帧间编码,85.99%的skip模式(跳过型CU只能采用帧间预测模式,而且产生的运动向量和图像的残差信息不需要传送给解码器)。

2022-12-22 18:53:36 1634

原创 地平线面试知识点补充

而同时,把这个数据所在的数据也调入缓存,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存,加快访问速度,这是基于时间局部性原理(如果某个数据被访问,那么在不久的将来它很可能再次被访问)和空间局部性原理(如果某个数据被访问,那么与它相邻的数据很快也可能被访问)因此,如果我们查看内存中的某个字节,我们可能很快就会访问其邻居。这个自增的大小,由 CPU 的位宽决定,比如 32 位的 CPU,指令是 4 个字节,需要 4 个内存地址存放,因此「程序计数器」的值会自增 4;............

2022-08-15 22:27:25 1000

原创 C++ 多线程学习12 线程池

注意:用户可能大批量输入任务,若没有使用多线程则一次只能处理一个,效率非常低下,又不想无限制创建线程来处理他们,这可能导致系统崩溃,于是使用线程池一次只能处理16个任务,未处理的任务在任务队列tasks_中排队,(3)输入v时开始视频转码:先用make_shared来创建一个task对象,输入视频源,输出尺寸,保存信息等。(1)输入L时调用线程池的task_run_count(),返回任务计数,任务计数在task run前+1,结束时减1,main()在启动线程后紧跟一个无限循环,与用户在终端上进行交互,.

2022-08-05 23:10:04 915

原创 c++多线程学习11 packaged_task与async

调用之后,两个对象共享相同的共享状态(1).stdpackaged_task对象是异步提供程序(asynchronousprovider),应通过调用存储的任务(storedtask)在某个时刻将共享状态设置为就绪。等待结果返回,wait_for可设置超时时间,如果在超时时间之内任务完成,则返回stdfuture_statusready状态;packaged_task类的主要作用是把一个函数包装成一个对象,通过这个对象的访问的时候在函数的调用和返回值的获取可以拆分成两步。...............

2022-07-31 19:19:19 922

原创 C++多线程学习10 promise和future多线程异步传值

先创建一个测试线程对主线程的承诺p,再从p中获得future对象,用这个对象做为信物来接收承诺P产生的值,在创建线程的时候将这个承诺传过去,然后主线程想要获得信物的值,在测试线程对承诺设置值之前主线程将在get那等待,设置好值后将返回这个值:...

2022-07-30 21:56:12 499

原创 C++多线程学习09 条件变量

使用lamda表达式当收到信号后表达式返回true时运行下面的代码,返回false继续阻塞(这里的话就是当队列非空时运行下面的代码,空的时候继续阻塞),然后让其他消费者去判断。解决思路,让消费者一直阻塞,当生产者生产出东西了通知消费者取消阻塞,用锁可以达到,但是如果有多个消费者不能确定是让哪个消费者来消费,因此使用条件变量。生产者线程每隔三秒生成往队列中放入一个数据,并用条件变量发送信号,然后将生产者线程detach,不用去管理其线程资源。生成三个消费者线程,每个线程也做detach(),.........

2022-07-29 19:23:56 783

原创 C++多线程学习08 使用list和互斥锁进行线程通信

01无限循环中要加入sleep,不然可能入口函数可能一直占着CPU,(两个while循环中间隔很短,在这个间隔中CPU不一定能调度去执行其他线程,在这里的表现就是一直运行接收消息队列,发送消息队列一直获取不到锁,消息队列都空了还在接收,这样当然是不行的)stop()将退出标志位置为true,具体的线程类的线程入口会在while循环中通过该标志位来判断是否继续循环,然后调用wait等待当前线程退出。继承自抽象线程类,又定义了一个sendmsg函数,其他线程通过调用该函数来给该具体线程类传递消息(线程通信)..

2022-07-29 17:12:20 547

原创 利用wireshark对TCP抓包分析

TCP本身没有分段的概念,它的sequencenumber和acknowledgenumber是使TCP是基于流的协议的支撑,TCPsegmentofareassembledPDU的出现是因为Wireshark分析了其上层的HTTP协议而给出的摘要,如果配置Wireshark不支持HTTP协议解析。第一行因为这个包是在主机上抓的,所以最外层的是通过数据链路层封装的,数据链路层会将数据包封装陈帧(Frame),帧的序号就是这个包的序号,该包共64字节。...............

2022-07-23 12:44:25 6110 1

原创 关于DP中完全背包的遍历次序探讨

先回顾一下几个背包问题的定义:01背包:每个物品只有取或者不取两个状态完全背包:每个物品可以取无限多次多重背包:每个物品可以多次取,但次数不同众所周知,01背包使用二维dp可以任意交换物品顺序与背包顺序,用一维dp的话必须先物品再背包且背包为倒序,不然会重复拿物品,倒序遍历的原因是,本质上还是一个对二维数组的遍历,并且右下角的值依赖上一层左上角的值,因此需要保证左边的值仍然是上一层的,从右向左覆盖。完全背包完全背包的两个for循环的先后顺序都是可以的。注意,纯完全背包求得是能否凑成总和,即dp数组中存

2022-07-13 17:07:57 474 4

原创 C++多线程学习07 unique_lock与scoped_lock

补充一个关键字noexceptnoexcept形如其名地,表示其修饰的函数不会抛出异常。不过与throw()动态异常声明不同的是,在C++11中如果noexcept修饰的函数抛出了异常,编译器可以选择直接调用std::terminate()函数来终止程序的运行,这比基于异常机制的throw()在效率上会高一些。这是因为异常机制会带来一些额外开销,比如函数抛出异常,会导致函数栈被依次地展开(unwind),并依帧调用在本帧中已构造的自动变量的析构函数等。unique_lock与lock_guard()一样

2022-07-05 20:08:56 1379 1

原创 C++多线程学习06 利用RAII

RAII是C++的发明者Bjarne Stroustrup提出的概念,RAII全称是“Resource Acquisition is Initialization”,直译过来是“资源获取即初始化”,也就是说在构造函数中申请分配资源,在析构函数中释放资源。即使用局部资源来管理对象,在RAII的指导下,我们应该使用类来管理资源,将资源和对象的生命周期绑定。为什么需要用RAII来管理:除去忘了写解锁语句这种低级错误,还可能加锁之后抛出异常,无法正常解锁在RAII的指导下,我们应该使用(XMutex类)来管理资源

2022-07-01 12:10:43 535

原创 C++多线程学习05 超时锁,递归锁与共享锁

功能:避免长时间死锁,可以记录锁获取情况,多次超时,可以记录日志,获取错误情况在04中可以由于try_lock()不会阻塞该线程而是一直占着CPU资源,因此加入sleep_for(100ms)延时一会阻塞下该线程给其他线程一点机会,然而这的延时是调用的this_thread下的函数:也可以将延时做为锁的构造函数的参数,使用超时锁timed_mutex:同样的为了确保unlock能释放资源,最后延时一下:创建了三个线程,每个线程尝试解锁之后先阻塞500ms.........

2022-06-30 23:12:48 2291

原创 C++ 多线程学习04 多线程状态与互斥锁

初始化→就绪态:操作系统为线程分配好了资源,将其挂载CPU的就绪队列上。就绪→运行:该线程排在就绪队列队首元素,且CPU调度到了该线程(如时间片轮转算法、高响应比优先算法、短作业优先等),将其交给CPU去运行运行→就绪:正在CPU上运行的线程用于CPU的调度中断了运行,挂载就绪队列队尾就绪→阻塞:X运行→阻塞:当进程请求某一资源(如外设)的使用和分配或等待某一事件的发生(如IO操作的完成)时,它就从运行状态转换为阻塞状态。进程以系统调用的形式请求操作系统提供服务,这是一种特殊的、由运行用户态程序调用

2022-06-26 11:14:32 1347

原创 C++多线程03 Lambda表达式与caII once

先创建一个对象,该对象有一个成员name再调用该类的start方法,该方法将一个Lambda表达式包装成线程,并让该线程阻塞主线程,该Lambda表达式做为线程入口,捕获列表捕获了该对象的this指针,指明了打印哪个对象的name![在这里插入图片描述](https://img-blog.csdnimg.cn/2d0ef6ecb74840038a426e4820e8ddee.png)## 二、caII once多线程函数调用,但函数只进入一次比如多个线程都要初始化一个库,但只需要进入一次,可以使用

2022-06-26 10:37:28 481

原创 C++多线程学习02 线程的入口参数

可以看到02中无法访问para中的成员,这是因为虽然将子线程与主线程detach了,但只是将其句柄的周期交给了子线程,para的生命周期随着 }结束而结束01与03中使用join(),虽然访问的成员没有经过复制,但用join()阻塞了主线程,使其访问问para后主线程才将释放,因此不会出现问题04中即使将para的创建放在 {}中,其生命周期随着{}的结束而结束,但para在线程的构造函数中进行了复制,因此不会出现问题,正常访问。## 三、成员函数做为线程入口实际应用中经常将对象做为一个线程存

2022-06-25 21:54:24 507

原创 c++多线程学习01 对象生命周期和线程的退出与等待

子线程:main函数三种情况:01:这是因为在使用函数指针做为thread的构造函数的参数时,会生成一个句柄 _Thr._Hnd ,这个句柄的生命周期与主线程一致,当主线程结束时该句柄也会被释放掉,由于此时子线程还在运行,因此将会出错02用detach()使子线程与主线程分离,相当于将子线程变成一个守护线程,将其资源如句柄的生命周期交给子线程java的守护线程:守护线程,是指在程序运行时 在后台提供一种通用服务的线程,这种线程并不属于程序中不可或缺的部分。th.join()方法用于把子线程

2022-06-25 12:30:26 901 1

原创 HEVC学习之码流分析

以H.264为例:H.264适应不同网络之间的传输,主要原因是引入了分层结构,分为视频编码层(VCL)与网络抽象层(NAL),从而实现压缩编码与网络传输分离。通过H.264算法压缩的后的数据通过NAL-VCL接口封装成NAL包NAL的基本单元是NALU,而VCL层自上而下的结构如下所示:其中划分条带(slice)的目的是为了适应不同传输网络的最大传输单元(MTU)分组的目的是为了使数据独立于其他分组,从而实现特定的目的,比如防止误差扩散保证图像质量,区分前景背景以分别编码每个NALU由包头信息

2022-06-20 22:20:13 1352 2

原创 c++的输入输出

00,将getline放在while中会不断读txt中每一行,当读到文件尾时进不去while了01,因此用getline处理文件输入流时最后访问到文件尾,再getline就访问不到新东西了,因此打开两个文件流分别来处理QP和bit02,getline只会识别换行符与设定的分隔符,会将空格保存起来,因此可能要进行去空格操作03,letter.find_last_not_of("0123456789");//从末尾向前找到非数字的索引04,substr()若只有一个参数则是该参数为起点,然后一直到尾部

2022-06-16 00:04:40 398

原创 HEVC之HM学习02

main 和mian10主要区别是profile和内部位深不同。intra表示是全I帧编码,low delay和low delay_p表示只有第一帧是I 帧编码,而其他的都是P帧或者是B帧编码。randomaccess表示分批B帧结构,周期性的插入一些随机访问帧,rext是范围扩展,high-throughput是高吞吐量。将上述组合下,比如encoder_intra_main10.cfg为Profile 为main10的帧内编码模式。**profile**是对

2022-06-08 11:31:49 1452 1

原创 HEVC之HM学习01

(1) TAppCommon 编码器和解码器共用的应用函数(2) TAppDecoder 解码器的应用函数(3)TAppDecoderAnalyser 解码器分析的应用函数(4) TAppEncoder 编码器的应用函数(5) TLibCommon 编码器和解码器共用的库函数(6) TLibDecoder 解码器的库函数(7)TLibDecoderAnalyser 编码器分析的应用函数(8) TLibEncoder 编码器的库函数(9) TLibVideoIO 视频输入、输出库函数开始配

2022-06-07 21:15:32 382

原创 CPU眼里的: MMU | 空间独立性|虚拟内存

内存中拆分的基本单位称为页(内存分页,一个页4K),拆分开的进程与拆分开的内存通过页表进行映射,页表由页表项组成,每个页表项指出当前进程的代码在内存中映射到哪一页,在该页中的偏移地址是多少。如上图0x00003005的0x00003让MMU查看页表第3行的值,也就是0x80003000,也就是虚拟内存页对应的物理内存页的起始地址,其低12位(12位刚好可以访问到4K的地址,即一个页表都能访问到)005指该虚拟地址在内存页中对应第5个。至此得到了虚拟地址在内存上物理地址的映射为0x80003005。.....

2022-06-03 16:31:20 628

原创 策略模式.

这里是将策略模式与工厂模式结合,即将模式选择的部分交给了cashcontextcashcontext接收一个具体的策略对象(或者具体策略对象对应的标记),然后根据具体的策略对象,调用其算法的方法,在没有和策略模式结合时,具体算法由指向策略对象的父类指针调用,若增加策略时工厂类要增加case,还要实现要增加的具体的策略,这两者都是变化的,而策略模式的核心在于**封装变化点**,即将这二者的通过cashcontext进行封装,原本客户端需要看到工厂类与策略的父类这两个类,现在只需要看到cashcontext这

2022-06-01 17:45:56 147

原创 简单工厂模式

看起来代码长了很多,但代码的维护性与安全性得到了提升,这对于大型项目来说至关重要不管是windows程序,还是web程序等都可以使用该代码提供的接口,具有更高的移植性若要增加各种复杂的运算,比如平方根,立方根等只要增加相应的运算子类即可,而不需要去重新编译不用变化的子类。然后在工厂类中的switch中增加分支即可使用。

2022-06-01 16:02:25 141

原创 C++ 刷题语法整理

substr()是C++语言函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。如果没有指定长度_Count或_Count+_Off超出了源字符串的长度,则子字符串将延续到源字符串的结尾。——摘自百科词条语法substr(size_type _Off = 0,size_type _Count = npos)一种构造string的方法形式 : s.substr(pos, len)返回值: string,包含s中从pos开始的len个字符的**拷贝**(pos的默认值是0,len的默

2022-05-31 11:01:47 413

原创 C++的四种强制转换

断点查看运行到*b = 5;时a的值被设为5了,但最后cout的a的值仍然为1why?对于const数据我们更要这样保证:绝对不对const数据进行重新赋值。如果我们不想修改const变量的值,那我们又为什么要去const呢?原因是,我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数却是const的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。...

2022-04-27 20:10:17 4257

原创 压缩伪影的探讨

什么是块效应:块效应是在视频编码中人眼察觉到的小块边界处的不连续,只要是以块为单位进行的视频编码就会出现块效应,当以低码率传输时更为明显。为什么会造成块效应:DCT变换不是将一整张图进行dct变换,而是切成16X16,8X8,4X4的块进行变换,不同的图像块进行了不同的处理,有时是量化步长不同,有时是舍去的高频分量不同,这将导致图像块之间的相关性被破坏。当量化时采用的步长越大,或者相邻块的量化步长之差不同时更为明显(低码率时往往量化步长比较大,块效应更明显)。表现形式:梯形噪声:dct的高频系数被

2022-03-29 23:16:40 5606

原创 论文速读之A New Framework Based on Spatio-Temporal Information for Enhancing Compressed Video

摘要在视频压缩过程中会产生抽压缩伪影;人们提出了许多方法来解决这个问题。大部分使用光流去进行时域的运动补偿去获取更好时间信息。然而光流可能不准确,因为压缩视频可能会会被各种压缩伪影扭曲。光流还引入了额外的模型复杂性并且消耗很多算了。它也容易获得在显著运动和严重遮挡场景下误差传播的影响。针对这些问题,我们提出了一种高效的具有多帧结构,通过时空信息引导的质量增强网络。我们的算法采用了时空可变形卷积来聚合时间信息。我们定义输入作为目标帧及其相邻的参考帧联合预测偏移场以使时空变形取样位置。具体的,我们通过设计一个

2022-03-28 22:41:43 1639

原创 播放器实战28 总结

至此,播放器的基本功能已经实现需要注意的点:1.对于多个进程共享变量要加锁,即使是一句C++语句在汇编中也是很多句,若两个线程同时访问一个变量可能会造成问题2.要进行差错控制3.在vs中切换成release模式,并在项目中添加头文件与库文件,在运行后生成.exe文件首先介绍一下静态库(静态链接库)、动态库(动态链接库)的概念,首先两者都是代码共享的方式。静态库:在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷

2022-03-04 17:48:00 310

原创 播放器实战27 完成seek到指定位置

关于if (vt->RepaintPts(pkt, seekPts)):根据seek到的pts与实际想要的pts来判断是等待还是直接绘制等待时RepaintPts返回false,然后进入下次while绘制后RepaintPts返回true,然后更新当前的pts关于暂停:不管seek前视频是否为播放状态,则seek前统一暂停,不然如果正在播放的话解封装线程在seek,其他线程仍然在做解码,会出问题。如果seek前为播放状态,则seek结束后恢复播放,如果seek前为暂停状态,则seek结束后仍暂停

2022-03-01 21:36:56 1032

原创 播放器实战26 添加暂停

可能缓冲队列未播完,造成了音频播放停止的延迟,然后当if (audioplay->Getfree() < size):当缓冲中空余的空间小于需要使用的空间时等待一秒再continue(就不往播放器里写音频数据了)如果当不小时,即使isPause=true也会继续往里面写,因此把判断暂停也加进去:if (audioplay->Getfree() < size||isPause)再将音频线程中暂时设置的加锁取消掉,目的是早点停掉音频播放,并且isPause通过人为控制,只有两个状态,去锁了一般也不会造

2022-03-01 18:39:31 437

原创 播放器实战25 添加滑动条与窗口变化

当前解码到的pts除以总pts,是个比例,用该比例乘上进度条总长度获得一个值,用该值**传回进度条获得当前的播放位置**,并不能实现拖拽功能在xplay的构造函数中添加定时器

2022-02-28 22:21:26 294

原创 播放器实战24 解封装模块添加close

1.vt与at是解封装线程来调用的,因为解封装线程要负责来清理vt与at2.为了防止指针删到一半,然后其他线程突然来使用删掉的指针指针造成bug,因此要将这四句加锁3.我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身,因此还要将这些new出来的指针置null对于vt与at的close来说,它们有大部分功能都是一样的,因此把一样的功能放在他们的共同基类xdecodethread中:

2022-02-27 22:30:23 1896

原创 播放器实战23 解码线程

对于视频线程和音频线程来说其中有很多一模一样的内容,比如用于存放pkt的队列,最大数量,解码器,push,pop等,故将他们抽象出来做为一个基类(xdecodethread),让视频线程和音频线程继承这个类,便可以使用这些共有的成员:

2022-02-26 23:33:12 1996

原创 播放器实战22 解决花屏与卡顿问题

引入stridestride:指在内存中每行像素所占的空间。为了实现内存对齐每行像素在内存中所占的空间并不一定是像素的宽度,可能要在每行末尾加一些字节的数据来做内存对齐查看ffmpeg结构体AVFrame中的三个成员:01.uint8_t *data[AV_NUM_DATA_POINTERS];data存储原始的音视频数据(视频为YUV,音频为PCM)。有两种存储音视频的方式,plannar方式和packet方式plannar方式:通道n的数据分别存储在data[n]中;拿YUV视频来说,就是d

2022-02-21 22:08:02 3657

原创 播放器实战21 音视频同步

在 xaudioplay的子类audioplay中添加获取还未播放的时间的功能:用还未播放的字节数除以一秒音频的字节大小,再乘以1000,获得还未播放的时间(毫秒)

2022-02-20 17:46:34 820

原创 播放器实战21 解封装线程

1.在open中打开音频线程与视频线程2.当主函数调用解码线程的run时会调用xdemuxthread::start(),在该函数中调用音频线程的run与视频线程的run3.在run中通过读封装获得packet,判断其类型,若是视频则push给视频线程的队列,若是音频则push给音频线程的队列

2022-02-19 11:41:21 253

原创 播放器实战20 音频线程与视频线程

以音频线程为例,解封装模块调用音频线程模块,音频线程模块模块将声音播放模块,解码模块,重采样模块结合起来,用音频线程模块去调用其他模块。1.当isexit为false时,进入循环,队列为空或者没有初始化成功则解锁该线程,等待数据或者初始化,等1秒再判断一次2.当队列非空并且初始化成功之后,从队列头部弹出一个packet发给解码线程3. 可能一次send多次receive,因此一次send之后当调用析构函数使isexit=false之后或者 adecode->receive()将解码队列读干净后才进入到下

2022-02-19 11:15:29 908

原创 播放器实战19 Xaudio打开音频

  含有纯虚函数的类被称为抽象类。抽象类只能作为派生类的基类,不能定义对象,但可以定义指针。在派生类实现该纯虚函数后,定义抽象类对象的指针,并指向或引用子类对象。1)在定义纯虚函数时,不能定义虚函数的实现部分;2)在没有重新定义这种纯虚函数之前,是不能调用这种函数的。  抽象类的唯一用途是为派生类提供基类,纯虚函数的作用是作为派生类中的成员函数的基础,并实现**动态多态性**。继承于抽象类的派生类如果不能实现基类中所有的纯虚函数,那么这个派生类也就成了抽象类。因为它继承了基类的抽象函数,只要含有

2022-02-13 22:28:29 1153

wireshark抓包结果

https://blog.csdn.net/qq_42567607/article/details/125940614?spm=1001.2014.3001.5501的对应抓包结果,免费下载,可自行打开分析

2022-08-10

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除