解码端去方块滤波代码详述

解码端去方块滤波代码详述

作者:张戟(E-mail:[email protected])

       这部分在标准的8.7 Deblocking filter process有详细的描述,技术白皮书中也有专门讲去方块滤波的部分,因此在资料方面应该是不成问题。去方块滤波的代码主要集中在JM8.6 DecoderloopFilter.c文件中,入口函数为DeblockPicture(),此函数在image.cexit_picture()中被调用,也就是说这个去方块滤波模块是在解码完一幅图像后被调用的。这里,我不得不说,H.264中的去方块滤波做的太好了,朋友们可以自己尝试一下,在exit_picture()中注释掉DeblockPicture(),你会发现解码的PSNR会下降那么多。另外,我这边还要提醒做误码掩盖的朋友们,不知道你们是否注意过DeblockPicture()是在误码掩盖前被调用的,也就是说此时去方块滤波对丢失块的边界并没有使用滤波,所以在误码掩盖后再进行一次去方块滤波你可能会有不一样的收获,当然,我相信你不会傻乎乎的直接在误码掩盖后直接再次调用DeblockPicture()就完事了。

       虽然这部分的代码不是很长,但我并不认为就很好理解,我下面只是把我的注释代码公布了下(本来想写详细过程的,但写了一半觉得不好,全部删除了),如果有误,请大家指正。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include <stdlib.h>

#include <string.h>

#include "global.h"

#include "image.h"

#include "mb_access.h"

#include "loopfilter.h"

 

extern const byte QP_SCALE_CR[52] ;

extern StorablePicture *dec_picture;

 

byte mixedModeEdgeFlag, fieldModeFilteringFlag;

 

/*********************************************************************************************************/

 

#define  IClip( Min, Max, Val) (((Val)<(Min))? (Min):(((Val)>(Max))? (Max):(Val)))

 

// NOTE: to change the tables below for instance when the QP doubling is changed from 6 to 8 values

//       send an e-mail to [email protected] to get a little programm that calculates them automatically

 

///

//标准204页的表8-16或毕书141页的表6.23

byte ALPHA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,4,4,5,6,  7,8,9,10,12,13,15,17,  20,22,25,28,32,36,40,45,  50,56,63,71,80,90,101,113,  127,144,162,182,203,226,255,255} ;

byte  BETA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,2,2,2,3,  3,3,3, 4, 4, 4, 6, 6,   7, 7, 8, 8, 9, 9,10,10,  11,11,12,12,13,13, 14, 14,   15, 15, 16, 16, 17, 17, 18, 18} ;

///

 

//这边对应标准206页的表8-17或毕书144页的表6.24

//但是稍微有点不同,二维数组中的52指量化参数,5Bs强度从0-4

//从表中知道,Bs=34,他们的CLIP_TAB是相同的

byte CLIP_TAB[52][5]  =

{

  { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},

  { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},

  { 0, 0, 0, 0, 0},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 1, 1, 1, 1},

  { 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 2, 3, 3},

  { 0, 1, 2, 3, 3},{ 0, 2, 2, 3, 3},{ 0, 2, 2, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 3, 3, 5, 5},{ 0, 3, 4, 6, 6},{ 0, 3, 4, 6, 6},

  { 0, 4, 5, 7, 7},{ 0, 4, 5, 8, 8},{ 0, 4, 6, 9, 9},{ 0, 5, 7,10,10},{ 0, 6, 8,11,11},{ 0, 6, 8,13,13},{ 0, 7,10,14,14},{ 0, 8,11,16,16},

  { 0, 9,12,18,18},{ 0,10,13,20,20},{ 0,11,15,23,23},{ 0,13,17,25,25}

} ;

 

void GetStrength(byte Strength[16],struct img_par *img,int MbQAddr,int dir,int edge, int mvlimit,StorablePicture *p);

void EdgeLoop(byte** Img, byte Strength[16],struct img_par *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, int yuv);

void DeblockMb(ImageParameters *img, StorablePicture *p, int MbQAddr, int flag);

void CheckNeighbors(int mb_nr);

void searchErrorMB( int *errorMB, int downMB, int rightMB );

 

/*!

 *****************************************************************************************

 * /brief

 *    Filter all macroblocks in order of increasing macroblock address.

 *****************************************************************************************

 */

//deblock会减轻block效应,但同时会导致画面模糊,不过这样看起来会舒服很多,

//在某些方面来说确实是“提高”质量吧。

void DeblockPicture(ImageParameters *img, StorablePicture *p, int flag, int *errorMB)

{

  unsigned int i;

  unsigned int currLen = 0;

  int downMB, rightMB;

 

  if( flag )

  {

         for (i=0; i<p->PicSizeInMbs; i++)//循环遍历图像内的所有宏块

         {

                DeblockMb( img, p, i, flag );

         }

  }

  else

  {

         while( errorMB[currLen] != errorMBInit )

                currLen++;

               

         i = 0;

         while( errorMB[i] != errorMBInit && i < currLen )

         {

                downMB  = errorMB[i] + p->PicWidthInMbs;

                rightMB = errorMB[i] + 1;

               

                searchErrorMB( errorMB, downMB, rightMB );

                i++;

         }

 

         i = 0;

         while( errorMB[i] != errorMBInit )

         {

                DeblockMb( img, p, errorMB[i], flag );

                i++;

         }

  }

}

 

 

/*!

 *****************************************************************************************

 * /brief

 *    Deblocking filter for one macroblock.

 *****************************************************************************************

 */

 

void DeblockMb(ImageParameters *img, StorablePicture *p, int MbQAddr, int flag)

{

  int           EdgeCondition;

  int           dir,edge;

  byte          Strength[16];

  int           mb_x, mb_y;

 

  int           filterLeftMbEdgeFlag;

  int           filterTopMbEdgeFlag;

  int           fieldModeMbFlag;

  int           mvlimit=4;

  int           i, StrengthSum;

  Macroblock    *MbQ;

  byte **imgY   = p->imgY;

  byte ***imgUV = p->imgUV;

 

  img->DeblockCall = 1;//滤波的标志位

  get_mb_pos (MbQAddr, &mb_x, &mb_y);//MbQAddr0~nOfMB的序号

  //mb_xmb_y表示当前宏块的左上顶点的整像素的横纵坐标

  filterLeftMbEdgeFlag  = (mb_x != 0);

  filterTopMbEdgeFlag   = (mb_y != 0);

  //为什么要判断filterLeftMbEdgeFlagfilterTopMbEdgeFlag

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值