【H264解析Demo】10、变换量化_1_CAVLC结果还原为系数矩阵
前面已经通过cavlc解析出了numCoeff、trailingOnes、trailingSigns(拖尾系数符号)、levels、totalZeros、runBefore等值,在反变换量化之前,需要根据这些值还原系数矩阵
一、定义
定义数据保存矩阵:int m_residual_matrix_luma[16][4][4];
定义还原函数:Restore_coeff_matrix
二、知识储备
一个宏块在进行CAVLC编码时是如何划分的:4 * 4模式是如何划分的呢?首先将16 * 16的宏块划分成4个8 * 8的,每个8 * 8的都是由cbp的一个bit表示的
基本编程思路:cavlc结果->还原为8 * 8的矩阵->4 * 4的矩阵->再填充矩阵数组
三、代码实现
1、重建8 * 8系数矩阵框架:
//<变换量化><1>根据cavlc结果还原系数矩阵
void CResidual::Restore_coeff_matrix()
{UINT8 cbp_luma = m_macroblock_belongs->m_cbp_luma;UINT8 cbp_chroma = m_macroblock_belongs->m_cbp_chroma;//<变换量化><1>4*4宏块if (m_macroblock_belongs->m_mb_type == I4MB){for (int blk8Idx = 0; blk8Idx < 4; blk8Idx++){if (cbp_luma & (1 << blk8Idx)) //<变换量化><1>判断是否有系数矩阵{restore_8x8_coeff_block_luma(m_coeff_matrix_luma, blk8Idx, LUMA); //<变换量化><1>处理8*8的块,将里面4个4*4的系数矩阵都解析出来}}}
}
2、解析8 * 8矩阵
//<变换量化><1>重建8 * 8系数矩阵接口
void CResidual::restore_8x8_coeff_block_luma(int (*matrix)[4][4], int idx, int blockType)
{int blkColumnIdxStart = 2 * (idx / 2), blkRowIdxStart = 2 * (idx % 2); //<变换量化><2>计算宏块索引序号,宏块的计数是针对于整体16 * 16的块而言的,第一行0-3,第二行4-7for (int columnIdx = blkColumnIdxStart; columnIdx < blkColumnIdxStart + 2; columnIdx ++){for (int rowIdx = blkRowIdxStart; rowIdx < blkRowIdxStart + 2; rowIdx++){restore_4x4_coeff_block_luma(columnIdx, rowIdx, blockType);}}
}
3、解析4 * 4矩阵
void CResidual::restore_4x4_coeff_block_luma(int column_idx, int row_idx, int blockType)
{int max_coeff_num = 0, start_idx = 0;Coeff4x4Block *targetBlock = NULL;switch (blockType){case LUMA:max_coeff_num = 16;targetBlock = &luma_residual[column_idx][row_idx]; //<变换量化><2>前面cavlc解析出的结果break;case LUMA_INTRA16x16AC:start_idx = 1; //<变换量化><2>设置为1是因为直流分量已经被单独解析了,所以这里需要从1开始max_coeff_num = 15;targetBlock = &luma_residual16x16_AC[column_idx][row_idx];break;default:break;}int coeffBuf[16] = { 0 };UINT8 numCoeff = targetBlock->numCoeff, coeffIdx = numCoeff;UINT8 trailingOnes = targetBlock->trailingOnes, trailingLeft = trailingOnes;UINT8 totalZeros = targetBlock->totalZeros;// write trailing ones//<变换量化><2>[10 0 2 3 0 0 5 3 0 1....]//<变换量化><2>[10 2 3 5 3 1] 先写为这种,后面再补0for (int i = numCoeff - trailingOnes, j = trailingOnes - 1; j >= 0; j--){coeffBuf[i++] = targetBlock->trailingSign[j];}// write levels//<变换量化><2>写非零非拖尾系数的值for (int i = numCoeff - trailingOnes - 1; i >= 0; i--){coeffBuf[i] = targetBlock->levels[numCoeff - trailingOnes - 1 - i];}// move levels with run_before//<变换量化><2>[10 0 2 3 0 0 5 3 0 1....]//<变换量化><2>[10 2 3 5 3 1 0 0 0 0] totalZeros=4 - runBefore=1//<变换量化><2>[10 2 3 5 3 0 0 0 0 1] totalZeros=3 - runBefore=0//<变换量化><2>[10 2 3 5 0 0 0 3 0 1] totalZeros=3 - runBefore=2//<变换量化><2>[10 2 3 0 0 0 5 3 0 1]for (int i = numCoeff - 1; i > 0; i--){swap(coeffBuf[i], coeffBuf[i + totalZeros]);totalZeros -= targetBlock->runBefore[i];}swap(coeffBuf[0], coeffBuf[totalZeros]); //<变换量化><2>如果totalZeros还不为0,需要交换最低频前面的0insert_matrix(m_coeff_matrix_luma, coeffBuf, start_idx, max_coeff_num, column_idx, row_idx); //<变换量化><2>插入系数矩阵数组// int blkIdx = position_to_block_index(row_idx, column_idx);
// coeff_invers_transform(m_coeff_matrix_luma[blkIdx], m_residual_matrix_luma[blkIdx]);
}
4、填充系数矩阵数组:
注意因为是Z字型扫描,所以我们定义了一个坐标数组
【H264解析Demo】10、变换量化_1_CAVLC结果还原为系数矩阵相关推荐
- 【H264解析Demo】10、变换量化_3_反变换
代码实现 //<变换量化><4>反变换(参数1:保存反量化系数 参数2:保存反变换之后) void CResidual::coeff_invers_transform(int( ...
- python经典书籍推荐-推荐10本量化Python书单,好好学习天天向上
推荐10本量化Python书~Python非常灵活,让实验变得容易.解决简单问题的方法简单而优雅.Python为新手程序员提供了一个很好的实验室. Python具有一些特征,使其成为第一种编程语言的接 ...
- 自己做量化交易软件(10)通通量化AI框架的数据获取与格式
自己做量化交易软件(10)通通量化AI框架的数据获取与格式 我与2018年07月08日开始学习python编程和设计通通量化AI框架,到昨天晚上2018年10月30日,基本框架已经完成.能够显示K线图 ...
- HM编码器代码阅读(32)——帧间预测之AMVP/Merge模式(七)encodeResAndCalcRdInterCU函数:残差计算、变换量化
encodeResAndCalcRdInterCU 原理和细节 经过运动估计.运动补偿,我们得到了MV以及参考块,那么接下来是计算残差.计算MVD,然后对系数进行变换.量化. encodeResAnd ...
- HM编码器代码阅读(20)——与变换量化有关的其他知识
与变换量化有关的其他知识 变换 哈达玛变换 哈达玛变换是广义傅立叶变换的一种,它的变换矩阵Hm是一个2^m x 2^m的矩阵. 哈达玛变换及其矩阵有下面的几个特性: 1.hadamard矩阵元素都是正 ...
- PHP二维码解析demo
@TOPHP二维码解析demoC PHP二维码解析demo PHP二维码解析demo
- 【一起学习输入法】华宇拼音输入法开源版本解析(10)
[一起学习输入法]华宇拼音输入法开源版本解析(10) 原创:good02xaut(CSDN) 硬件框图
- wireshark添加h264解析插件
1.下载h264解析插件rtp_h264_extractor.lua https://github.com/volvet/h264extractor 2.将插件rtp_h264_extractor.l ...
- 深度学习与计算机视觉教程(10) | 轻量化CNN架构 (SqueezeNet,ShuffleNet,MobileNet等)(CV通关指南·完结)
作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/37 本文地址:https://www.showmeai.tech/article-d ...
最新文章
- Linux IPv6 地址配置
- python图像直方图与直方图均衡化
- IDE安装Lombok插件提高开发效率
- JavaScript---事件详解
- java 代码执行el,专属于java的漏洞——EL表达式注入
- 传智杯Java终端有一天您厌烦了电脑上又丑又没用的终端,打算自己实现一个 Terminal
- java=====Striing date 转化
- 野火IMJAVA开发的即时通讯系统源码
- Zcash已发布ZIP 313提案
- apply_async进程不执行_[粉丝问答6]子进程进程的父进程关系
- 00002-微信小游戏--触摸事件
- 2/8法则系列 | 你真的了解二八法则吗?
- 解决国内手机安装Google Play打开闪退问题
- LUN详解 iscsi
- 微信公众号自动回复多图文(php)
- GEA 1.6 运行时引擎架构
- linux 服务器端listen(5)
- SOLIDWORKS的钛合金分析
- Android 悬浮窗权限各机型各系统适配大全
- 质量基础设施一站式公共服务平台建设,NQI系统开发