从T264代码看帧内预测
来源:互联网 发布:mac怎么安装sass 编辑:程序博客网 时间:2024/05/19 17:05
越来越感觉到这种看标准和理解代码的方法的好处了,以前单看标准再单看x264都没甚么成果。现在一部分一部分的看代码和标准,虽然还有很多需要贯通起来,但是想一想已经了解一些了。或许前面就是个铺垫,又怎么会知道呢。毕竟以前不会再重来,未来还是需要自己去尝试的。或许过了几个月我又感觉到另外一种方法的好呢,这都不管了,现在我就是乐此不疲了!
首先看一组T264中的定义:
/*16x16模式的亮度4种预测*/
void T264_predict_16x16_mode_0_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_16x16_mode_1_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_16x16_mode_2_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_16x16_mode_20_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_16x16_mode_21_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_16x16_mode_22_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_16x16_mode_3_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
// 亮度预测的精确模式,一个9种
4x4 luma (6 functions)
void T264_predict_4x4_mode_0_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_1_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_2_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_20_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_21_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_22_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_3_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_4_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_5_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_6_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_7_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_4x4_mode_8_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
//色度模式的4种预测
// 8x8 chroma (7 functions)
void T264_predict_8x8_mode_0_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_8x8_mode_1_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_8x8_mode_2_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_8x8_mode_20_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_8x8_mode_21_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_8x8_mode_22_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
void T264_predict_8x8_mode_3_c (uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left);
上面的注释的几种是对应的标准中的说明,可以进行参照。而进行实现(T264)中的函数就变得多了,但是类型还是一样的,比如在亮度16x16的20、21、22就是对应的一个类型的预测,就是16x16中的所谓第二种DC预测模式。说起这个类型,在其他两个块中也是有的,就其说明来看,是很牛的:Mode 2 (DC prediction)
is modified depending on which samples A–M have previously been coded; each of the other
modes may only be used if all of the required prediction samples are available。模式2(DC预测):取决于A-M中在前面已经编码的采样进行修正,而其他的模式只能在其需要的象素全部可得的时候才可以用。这样看,好像其是很厉害的,用了甚么方法可以使得其不用要求固定象素可得来预测呢?其实这样也太为难人家了,谁也不能在甚么都不知道的情况下,做个精确的预测,而模式2其实就是一种很简单的处理,是在象素不可得的时候的一种很无赖的处理:牺牲了精确性。看代码:
// none available 注意:全不可得
//
void
T264_predict_16x16_mode_22_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left)
{
int32_t i, j;
for(i = 0 ; i < 16 ; i ++)
{
for(j = 0 ; j < 16 ; j ++)
{
dst[j] = 128;
}
dst += dst_stride;
}
}
原来全不可得的时候就是取个中值(256/2)。这是我个人认为最无赖的一段代码,但是反过来想也只有这样的办法了。而且在仔细想想,这种情况是很少的。虽然会给我们带来时间取理解。其他的两种模式(20、21)还说的过去,但是都比其他方法要粗糙。而在4x4亮度和8x8的色度中的这种方法也是类似的。
其实重点还是4x4的几种方法,在此说一个就够了。我们看这段代码:
//Mode 4 Intra_4x4_DIAGONAL_DOWNRIGHT when Top and left are available
void T264_predict_4x4_mode_4_c(uint8_t* dst, int32_t dst_stride, uint8_t* top, uint8_t* left)
{
uint8_t *cur_dst = dst;
*(cur_dst + 12) = (left[3] + (left[2] << 1) + left[1] + 2) >> 2;
*(cur_dst + 8) = *(cur_dst + 13) = (left[2] + (left[1] << 1) + left[0] + 2) >> 2;
*(cur_dst + 4) = *(cur_dst + 9) = *(cur_dst + 14) = (left[1] + (left[0] << 1) + *(left - 1) + 2) >> 2;
*(cur_dst) = *(cur_dst + 5) = *(cur_dst + 10) = *(cur_dst + 15) = (left[0] + (*(left - 1) << 1) + top[0] + 2) >> 2;
*(cur_dst + 1) = *(cur_dst + 6) = *(cur_dst + 11) = (*(top - 1) + (top[0] << 1) + top[1] + 2) >> 2;
*(cur_dst + 2) = *(cur_dst + 7) = (top[0] + (top[1] << 1) + top[2] + 2) >> 2;
*(cur_dst + 3) = (top[1] + (top[2] << 1) + top[3] + 2) >> 2;
}
这是在左和上都可得的情况下进行的4x4亮度第四种模式预测:下右。从参数开始看,dst肯定是目的象素地址了;dst_-stride目的象素每两行之间的距离(算完一行后,加上这个就可以到下一行,这段代码没用这个参数);top和left就是上面和左面的象素了(就是标准种的A-M,而这里用的到的就是ABCD,IJKLM,分别是top0-3,left0-3,而M既是top-1,也是left-1,可对应代码看)。用方块的画法看差值不是很明确,用点的方法就很好了。
。 。 。 。 。
。 x x x x
。 x x x x
。 x x x x
。 x x x x
从左上到下右方向45度画斜线,就可以这样分组(目的象素按行分别为0-15)0、5、10、15为一组;1、6、11为一组;2、7为一组;3为一组;4、9、14为一组;8、13为一组;12为一组。同组内的象素使用相同的象素点来预测。以0这组为例,画线表示该组象素和top0,left0,left-1(top-1)有关,那么就是这三个象素计算得到,很明显left-1(top-1)的关系重大一些,那么就是权重大就表示了。最后结果就是round(left0/4+left-1/2+top0/4),对比代码可以更为明确。而其他象素的计算也是类似的,就是中间的象素权重大,表示相关性高。
其他模式也是类似的方法,都是对应可得象素的情况来决定预测方式。
这就是帧内预测了。
- 从T264代码看帧内预测
- 从T264代码看H.264半象素插值
- Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测
- Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测
- Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测
- 关于cavlc的理解和t264代码分析
- T264 简介
- 【T264 简介】
- 灰色预测代码
- 关于T264代码中IDCT模块在DSP上的汇编优化
- [T264] VC6下调试T264编解码器全过程
- 帧内预测代码分析
- 帧内预测代码详解
- 利用分支预测优化代码
- Issue List on T264
- Linux下编译T264
- T264关键数据结构解析
- VS2005编译T264总结
- No such file or directory: Failed to enable the 'httpready' Accept Filter
- SQL Server如何得到用户的继承列表
- ADO.NET概述
- 不知道是不是TpageControl的bug
- Oracle彻底优化
- 从T264代码看帧内预测
- 品牌機,你的優勢在哪里?
- 一个HexToInt的C/C++函数
- php画K线图的一个工具
- 隐形大法:用暴风隐藏重要文件
- 什么是WIKI
- T5的页面生存周期
- VS2005[C#] 操作 Excel 全攻略(转贴)
- 如果你想推荐本文到CSDN 技术中心