📄 dsp_vop.c
字号:
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <std.h>
#include "dsp_type.h"
#include "dsp_global.h"
#include "dsp_stream.h"
#include "dsp_vop.h"
#include "dsp_vlc.h"
//static unsigned char * g_currMB1;
/*
void initVopPar()//初始化各参数
{
p_par->prediction_type=I_VOP;
p_par->rounding_type=0;
p_par->width=720;
p_par->height=576;
p_par->hor_spat_ref=-16;
p_par->ver_spat_ref=-16;
p_par->quantizer=8;
p_par->intra_quantizer=8;
p_par->time_increment_resolution=30;
p_par->sr_for=16;
p_par->fcode_for=1;
p_par->quant_precision=5;
p_par->bits_per_pixel=8;
p_par->modulo_time_base=0;
}
*/
void CodeVOVOLHeader()
{
BitstreamPutBits(0x100,32);//VO_START_CODE
BitstreamPutBits(0x120,32);//VOL_START_CODE
BitstreamPutBits(0,1);//random_accessible_vol
BitstreamPutBits(4,8);//video_object_type_indication,simple object
BitstreamPutBits(0,1);//is_object_layer_identifier
BitstreamPutBits(1,4);//aspect_ratio_info
BitstreamPutBits(0,1);//vol_control_paramters
BitstreamPutBits(0,2);//video_object_layer_shape
BitstreamPutBits(1,1);//marker
BitstreamPutBits(30,16);//vop_time_increment_resolution
BitstreamPutBits(1,1);//marker
BitstreamPutBits(0,1);//fixed_vop_rate
BitstreamPutBits(1,1);//marker
BitstreamPutBits(p_par->width,13);//video_object_layer_width
BitstreamPutBits(1,1);//marker
BitstreamPutBits(p_par->height,13);//video_object_layer_height
BitstreamPutBits(1,1);//marker
BitstreamPutBits(0,1);//interlaced
BitstreamPutBits(1,1);//obmc_disable
BitstreamPutBits(0,1);//sprite_enable
BitstreamPutBits(0,1);//not_8_bit
BitstreamPutBits(0,1);//quant_type
BitstreamPutBits(1,1);//complexity_estimation_disable
BitstreamPutBits(0,1);//resync_marker_disable
BitstreamPutBits(0,1);//data_partitioned
BitstreamPutBits(0,1);//scalability
}
char get_fcode (short search_range)
{
if (search_range<=16) return 1;
else if (search_range<=32) return 2;
else if (search_range<=64) return 3;
else if (search_range<=128) return 4;
else if (search_range<=256) return 5;
else if (search_range<=512) return 6;
else if (search_range<=1024) return 7;
else return (-1);
}
void CodeVop(unsigned char * curr,
unsigned char * reference,
unsigned char * reconstruct,
// short * error,
short frame)
{
// short *mvx, *mvy; //mot
// char * MB_md; //mot
// char edge,f_code_for;
int mad =0;//平均绝对差值准则
// edge = 0;
// mvx = mot_x; mvy = mot_y; MB_md = MB_decisions;//mot
// f_code_for = p_par->fcode_for;
if (p_par->prediction_type == P_VOP)//如果是P帧则进行运动估计
{
/* Carry out motion estimation and compensation*/
MotionEstimation(curr, reference, &mad, g_motion_x,g_motion_y,g_MB_Mode);
}
else
mad = SCENE_CHANGE_THREADHOLD * 2;
if (mad > SCENE_CHANGE_THREADHOLD) //如果属于剧烈运动
{
// mad is too large.
// the coding mode should be I_VOP
p_par->prediction_type = I_VOP;
p_par->rounding_type = 1;
// We need to recalculate MAD here, since the last MAD was calculated by assuming
// INTER coding, though the actual difference might not be significant to coding.
//? mad = (Float) compute_MAD_unchar(curr);
CodeVopHeader(frame);
/* Code Texture in Intra mode */
CodeIntraVOPTexture(curr,reconstruct);//进行帧内编码
//@ BitstreamPut(texture_bitstream,vo_id,vol_id);
}
else
{
// mad is fine. continue to code as P_VOP
p_par->prediction_type = P_VOP;
CodeVopHeader(frame);//进行帧间编码
//@ SubImage(curr->y_chan, reconstruct->y_chan, error->y_chan);
//@ SubImage(curr->u_chan, reconstruct->u_chan, error->u_chan);
//@ SubImage(curr->v_chan, reconstruct->v_chan, error->v_chan);
CodeInterVOP(curr, reconstruct, g_MB_Mode,g_motion_x, g_motion_y,reference);
//@ pnum_bits->syntax +=
//@ BitstreamPutVopHeader(vo_id,frame,vol_id);
//@ pnum_bits->mot_shape_text +=
//@ BitstreamPut(mottext_bitstream,vo_id,vol_id);
}
//@ if (MB_decisions) FreeImage(MB_decisions);
//@ if (mot_x) FreeImage(mot_x);
//@ if (mot_y) FreeImage(mot_y);
/* Deallocate memory for intermediate bitstreams */
//@ BitstreamFree(texture_bitstream);
//@ BitstreamFree(mottext_bitstream);
//@ ImageRepetitivePadding(reference->y_chan, 16);
//@ ImageRepetitivePadding(reference->u_chan, 8);
//@ ImageRepetitivePadding(reference->v_chan, 8);
//@ pnum_bits->texture+=
//@ NextStartCode(vo_id,vol_id);
return;
}
void CodeVopHeader(short frame)//进行VOP头编码
{
short time_modulo;
unsigned short time_inc;
UChar bits_inc;
short currSecond,t_resolution;
BitstreamPutBits(VOP_START_CODE,VOP_START_CODE_LENGTH);
BitstreamPutBits((UInt)p_par->prediction_type,2);/* vop_coding_type */
t_resolution = p_par->time_increment_resolution;
currSecond = (int)(frame/t_resolution);
time_modulo = currSecond - p_par->modulo_time_base;
BitstreamPutBits((UInt)0xfffffffe,time_modulo+1);/* modulo_time_base */
p_par->modulo_time_base = currSecond;
BitstreamPutBits( 1,1);/* marker bit */
time_inc = frame - currSecond * t_resolution;
for(bits_inc=1;bits_inc<16;bits_inc++)
{
if(t_resolution==1)
break;
t_resolution = t_resolution>>1;
}
BitstreamPutBits(time_inc,bits_inc);/* vop_time_increment */
BitstreamPutBits( 1,1);/* marker bit */
BitstreamPutBits( 1L,1L);/* vop_coded */
if( p_par->prediction_type == P_VOP )
BitstreamPutBits( p_par->rounding_type,1);/* vop_rounding_type */
BitstreamPutBits(0,3);/* intra_dc_vlc_thr,force to zero */
if (p_par->prediction_type == I_VOP)
BitstreamPutBits( p_par->intra_quantizer,p_par->quant_precision);/* vop_quant */
else /* P_VOP */
BitstreamPutBits( p_par->quantizer,p_par->quant_precision);/* vop_quant */
if (p_par->prediction_type!=I_VOP)
{
BitstreamPutBits( p_par->fcode_for,3);/* vop_fcode_forward */
}
}
//进行VOP纹理编码
void CodeIntraVOPTexture(unsigned char * curr,unsigned char * reference)
{
char QP = p_par->intra_quantizer;
char Mode = MODE_INTRA;
short* qcoeff;
register short i, j;
Int CBP ;
char COD;
char CBPY;
// char CBPC;
short num_pixels = (p_par->width);
short num_lines = (p_par->height);
char vop_type;
short ***DC_store_curr;
short ***DC_store_above;
short ***DC_store_tmp;
char MB_width = num_pixels / MB_SIZE;
char MB_height = num_lines / MB_SIZE;
short m;
char ACpred_flag=-1;
char direction[6];
char dc_scaler_lum,dc_scaler_chr;
dc_scaler_lum = cal_dc_scaler(QP,1);
dc_scaler_chr = cal_dc_scaler(QP,2);
qcoeff = g_qcoeff;
for (i = 0; i < 6; i++)
direction[i] = 0;
DC_store_above = g_DC_store[0];
DC_store_curr = g_DC_store[1];
vop_type = PCT_INTRA;
for (j = 0; j < MB_height; j++) /* Macro Block loop */
{
for (i = 0; i < MB_width; i++)
{
loadUCharMBdata(curr,i,j,p_par->width,p_par->height, g_currMB);//g_currMB now is the source MB
FromCharToShort();//from g_currMB to g_fblock
//使用帧内量化模式
DCT_Quant_Rec_MB (QP, MODE_INTRA);// g_currMB is finally the reconstructed MB
CopyRecMBToRef(reference,i,j,p_par->width + 32, p_par->height + 32);//from g_currMB to reference vop
CopyRecMBToResult(result,i,j,p_par->width, p_par->height);//获得重建图像
if(i==0)
{ paddingMBleft(reference,j,p_par->width + 32, p_par->height + 32);
paddingMBleft1(result,j,p_par->width, p_par->height);
}
else if(i==(MB_width-1))
{ paddingMBright(reference,j,p_par->width + 32, p_par->height + 32);
paddingMBright1(result,j,p_par->width, p_par->height);
}
COD = 0;
m =0;
DC_store_curr[ i][0][m] = qcoeff[m]*dc_scaler_lum;
DC_store_curr[ i][1][m] = qcoeff[m+64]*dc_scaler_lum;
DC_store_curr[ i][2][m] = qcoeff[m+128]*dc_scaler_lum;
DC_store_curr[ i][3][m] = qcoeff[m+192]*dc_scaler_lum;
DC_store_curr[ i][4][m] = qcoeff[m+256]*dc_scaler_chr;
DC_store_curr[ i][5][m] = qcoeff[m+320]*dc_scaler_chr;
for (m = 1; m < 8; m++)
{
DC_store_curr[ i][0][m] = qcoeff[m];
DC_store_curr[ i][1][m] = qcoeff[m+64];
DC_store_curr[ i][2][m] = qcoeff[m+128];
DC_store_curr[ i][3][m] = qcoeff[m+192];
DC_store_curr[ i][4][m] = qcoeff[m+256];
DC_store_curr[ i][5][m] = qcoeff[m+320];
}
for (m = 0; m < 7; m++)
{
DC_store_curr[ i][0][m+8] = qcoeff[(m+1)*8];
DC_store_curr[ i][1][m+8] = qcoeff[(m+1)*8+64];
DC_store_curr[ i][2][m+8] = qcoeff[(m+1)*8+128];
DC_store_curr[ i][3][m+8] = qcoeff[(m+1)*8+192];
DC_store_curr[ i][4][m+8] = qcoeff[(m+1)*8+256];
DC_store_curr[ i][5][m+8] = qcoeff[(m+1)*8+320];
}
CBP = FindCBP(qcoeff,Mode,64);
//对DC系数进行差分预测
ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j, DC_store_curr,
DC_store_above, QP, direction);
//@ if (DQUANT) Mode=MODE_INTRA_Q;else Mode=MODE_INTRA;
//@ QP+=DQUANT;
CBPY = CBP >> 2;
CBPY = CBPY & 15; /* last 4 bits */
// CBPC = CBP & 3; /* last 2 bits */
Bits_CountMB_combined (Mode, COD, ACpred_flag, CBP,vop_type);
//void MB_CodeCoeff(short *qcoeff,char Mode, Int CBP, char ncoeffs,char direction[]);
MB_CodeCoeff( qcoeff, Mode, CBP, 64,direction);
}
if(j==0)
{ paddingVOPTop(reference,p_par->width + 32, p_par->height + 32);
paddingVOPTop1(result,p_par->width, p_par->height);
}
//exchange the DC_store_curr and DC_store_above
DC_store_tmp = DC_store_curr;
DC_store_curr = DC_store_above;
DC_store_above = DC_store_tmp;
}
// paddingVOPTop(reference,p_par->width + 32, p_par->height + 32);
paddingVOPBottom(reference,p_par->width + 32, p_par->height + 32);
paddingVOPBottom1(result,p_par->width, p_par->height);
}
//loadUCharMBdata(curr,i,j,p_par->width,p_par->height, g_currMB);
void loadUCharMBdata(unsigned char * currvop, short mb_x, short mb_y, short width,short height,unsigned char * currMB)
{
char ic;
unsigned char* ppxlcCurrMBY = currMB;
unsigned char* ppxlcCurrMBU = currMB + MB_SIZE * MB_SIZE;
unsigned char* ppxlcCurrMBV = currMB+(MB_SIZE * MB_SIZE/4)*5;
unsigned char* ppxlcCurrVopY = currvop + (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
unsigned char* ppxlcCurrVopU = currvop + width*height + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
unsigned char* ppxlcCurrVopV = currvop + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
for (ic = 0; ic < 8; ic++) {
memcpy (ppxlcCurrMBY, ppxlcCurrVopY, MB_SIZE);
memcpy (ppxlcCurrMBU, ppxlcCurrVopU, BLOCK_SIZE);
memcpy (ppxlcCurrMBV, ppxlcCurrVopV, BLOCK_SIZE);
ppxlcCurrMBY += MB_SIZE; ppxlcCurrVopY += width;
ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrVopU += (width/2);
ppxlcCurrMBV += BLOCK_SIZE; ppxlcCurrVopV += (width/2);
memcpy (ppxlcCurrMBY, ppxlcCurrVopY, MB_SIZE); // two rows for Y
ppxlcCurrMBY += MB_SIZE; ppxlcCurrVopY += width;
}
}
/*****************************************************************/
void CopyRecMBToResult(unsigned char * result, short mb_x, short mb_y, short width,short height)
{
char ic;
//short offsetY,offsetUV;
unsigned char *ppxlcCurrMBY= g_currMB;
unsigned char *ppxlcCurrMBU= g_currMB + MB_SIZE * MB_SIZE;
unsigned char *ppxlcCurrMBV= g_currMB+(MB_SIZE * MB_SIZE/4)*5;
unsigned char *ppxlcCurrRefY=result + (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
unsigned char *ppxlcCurrRefU= result + width*height + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
unsigned char *ppxlcCurrRefV= result + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
//edge=16;
//offsetY = width * edge + edge;
//offsetUV = (width>>1) * (edge>>1) + (edge>>1);
/*
ppxlcCurrMBY= g_currMB;
ppxlcCurrMBU = g_currMB + MB_SIZE * MB_SIZE;
ppxlcCurrMBV = g_currMB+(MB_SIZE * MB_SIZE/4)*5;
ppxlcCurrRefY = result + (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
ppxlcCurrRefU = result + width*height + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
ppxlcCurrRefV = result + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
*/
for (ic = 0; ic < 8; ic++) {
memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE);
memcpy (ppxlcCurrRefU, ppxlcCurrMBU, BLOCK_SIZE);
memcpy (ppxlcCurrRefV, ppxlcCurrMBV, BLOCK_SIZE);
ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrRefU += (width/2);
ppxlcCurrMBV += BLOCK_SIZE; ppxlcCurrRefV += (width/2);
memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE); // two rows for Y
ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
}
}
/*****************************************************************/
void CopyRecMBToRef(unsigned char * reference, short mb_x, short mb_y, short width,short height)
{
char ic,edge;
short offsetY,offsetUV;
unsigned char *ppxlcCurrMBY;
unsigned char *ppxlcCurrMBU;
unsigned char *ppxlcCurrMBV;
unsigned char *ppxlcCurrRefY;
unsigned char *ppxlcCurrRefU;
unsigned char *ppxlcCurrRefV;
edge=16;
offsetY = width * edge + edge;
offsetUV = (width>>1) * (edge>>1) + (edge>>1);
ppxlcCurrMBY= g_currMB;
ppxlcCurrMBU = g_currMB + MB_SIZE * MB_SIZE;
ppxlcCurrMBV = g_currMB+(MB_SIZE * MB_SIZE/4)*5;
ppxlcCurrRefY = reference + offsetY+ (mb_y*MB_SIZE)*width+(mb_x*MB_SIZE);
ppxlcCurrRefU = reference + width*height + offsetUV + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
ppxlcCurrRefV = reference + (width*height/4)*5 + offsetUV + (mb_y*BLOCK_SIZE) * width/2 + (mb_x*BLOCK_SIZE);
for (ic = 0; ic < 8; ic++) {
memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE);
memcpy (ppxlcCurrRefU, ppxlcCurrMBU, BLOCK_SIZE);
memcpy (ppxlcCurrRefV, ppxlcCurrMBV, BLOCK_SIZE);
ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrRefU += (width/2);
ppxlcCurrMBV += BLOCK_SIZE; ppxlcCurrRefV += (width/2);
memcpy (ppxlcCurrRefY, ppxlcCurrMBY, MB_SIZE); // two rows for Y
ppxlcCurrMBY += MB_SIZE; ppxlcCurrRefY += width;
}
}
void FromCharToShort()//from g_currMB to g_fblock
{
register short k,i,j;
short xwidth;
unsigned char *pxl;
for(k=0; k<6; k++)
{
switch (k)
{
case 0:
pxl = g_currMB;
xwidth = 16;
break;
case 1:
pxl = g_currMB+8;
xwidth = 16;
break;
case 2:
pxl = g_currMB+8*MB_SIZE;
xwidth = 16;
break;
case 3:
pxl = g_currMB+8*MB_SIZE+8;
xwidth = 16;
break;
case 4:
pxl = g_currMB + MB_SIZE*MB_SIZE;
xwidth = 8;
break;
case 5:
pxl = g_currMB + (MB_SIZE*MB_SIZE/4)*5;
xwidth = 8;
break;
default:
break;
}
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
g_fblock[k][i*8 + j] = (short)pxl[j];
}
pxl+=xwidth;
}
}//end k
}
void DCT_Quant_Rec_MB (char QP, char Mode)
{
register char k;
char type;
short *qcoeff_ind,offset,xwidth;
register short i,j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -