264 参考帧 list0 list1

本文详细探讨了H.264编码标准中参考帧的使用机制,包括P帧与B帧的不同参考方式,以及如何在解码过程中确定参考帧。解释了short-term与long-term参考帧的区别,并介绍了参考帧列表(list0和list1)的更新与维护过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作了这么久的h264工作,这部分还一直从未去深入了解过,真是不求甚解啊,那帮老外的代码也写得太全了,该部分至今天才开始研究

首先参考帧这里关注的是两种,p ,b ,前向参考和后向参考

由白皮书中看到,p帧的参考帧都在list0中,该list0可以包含p帧之前的也可以是之后(播放次序),这里的之后并不是说p帧成b帧了,这就是264搞这么复杂的因素吧,

解码编码时,一个帧(暂且不考虑多slice)只能被标示为

a,不是参考帧

b,放在short-term中作参考帧

c,放在long-term中作参考帧

d, 直接输出显示

我在这里就直接翻译白皮书了,一个关键点,P帧只参考list0,B帧则list0,list1皆可

list0中,short-term中图像由自带的picnum(每个图像都有的一个变量),计算出一个值,然后从高到低排列在short-term中,long-term也是如此,但是它次序是从低到高,每次编码解码完一帧,这个次序会随之变动,如果码流中标示变动的话。最后会由于这个因素,长江后浪推前浪,前浪被推出参考序列(因为参考序列中的数目是固定的,比如标准最多是16,编码器可控)。编码器可任意对list0中参考帧进行变动。

具体解码中,这个参考方式是细化到宏块,甚至4x4的子快,一个宏块头信息中标示着内部参考方式,如果可能,多到16种。通过这个数目从list0中找出参考帧。

需要说明一下白皮书中的例子

list0:,假设参考帧是5个,

正常情况下,编完一帧都是把他放到最近的short-term中,意味着最容易被参考到,如果编码器其需要改动,就会把某一帧放到short-term的后面,就是long-term,这些都是按照longtermpicnum,shortpicnum的大小次序存放。而0,1,2,3,4,则会在每一个宏块甚至子块的解码过程中用到。

IDR帧将上述的次序全部清零,重新开始排序。

边看标准和代码,别写下这些文字,没有整理,凑合看吧。

B帧的list1,也是按照list0的排列规则存放,然后具体到每个宏块,则可能该宏块同时参考到list0和list1,那就是需要avg的算法了,绝大部分编解码都有该关键词来处理B帧。

等有空放上具体代码及详解。


<think>我们正在解决Unity游戏运行时显示0帧的问题。0帧通常意味着游戏卡在某一帧无法更新,可能由死循环、阻塞操作或引擎崩溃导致。根据经验,常见原因包括:1.脚本中存在无限循环或阻塞操作(如未正确终止的while循环)2.资源加载阻塞主线程(如同步加载大量资源)3.物理引擎或动画系统异常4.渲染问题(如着色器编译卡住)解决步骤:1.使用调试器或日志定位问题:在代码中添加Debug.Log输出,确定卡顿位置。2.检查最近修改的脚本:特别是循环、协程、物理回调等。3.分析堆栈:若游戏无响应,可使用UnityProfiler或外部调试器(如VisualStudio)附加到进程查看主线程堆栈。示例:一个常见的死循环错误```csharpvoidUpdate(){while(condition){//condition永远为真且没有退出机制//执行操作}}```应改为使用协程或确保循环能退出。另一个常见问题:同步加载大型资源```csharpvoidStart(){//同步加载大量资源会导致主线程卡住Texture2DlargeTexture=Resources.Load<Texture2D>("veryLargeTexture");}```改为异步加载:```csharpIEnumeratorLoadTextureAsync(){ResourceRequestrequest=Resources.LoadAsync<Texture2D>("veryLargeTexture");yieldreturnrequest;Texture2Dtexture=request.assetasTexture2D;//使用texture}```此外,检查是否在Unity主线程中进行了耗时计算(如复杂物理模拟、路径搜索等),这些应移至后台线程或分帧处理。如果问题无法通过代码解决,可尝试:-重置Unity布局(有时编辑器问题)-重启Unity-更新Unity版本若在特定平台出现,检查平台相关设置(如图形API、分辨率等)。参考引用:[^1]:关于显示不一致的问题,可能与分辨率设置有关,但0帧问题更可能是代码逻辑导致。[^2]:全屏设置可能导致渲染问题,但通常不会导致0帧,可尝试取消全屏测试。相关问题:1.如何避免在Unity中造成主线程阻塞?2.Unity中如何正确使用多线程?3.UnityProfiler的使用方法有哪些?</think>### 解决Unity游戏运行时显示0帧问题 在Unity中遇到游戏运行时显示0帧的问题,通常表示游戏卡在某一帧无法更新。以下是系统性的解决方案: --- ### 一、常见原因与解决方案 1. **无限循环阻塞主线程** - 检查代码中是否存在未正确退出的`while`循环或递归调用 - 解决方案: ```csharp // 错误示例:未设置退出条件的循环 void Update() { while(condition) { // 卡死主线程 // 逻辑代码 } } // 正确做法:改用协程或分帧处理 IEnumerator SafeCoroutine() { while(condition) { yield return null; // 每帧执行一次 } } ``` 2. **同步加载大型资源** - 同步加载`Resources.Load()`大文件会导致主线程卡顿 - 解决方案: ```csharp // 异步加载资源 IEnumerator LoadAssetAsync() { ResourceRequest request = Resources.LoadAsync<Texture>("largeImage"); yield return request; // 使用request.asset } ``` 3. **物理引擎死锁** - 复杂物理碰撞可能引发引擎死锁(常见于FixedUpdate) - 检查项: - 刚体互锁(Rigidbody相互卡住) - 过小的Fixed Timestep(Edit > Project Settings > Time) - 临时方案:在编辑器中暂停物理模拟测试 4. **渲染管线阻塞** - 检查是否触发了GPU无限等待: - 着色器编译错误(查看Console报错) - RenderTexture配置错误 - 解决方案: - 更新显卡驱动 - 简化复杂Shader --- ### 二、诊断工具 1. **使用Profiler定位** - 菜单栏 > Window > Analysis > Profiler - 重点观察: - `Main Thread`的CPU占用率 - `Physics.Processing`耗时 - `Gfx.WaitForPresent`(GPU等待) 2. **控制台日志过滤** - 启用`Error Pause`(Console窗口右上角) - 过滤`Error`和`Warning`级别日志 3. **最小化测试法** 1️⃣ 新建空场景测试基础性能 2️⃣ 逐模块添加功能(物理、UI、脚本等) 3️⃣ 定位到具体引发卡顿的组件 --- ### 三、高级修复方案 1. **多线程优化** ```csharp // 将耗时计算移至后台线程 ThreadPool.QueueUserWorkItem(state => { ComplexCalculation(); // 注意:Unity API不能在子线程调用 }); ``` 2. **分帧处理** ```csharp // 将大任务拆分成多帧执行 IEnumerator ProcessLargeData() { foreach(var item in bigList) { ProcessItem(item); yield return null; // 每帧处理一个 } } ``` 3. **引擎设置调整** - 修改`Time Manager`设置(Edit > Project Settings > Time): - 降低`Maximum Allowed Timestep`(默认0.333) - 提高`Fixed Timestep`(默认0.02) - 关闭垂直同步: ```csharp QualitySettings.vSyncCount = 0; Application.targetFrameRate = 60; ``` --- ### 四、特定平台处理 - **Android/iHL**: 检查`Graphics API`(Player Settings)兼容性,建议关闭`Multithreaded Rendering` - **WebGL**: 在`Player Settings > Publishing Settings`启用`Exceptions`为`Full`捕获异步错误 > 若仍无法解决,建议重置Unity布局(Window > Layouts > Revert Factory Settings)或升级Unity版本[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值