R语言 机器学习 ASP.NET acm html 智慧树 powershell swing keras icons bootstrap后台管理系统 angular视频教程 安卓项目实战 python for循环 mysql查询 安装python教程 python新手教程 python语言入门 java9 java数据库连接 java环境配置 javasocket通信 java数据库 java自学教程 java基础课程 javaabstract java版本查看 java代码 decimalformat 图解设计模式 sql行转列 winhex使用教程 3dmax插件神器 网络文件服务器 微信彩色字 js分页 babelrc 大数据之路 allowtransparency 数据库编程软件
当前位置: 首页 > 学习教程  > 编程语言

x264中的熵编码 cavlc

2020/12/5 10:55:24 文章标签:

cavlc是以字段为单位来写数据的。代码位于cavlc.c中 主要函数 x264_macroblock_write_cavlc { cavlc_mb_header_i//包含预测模式 cavlc_mb_header_p//包含MVD, cavlc_mb_header_b//包含MVD cavlc_qp_delta//qp值 x264_cavlc_block_residual //残差 } cavl…

cavlc是以字段为单位来写数据的。代码位于cavlc.c中

主要函数

x264_macroblock_write_cavlc

{

cavlc_mb_header_i//包含预测模式

cavlc_mb_header_p//包含MVD,

cavlc_mb_header_b//包含MVD

cavlc_qp_delta//qp值

x264_cavlc_block_residual //残差

}

cavlc_mb_header_i 写了哪些信息?I 块没有MVD,只有intra预测模式

static void cavlc_mb_header_i( x264_t *h, int i_mb_type, int i_mb_i_offset, int chroma )

{

   bs_t *s = &h->out.bs;

  if( i_mb_type == I_16x16 )

  {//cbp 标示子块中哪些子块有残差信息

      bs_write_ue( s, i_mb_i_offset + 1 + x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode]  + h->mb.i_cbp_chroma * 4 + ( h->mb.i_cbp_luma == 0 ? 0 : 12 ) );//pred 模式,以及cbp

 }

else //if( i_mb_type == I_4x4 || i_mb_type == I_8x8 )

{

  int di = i_mb_type == I_8x8 ? 4 : 1;

  bs_write_ue( s, i_mb_i_offset + 0 );

  if( h->pps->b_transform_8x8_mode )

  bs_write1( s, h->mb.b_transform_8x8 );

 

/* Prediction: Luma */

for( int i = 0; i < 16; i += di )

{

int i_pred = x264_mb_predict_intra4x4_mode( h, i );// 存储预测模式

int i_mode = x264_mb_pred_mode4x4_fix( h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] ); 

 

if( i_pred == i_mode )

bs_write1( s, 1 ); /* b_prev_intra4x4_pred_mode */

else

bs_write( s, 4, i_mode - (i_mode > i_pred) );

}

 

}

if( chroma )

    bs_write_ue( s, x264_mb_chroma_pred_mode_fix[h->mb.i_chroma_pred_mode] );

}

cavlc_mb_header_p//有哪些信息

cavlc_mvd( h, 0, 0, 4 );// 各种不同的模式都需要存储mvd

bs_write_ue 无符号指数哥伦布编码写参考帧

else //if( IS_INTRA( i_mb_type ) )

cavlc_mb_header_i( h, i_mb_type, 5, chroma ); //写颜色相关的信息

cavlc_mb_header_b// B帧

先写子块形状

bs_write_ue( s, subpartition_b_to_golomb[ h->mb.i_sub_partition[i] ] );

bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[i*4]] ); //参考帧,向前参考

bs_write_te( s, h->mb.pic.i_fref[1] - 1, h->mb.cache.ref[1][x264_scan8[i*4]] );//向后参考

写qp值

static void cavlc_qp_delta( x264_t *h )

{

bs_t *s = &h->out.bs;

int i_dqp = h->mb.i_qp - h->mb.i_last_qp;//qp差值

 

/* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely

* flat background area. Don't do this if it would raise the quantizer, since that could

* cause unexpected deblocking artifacts. */

if( h->mb.i_type == I_16x16 && !(h->mb.i_cbp_luma | h->mb.i_cbp_chroma)

&& !h->mb.cache.non_zero_count[x264_scan8[LUMA_DC]]

&& !h->mb.cache.non_zero_count[x264_scan8[CHROMA_DC+0]]

&& !h->mb.cache.non_zero_count[x264_scan8[CHROMA_DC+1]]

&& h->mb.i_qp > h->mb.i_last_qp )

{

#if !RDO_SKIP_BS

h->mb.i_qp = h->mb.i_last_qp;

#endif

i_dqp = 0;//如果是skip块,i_dqp = 0;

}

 

if( i_dqp )

{

if( i_dqp < -(QP_MAX_SPEC+1)/2 )

i_dqp += QP_MAX_SPEC+1;

else if( i_dqp > QP_MAX_SPEC/2 )

i_dqp -= QP_MAX_SPEC+1;

}

bs_write_se( s, i_dqp ); //写qp值

}

static ALWAYS_INLINE void cavlc_macroblock_luma_residual( x264_t *h, int plane_count )

{

if( h->mb.b_transform_8x8 )

{

/* shuffle 8x8 dct coeffs into 4x4 lists */

for( int p = 0; p < plane_count; p++ )

for( int i8 = 0; i8 < 4; i8++ )

if( h->mb.cache.non_zero_count[x264_scan8[p*16+i8*4]] )

h->zigzagf.interleave_8x8_cavlc( h->dct.luma4x4[p*16+i8*4], h->dct.luma8x8[p*4+i8],

&h->mb.cache.non_zero_count[x264_scan8[p*16+i8*4]] );

}

 

for( int p = 0; p < plane_count; p++ )

FOREACH_BIT( i8, 0, h->mb.i_cbp_luma )// cpb 标示的有残差的块

for( int i4 = 0; i4 < 4; i4++ )

x264_cavlc_block_residual( h, DCT_LUMA_4x4, i4+i8*4+p*16, h->dct.luma4x4[i4+i8*4+p*16] );//按4x4的块写

}

 

 

 

 

 

 


本文链接: http://www.dtmao.cc/news_show_450348.shtml

附件下载

上一篇:注解合并

下一篇:Windows环境下安装Redis

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?