⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text_code_mb.c

📁 mpeg4源代码
💻 C
字号:

/**************************************************************************
该文件包含了宏块纹理编码的函数代码
***************************************************************************/

#include "text_code.h"
#include "text_dct.h"

#define BLOCK_SIZE 8

Void    BlockPredict (SInt *curr, /*SInt *rec_curr,*/
    Int x_pos, Int y_pos, UInt width, Int fblock[][8]);
Void    BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
    Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]);
Void    BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type,
    Int *qcoeff, Int maxDC, Int image_type);
Void    BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type,
    Int *rcoeff, Int image_type, Int short_video_header, Int bits_per_pixel);


/***********************************************************CommentBegin******
 函数功能:
 编码、解码重建的视频宏块
 函数输入:
 Int x_pos  宏块的x轴方向坐标
 Int y_pos  宏块的y轴方向坐标
 UInt width Vop边界会的宽度
 Int QP     量化参数
 Int Mode   宏块编码模式
 函数输入/输出:
 Vop *curr  当前未编码的视频对象平面
 Vop *rec_curr  当前解码并重建的视频对象平面
 Vop *comp      当前已经过运动补偿后的视频对象平面
 Int *qcoeff    系数块(384 * sizeof(Int))
 *
 ***********************************************************CommentEnd********/

Void CodeMB(Vop *curr, Vop *rec_curr, Vop *comp, Int x_pos, Int y_pos, UInt width,
Int QP, Int Mode, Int *qcoeff)
{
    Int k;
    Int fblock[6][8][8];
    Int coeff[384];
    Int *coeff_ind;
    Int *qcoeff_ind;
    Int* rcoeff_ind;
    Int x, y;
    SInt *current, *recon, *compensated = NULL;
    UInt xwidth;
    Int iblock[6][8][8];
    Int rcoeff[6*64];
    Int i, j;
    Int type;                                     /* luma = 1, chroma = 2 */
//  Int *qmat;
    SInt tmp[64];
    Int s;

    int operation = curr->prediction_type;
    /* This variable is for combined operation.
    If it is an I_VOP, then MB in curr is reconstruct into rec_curr,
    and comp is not used at all (i.e., it can be set to NULL).
    If it is a P_VOP, then MB in curr is reconstructed, and the result
    added with MB_comp is written into rec_curr. 
    - adamli 11/19/2000 */

    Int max = GetVopBrightWhite(curr);
    /* This variable is the max value for the clipping of the reconstructed image. */

    coeff_ind = coeff;
    qcoeff_ind = qcoeff;
    rcoeff_ind = rcoeff;

    for (k = 0; k < 6; k++)
    {
        switch (k)
    	{
            case 0:
                x = x_pos;
                y = y_pos;
                xwidth = width;
                current = (SInt *) GetImageData (GetVopY (curr));
            	break;
            case 1:
                x = x_pos + 8;
                y = y_pos;
                xwidth = width;
                current = (SInt *) GetImageData (GetVopY (curr));
            	break;
            case 2:
                x = x_pos;
                y = y_pos + 8;
                xwidth = width;
                current = (SInt *) GetImageData (GetVopY (curr));
            	break;
            case 3:
                x = x_pos + 8;
                y = y_pos + 8;
                xwidth = width;
                current = (SInt *) GetImageData (GetVopY (curr));
            	break;
            case 4:
                x = x_pos / 2;
                y = y_pos / 2;
                xwidth = width / 2;
                current = (SInt *) GetImageData (GetVopU (curr));
            	break;
            case 5:
                x = x_pos / 2;
                y = y_pos / 2;
                xwidth = width / 2;
                current = (SInt *) GetImageData (GetVopV (curr));
            	break;
            default:
            	break;
    	}
        BlockPredict (current, x, y, xwidth, fblock[k]);
    }

    for (k = 0; k < 6; k++)
    {
        s = 0;
        for (i = 0; i < 8; i++)
            for (j = 0; j < 8; j++)
                tmp[s++] = (SInt) fblock[k][i][j];
#ifndef _MMX_
        fdct_enc(tmp);
#else
        fdct_mm32(tmp);
#endif
        for (s = 0; s < 64; s++)
            coeff_ind[s] = (Int) tmp[s];

        if (k < 4) type = 1;
        else type = 2;

        /* For this release, only H263 quantization is supported. - adamli */
        BlockQuantH263(coeff_ind,QP,Mode,type,qcoeff_ind,
            GetVopBrightWhite(curr),1);
        BlockDequantH263(qcoeff_ind,QP,Mode,type,rcoeff_ind,1, 0, GetVopBitsPerPixel(curr));

        for (s = 0; s < 64; s++)
            tmp[s] = (SInt) rcoeff_ind[s];
#ifndef _MMX_
        idct_enc(tmp);
#else
        Fast_IDCT(tmp);
#endif
        s = 0;
        for (i = 0; i < 8; i++)
            for (j = 0; j < 8; j++)
                iblock[k][i][j] = (Int)tmp[s++];

        coeff_ind += 64;
        qcoeff_ind += 64;
        rcoeff_ind += 64;

        if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)
            for (i = 0; i < 8; i++)
                for (j = 0; j < 8; j ++)
                    iblock[k][i][j] = MIN (GetVopBrightWhite(curr), MAX (0, iblock[k][i][j]));

        switch (k)
    	{
            case 0:
            case 1:
            case 2:
                continue;

            case 3:
                recon = (SInt *) GetImageData (GetVopY (rec_curr));
                if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopY (comp));
                BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos,     width, 16, iblock[0]);
                BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos,     width, 16, iblock[1]);
                BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos + 8, width, 16, iblock[2]);
                BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos + 8, width, 16, iblock[3]);
                continue;

            case 4:
                recon = (SInt *) GetImageData (GetVopU (rec_curr));
                if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopU (comp));
                BlockRebuild (recon, compensated, operation, max,
                    x_pos/2, y_pos/2, width/2, 8, iblock[4]);
                continue;

            case 5:
                recon = (SInt *) GetImageData (GetVopV (rec_curr));
                if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopV (comp));
                BlockRebuild (recon, compensated, operation, max,
                    x_pos/2, y_pos/2, width/2, 8, iblock[5]);
                continue;
    	}
    }

    return;
}


/***********************************************************CommentBegin******
 函数功能:
对一个帧内宏块进行预测,并得到它的预测结果。
函数输入:
1) nt x_pos:宏块的x方向的空间位置;
2) nt y_pos:宏块的y方向的空间位置;
3) Int width:宏块所在视频对象平面的边界框的宽度。
函数输出:
Int fblock[][8]:将要进行编码的预测宏块,输出到数据流中。
函数输入/输出:
1)SInt* curr   :当前未编码的视频对象平面数据;
2)SInt* rec_curr:重建视频对象平面数据的区域

 *
 ***********************************************************CommentEnd********/
Void
BlockPredict (SInt *curr, /*SInt *rec_curr,*/ Int x_pos, Int y_pos,
UInt width, Int fblock[][8])
{
    Int i, j;

    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 8; j++)
    	{
            fblock[i][j] = curr[(y_pos+i)*width + x_pos+j];
    	}
    }
}


/***********************************************************CommentBegin******
函数功能:
在视频对象平面数据区域中重建一个宏块。
函数输入:
1) nt x_pos:宏块的x方向的空间位置;
2) Int y_pos:宏块的y方向的空间位置;
3)UInt width:宏块所在视频对象平面的边界框的宽度。
函数输出:
SInt* rec_curr:当前将要重建的视频对象平面数据区域。
函数描述:
对帧内的预测块也进行重建。

 ***********************************************************CommentEnd********/

Void BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,
Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8])
{
    /* 本函数将同时重建块和产生新的误差*/
    Int i, j;
    SInt *rec;
    Int padded_width;
    
    padded_width = width + 2 * edge;
    rec = rec_curr + edge * padded_width + edge;

    if (pred_type == I_VOP)
    {
        SInt *p;
        p  = rec + y_pos * padded_width + x_pos;

        for (i = 0; i < 8; i++) 
    	{
            for (j = 0; j < 8; j++)
    		{
                SInt temp = fblock[i][j];
                *(p++) = CLIP(temp, 0, max);
    		}

            p += padded_width - 8;
    	}
    }
    else if (pred_type == P_VOP)
    {
        SInt *p, *pc; 
        p  = rec + y_pos * padded_width + x_pos;
        pc = comp     + y_pos * width + x_pos;

        for (i = 0; i < 8; i++)
    	{
            for (j = 0; j < 8; j++)
    		{
                SInt temp = *(pc++) + fblock[i][j];
                *(p++) = CLIP(temp, 0, max);
    		}
            p += padded_width - 8;
            pc += width - 8;
    	}
    }
}




/***********************************************************CommentBegin******
 函数功能:
 *  8x8宏块量化
 函数输入:
 Int *coeff 未量化系数
 Int QP     量化参数
 Int Mode   宏块编码模式
 函数输出:
 Int *qcoeff    已量化系数
***********************************************************CommentEnd********/
Void
BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type, Int *qcoeff, Int maxDC, Int image_type)
{
    Int i;
    Int level, result;
    Int step, offset;
    Int dc_scaler;

    if (!(QP > 0 && (QP < 32*image_type))) return;
    if (!(type == 1 || type == 2)) return;

    if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
    {                       				  /* Intra */
        dc_scaler = cal_dc_scaler(QP,type);
        qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler));

        step = 2 * QP;
        for (i = 1; i < 64; i++)
    	{
            level = (abs(coeff[i]))  / step;
            result = (coeff[i] >= 0) ? level : -level;
            qcoeff[i] =  MIN(2047, MAX(-2048, result));
    	}
    }
    else
    {                           			  /* non Intra */
        step = 2 * QP;
        offset = QP / 2;
        for (i = 0; i < 64; i++)
    	{
            level = (abs(coeff[i]) - offset)  / step;
            result = (coeff[i] >= 0) ? level : -level;
            qcoeff[i] =  MIN(2047, MAX(-2048, result));
    	}
    }

    return;
}


/***********************************************************CommentBegin******
 *
 * -- BlockDequantH263 -- 8x8 block dequantization
 *
 * Purpose :
 *  8x8 block dequantization
 *
 * Arguments in :
 *  Int *qcoeff         quantized coefficients
 *  Int QP              quantization parameter
 *  Int mode            Macroblock coding mode
 *      Int short_video_header  Flag to signal short video header bitstreams (H.263)
 *
 * Arguments out :
 *  Int *rcoeff reconstructed (dequantized) coefficients
 *
 ***********************************************************CommentEnd********/
Void
BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type, Int *rcoeff,
Int image_type, Int short_video_header, Int bits_per_pixel)
{
    Int i;
    Int dc_scaler;
    Int lim;

    lim = (1 << (bits_per_pixel + 3));

    if (QP)
    {
        for (i = 0; i < 64; i++)
    	{
            if (qcoeff[i])
    		{
                /* 16.11.98 Sven Brandau: "correct saturation" due to N2470, Clause 2.1.6 */
                qcoeff[i] =  MIN(2047, MAX(-2048, qcoeff[i] ));
                if ((QP % 2) == 1)
                    rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);
        		else
                    rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;
                rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];
    		}
        	else
                rcoeff[i] = 0;
    	}
        if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
        {                   					  /* Intra */

            MOMCHECK(QP > 0 && (QP < 32*image_type));
            MOMCHECK(type == 1 || type == 2);

            if (short_video_header)
                dc_scaler = 8;
        	else
                dc_scaler = cal_dc_scaler(QP,type);

            rcoeff[0] = qcoeff[0] * dc_scaler;
    	}
    }
    else
    {
        /* No quantizing at all */
        for (i = 0; i < 64; i++)
    	{
            rcoeff[i] = qcoeff[i];
    	}

        if (mode == MODE_INTRA || mode == MODE_INTRA_Q)
        {                   					  /* Intra */
            rcoeff[0] = qcoeff[0]*8;
    	}
    }
    for (i=0;i<64;i++)
        if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);
        else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);

    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -