宏块在经过变换、量化后,得到大小为4x4或者8x8的矩阵,矩阵中的数据被称为transform coefficient levels。这些level在后面会被用于熵编码,因此我们需要把矩阵按照一定顺序进行扫描,得到数字序列。

扫描顺序在帧与场会有所不同

4x4块矩阵的扫描顺序如下

              

Zig-zag scan(Frame)                          Field scan

8x8块矩阵的扫描顺序如下

           

Zig-zag scan(Frame)                                  Field scan           

在实际的代码处理上(JM),对变换系数的扫描过程是包含在量化过程中的,因为对矩阵内的元素的量化也是逐个进行的,因此就可以按照对变换系数扫描的顺序取出矩阵内的元素进行量化,后续就能直接对这些transform coefficient level序列进行熵编码。

int quant_4x4_normal(Macroblock *currMB, int **tblock, struct quant_methods *q_method)
{
VideoParameters *p_Vid = currMB->p_Vid;
QuantParameters *p_Quant = p_Vid->p_Quant;
Slice *currSlice = currMB->p_Slice;
Boolean is_cavlc = (Boolean) (currSlice->symbol_mode == CAVLC); int block_x = q_method->block_x;
int qp = q_method->qp;
int* ACL = &q_method->ACLevel[0];
int* ACR = &q_method->ACRun[0];
LevelQuantParams **q_params_4x4 = q_method->q_params;
const byte (*pos_scan)[2] = q_method->pos_scan;
const byte *c_cost = q_method->c_cost;
int *coeff_cost = q_method->coeff_cost; LevelQuantParams *q_params = NULL;
int i,j, coeff_ctr; int *m7;
int scaled_coeff; int level, run = 0;
int nonzero = FALSE;
int qp_per = p_Quant->qp_per_matrix[qp];
int q_bits = Q_BITS + qp_per;
const byte *p_scan = &pos_scan[0][0]; // Quantization
// 4x4 block matrix has 16 coefficients
for (coeff_ctr = 0; coeff_ctr < 16; ++coeff_ctr)
{
//scanning positions (Zig-zag scan or Field scan)
i = *p_scan++; // horizontal position
j = *p_scan++; // vertical position //block_x,block_y here is the position of a block on a Macroblock with the unit of pixel
m7 = &tblock[j][block_x + i]; if (*m7 != 0)
{
q_params = &q_params_4x4[j][i];
scaled_coeff = iabs (*m7) * q_params->ScaleComp;
level = (scaled_coeff + q_params->OffsetComp) >> q_bits; if (level != 0)
{
if (is_cavlc)
level = imin(level, CAVLC_LEVEL_LIMIT); *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; level = isignab(level, *m7);
*m7 = rshift_rnd_sf(((level * q_params->InvScaleComp) << qp_per), 4);
// inverse scale can be alternative performed as follows to ensure 16bit
// arithmetic is satisfied.
// *m7 = (qp_per<4) ? rshift_rnd_sf((level*q_params->InvScaleComp),4-qp_per) : (level*q_params->InvScaleComp)<<(qp_per-4);
*ACL++ = level;
*ACR++ = run;
// reset zero level counter
run = 0;
nonzero = TRUE;
}
else
{
*m7 = 0;
++run;
}
}
else
{
++run;
}
} *ACL = 0; return nonzero;
}

h.264 scanning process for transform coefficients的更多相关文章

  1. H.264视频的RTP荷载格式

    Status of This Memo This document specifies an Internet standards track protocol for the   Internet ...

  2. H.264 Transform

    变换是视频.图像编码的核心部分.目前所采用的变换算法都是从傅里叶变换演变而来.单纯的变换并不会导致视频(图像)的码率变小,反而会增大.但是非常巧妙的一点是:变换把图像从空域转换成的时域,把由色块组成的 ...

  3. h.264 Mode Decision

    Mode Decision(模式选择)决定一个宏块以何种类型进行分割.宏块的分割类型有以下几种: //P_Skip and B_Skip means that nothing need to be e ...

  4. H.264 / MPEG-4 Part 10 White Paper-翻译

    1. Introduction Broadcast(广播) television and home entertainment(娱乐) have been revolutionised(彻底改变) b ...

  5. [ffmpeg] h.264解码所用的主要缓冲区介绍

    在进行h264解码过程中,有两个最重要的结构体,分别为H264Picture.H264SliceContext. H264Picture H264Picture用于维护一帧图像以及与该图像相关的语法元 ...

  6. h.264语法结构分析

    NAL Unit Stream Network Abstraction Layer,简称NAL. h.264把原始的yuv文件编码成码流文件,生成的码流文件就是NAL单元流(NAL unit Stre ...

  7. h.264参考图像列表、解码图像缓存

    1.参考图像列表(reference picture list) 一般来说,h.264会把需要编码的图像分为三种类型:I.P.B,其中的B.P类型的图像由于采用了帧间编码的这种编码方式,而帧间编码又是 ...

  8. H.264, MPEG4之间的关系

    百度百科搜索 H.264 H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式.H.264是ITU-T以H.26x系列为名称命名的视频编解码技 ...

  9. H.264 Profile

    提到High Profile H.264解码许多人并不了解,那么到底什么是High Profile H.264解码?其应用效果又是如何呢?  作为行业标准,H.264编码体系定义了4种不同的Profi ...

随机推荐

  1. VC++ 获取windows系统的版本类型

    vc中获取windows版本信息,一般是调用GetVersionEx 这个API函数来获取的,这个API需要OSVERSIONINFOEX 这个结构体作为参数,OSVERSIONINFOEX 的对应的 ...

  2. Java 之文件IO编程 之写入

    package com.sun; /* * 操作对文件IO的写 * 2014-08-10 */ import java.io.*; public class File_Write { public s ...

  3. 浅谈Mamcached集成web项目

    1.资源文件配置 config.properties 添加 #memcached服务器地址 memchchedIP=192.168.1.8 2.编写工具类 MemUtils package cn.co ...

  4. WisDom.Net 框架设计(八) 持久层

    WisDom.Net ---持久层  1.什么是持久层        持久层负责最基础的功能支撑,为项目提供一个高层,统一,和并发的数据持久机制,提供了比如建立数据库连接,关闭数据库连接,执行sql语 ...

  5. [上传下载] C#修改DownLoadHelper上传下载帮助类 (转载)

    点击下载 DownLoadHelper.rar 主要功能如下 /// <summary> /// 输出硬盘文件,提供下载 支持大文件.续传.速度限制.资源占用小 /// </summ ...

  6. python基础知识九

    sys模块 sys模块包含系统对应的功能.我们已经学习了sys.argv列表,它包含命令行参数. 命令行参数 例14.1 使用sys.argv #!/usr/bin/python # Filename ...

  7. 删除svn密码方法

    很多时候使用svn,我们需要切换svn账号,但是由于之前的账号已经选择了记住密码,那么我们应该如何删除svn密码来切换新的svn账号呢? 其实很简单,svn账号密码信息保存在电脑某一文件中,我们只要删 ...

  8. 【工具篇】source Insight

    不多说,阅读代码利器. 一.修改背景颜色 使用淡绿色更护眼(听说而已),菜单“选项”>>“属性”,使用自己喜欢的颜色吧.我的淡绿色RGB是181,236,207 二.行号,空格替换tabs ...

  9. HDU1878欧拉回路

    这道题WA了好多次.测试数据感觉有点问题-- 并查集啊,必须有. #include<stdio.h> #include<string.h> int ad[1003]; int ...

  10. C++单元测试2

    这里再对上一篇<C++单元测试>进行技巧补充. 我们知道对动态链接库(lib和dll)的测试是比较简单的,我这里主要对需要注意的地方说明一下. 1.建议单独创建单元测试解决方案(不是创建项 ...