📄 dsp_mot.c
字号:
vec2 = 0 ; yin2 = y ; xin2 = x;
vec3 = 1 ; yin3 = y ; xin3 = x;
break;
default:
// printf("Illegal block number in find_pmv (mot_decode.c)");
*mvx=*mvy=0;
return ;
}
if (block==0)
{ /* check borders for MB */
/* left border */
if (x>0 )
rule1 = 0;
else
rule1 = 1;
/* top border */
if (y>0 )
rule2 = 0;
else
rule2 = 1;
if ( (x != xB/2 -1) && (y>0 ) )
rule3 = 0;
else
rule3 = 1;
}
else
{
/* check borders for single blocks */
/* left border */
if (((block == 1 || block == 3) && (x == 0)))
rule1 = 1;
else
rule1 = 0;
/* top border */
if (((block == 1 || block == 2) && (y == 0)))
rule2 = 1;
else
rule2 = 0;
if (((block == 1 || block == 2) && (x == xB/2 -1 || y == 0)) )
rule3 = 1;
else
rule3 = 0;
}
if (rule1 )
{
p1x = p1y = 0;
}
else
{
p1x = BV(motxdata, xB, xin1, yin1, vec1&0x1, vec1>>1 );
// #define BV(p,xdim,h,v,h2,v2) (p[(2*(v)+(v2))*(xdim)+2*(h)+(h2)])
p1y = BV(motydata, xB, xin1, yin1, vec1&0x1, vec1>>1 );
}
if (rule2)
{
p2x = p2y = 0 ;
}
else
{
p2x = BV(motxdata, xB, xin2, yin2, vec2&0x1, vec2>>1 );
p2y = BV(motydata, xB, xin2, yin2, vec2&0x1, vec2>>1 );
}
if (rule3 )
{
p3x = p3y =0;
}
else
{
p3x = BV(motxdata, xB, xin3, yin3, vec3&0x1, vec3>>1 );
p3y = BV(motydata, xB, xin3, yin3, vec3&0x1, vec3>>1 );
}
if (rule1 && rule2 && rule3 )
{
/* all MBs are outside the VOP */
*mvx=*mvy=0;
}
else if (rule1+rule2+rule3 == 2)
{
/* two of three are zero */
*mvx=(short) subdim*(p1x+p2x+p3x);
*mvy=(short) subdim*(p1y+p2y+p3y);
}
else
{
*mvx=(short)(subdim*(p1x+p2x+p3x-MAX(p1x,MAX(p2x,p3x))-MIN(p1x,MIN(p2x,p3x))));
*mvy=(short)(subdim*(p1y+p2y+p3y-MAX(p1y,MAX(p2y,p3y))-MIN(p1y,MIN(p2y,p3y))));
}
/*
#ifdef _DEBUG_PMVS_
fprintf(stdout,"find_pmvs (%2d,%2d, rule %1d%1d%1d) :\np1 %6.2f / %6.2f\np2 %6.2f / %6.2f\np3 %6.2f / %6.2f\n",x,y,rule1,rule2,rule3,p1x,p1y,p2x,p2y,p3x,p3y);
#endif
*/
return;
}
void
ScaleMVD (
char f_code, /* <-- MV range in 1/2 units: 1=32,2=64,...,7=2048 */
short diff_vector, /* <-- MV Difference commponent in 1/2 units */
short *residual, /* --> value to be FLC coded */
short *vlc_code_mag /* --> value to be VLC coded */
)
{
short range;
char scale_factor;
char r_size;
short low;
short high;
short aux;
r_size = f_code-1;
scale_factor = 1<<r_size;
range = 32*scale_factor;
low = -range;
high = range-1;
if (diff_vector < low)
{
diff_vector += 2*range;
}
else if (diff_vector > high)
{
diff_vector -= 2*range;
}
if (diff_vector==0)
{
*vlc_code_mag = 0;
*residual = 0;
}
else if (scale_factor==1)
{
*vlc_code_mag = diff_vector;
*residual = 0;
}
else
{
aux = ABS(diff_vector) + scale_factor - 1;
*vlc_code_mag = aux>>r_size;
if (diff_vector<0)
*vlc_code_mag = -*vlc_code_mag;
*residual = aux & (scale_factor-1);
}
}
void PutMV (short mvint)
{
char sign = 0;
short absmv;
if (mvint > 32)
{
absmv = -mvint + 65;
sign = 1;
}
else
absmv = mvint;
BitstreamPutBits ( mvtab[absmv].code, mvtab[absmv].len);
if (mvint != 0)
{
BitstreamPutBits (sign, 1);
// return mvtab[absmv].len + 1;
}
// else
// return mvtab[absmv].len;
}
void
WriteMVcomponent(
char f_code,
short dmv
)
{
short residual, vlc_code_mag, entry;
ScaleMVD(f_code, dmv, &residual, &vlc_code_mag);
if (vlc_code_mag < 0)
entry = vlc_code_mag + 65;
else
entry = vlc_code_mag;
PutMV (entry);
if ((f_code != 1) && (vlc_code_mag != 0))
{
BitstreamPutBits(residual, f_code-1);//运动矢量编码
}
}
void
Bits_CountMB_MV(
char *mot_h, /* <-- motion vectors (Float) - per block */
char *mot_v, /* <-- motion vectors (Float) - per block */
char mode, /* <-- macroblocks modes (SInt) - per MB */
char h, /* <-- horizontal coordinate of the MB */
char v, /* <-- vertical coordinate of the MB */
char f_code /* <-- MV range in 1/2 or 1/4 pel units 1=32,2=64,...,7=2048 */ /* <-- flag for quarter pel MC mode */
)
{
short hdim; /* Dimensions in macroblocks */
char *ph, *pv; /* Motion vectors */
short pred_h=0, pred_v=0;
short diff_h, diff_v;
char i, bh, bv;
char subdim=2;
hdim = (p_par->width)/MB_SIZE;
ph= mot_h;
pv= mot_v;
switch (mode)
{
case MODE_INTRA:
break;
case MODE_INTER:
find_pmvs(mot_h,mot_v,h,v,0,&pred_h,&pred_v);
WriteMVcomponent(f_code, (subdim*(MBV_H(h,v)) - pred_h));
WriteMVcomponent(f_code, (subdim*(MBV_V(h,v)) - pred_v));
// #define MBV_H(h,v) (ph[2*(v)*2*hdim+2*(h)])
// #define MBV_V(h,v) (pv[2*(v)*2*hdim+2*(h)])
break;
case MODE_INTER4V:
i=1;
for (bv=0; bv<=1; bv++)
for (bh=0; bh<=1; bh++)
{
find_pmvs(mot_h,mot_v,h,v,i, &pred_h,&pred_v);
i++;
diff_h = subdim * (BV_H(h,v,bh,bv)) - pred_h;
diff_v = subdim * (BV_V(h,v,bh,bv)) - pred_v;
// #define BV_H(h,v,h2,v2) (ph[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])
// #define BV_V(h,v,h2,v2) (pv[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])
WriteMVcomponent(f_code, diff_h);
WriteMVcomponent(f_code, diff_v);
}
break;
}
// return bits_mot;
}
void paddingMBleft(unsigned char * reference, short mb_y, short width,short height)
{
char ic,edge;
short offsetY,offsetUV;
unsigned char *ppxlcCurrRefY;
unsigned char *ppxlcCurrRefU;
unsigned char *ppxlcCurrRefV;
edge=16;
offsetY = width * edge;
offsetUV = (width>>1) * (edge>>1);
ppxlcCurrRefY = reference + offsetY+ (mb_y*MB_SIZE)*width;
ppxlcCurrRefU = reference + width*height + offsetUV + (mb_y*BLOCK_SIZE) * width/2;
ppxlcCurrRefV = reference + (width*height/4)*5 + offsetUV + (mb_y*BLOCK_SIZE) * width/2 ;
for (ic = 0; ic < 8; ic++) {
memset (ppxlcCurrRefY, ppxlcCurrRefY[16], edge);
memset (ppxlcCurrRefU, ppxlcCurrRefU[8], edge/2);
memset (ppxlcCurrRefV, ppxlcCurrRefV[8], edge/2);
ppxlcCurrRefY += width;
ppxlcCurrRefU += (width/2);
ppxlcCurrRefV += (width/2);
memset (ppxlcCurrRefY, ppxlcCurrRefY[16], edge); // two rows for Y
ppxlcCurrRefY += width;
}
}
void paddingMBright(unsigned char * reference, short mb_y, short width,short height)
{
char ic,edge,halfedge;
short offsetY,offsetUV,halfwidth;
unsigned char *ppxlcCurrRefY;
unsigned char *ppxlcCurrRefU;
unsigned char *ppxlcCurrRefV;
edge=16;
halfedge = edge>>1;
halfwidth = width>>1;
offsetY = width * edge + (width - edge);
offsetUV = (halfwidth) * (halfedge) + (halfwidth - halfedge);
ppxlcCurrRefY = reference + offsetY+ (mb_y*MB_SIZE)*width;
ppxlcCurrRefU = reference + width*height + offsetUV + (mb_y*BLOCK_SIZE) * width/2;
ppxlcCurrRefV = reference + (width*height/4)*5 + offsetUV + (mb_y*BLOCK_SIZE) * width/2 ;
for (ic = 0; ic < 8; ic++) {
memset (ppxlcCurrRefY, *(ppxlcCurrRefY-1), edge);
memset (ppxlcCurrRefU, *(ppxlcCurrRefU-1), halfedge);
memset (ppxlcCurrRefV, *(ppxlcCurrRefV-1), halfedge);
ppxlcCurrRefY += width;
ppxlcCurrRefU += halfwidth;
ppxlcCurrRefV += halfwidth;
memset (ppxlcCurrRefY, *(ppxlcCurrRefY-1), edge); // two rows for Y
ppxlcCurrRefY += width;
}
}
void paddingVOPTop(unsigned char * reference, short width,short height)
{
char ic,edge;
unsigned short offsetY,offsetUV;
unsigned char * topLineY;
unsigned char * topLineU;
unsigned char * topLineV;
unsigned char *ppxlcCurrRefY;
unsigned char *ppxlcCurrRefU;
unsigned char *ppxlcCurrRefV;
edge=16;
offsetY = width * edge;
offsetUV = (width>>1) * (edge>>1);
ppxlcCurrRefY = reference;
ppxlcCurrRefU = reference + width*height;
ppxlcCurrRefV = reference + (width*height/4)*5;
topLineY = ppxlcCurrRefY+offsetY;
topLineU = ppxlcCurrRefU+offsetUV;
topLineV = ppxlcCurrRefV+offsetUV;
for (ic = 0; ic < 8; ic++) {
memcpy (ppxlcCurrRefY, topLineY, width);
memcpy (ppxlcCurrRefU, topLineU, (width>>1));
memcpy (ppxlcCurrRefV, topLineV, (width>>1));
ppxlcCurrRefY += width;
ppxlcCurrRefU += (width/2);
ppxlcCurrRefV += (width/2);
memcpy (ppxlcCurrRefY, topLineY, width); // two rows for Y
ppxlcCurrRefY += width;
}
}
void paddingVOPBottom(unsigned char * reference, short width,short height)
{
char ic,edge;
unsigned int offsetY,offsetUV;
unsigned char * botLineY;
unsigned char * botLineU;
unsigned char * botLineV;
unsigned char *ppxlcCurrRefY ;
unsigned char *ppxlcCurrRefU ;
unsigned char *ppxlcCurrRefV;
edge=16;
offsetY = width * (height - edge);
offsetUV = (width>>1) * ((height>>1) - (edge>>1));
ppxlcCurrRefY = reference + offsetY;
ppxlcCurrRefU = reference + width*height + offsetUV;
ppxlcCurrRefV = reference + (width*height/4)*5 + offsetUV;
botLineY = ppxlcCurrRefY - width;
botLineU = ppxlcCurrRefU - (width>>1);
botLineV = ppxlcCurrRefV - (width>>1);
for (ic = 0; ic < 8; ic++) {
memcpy (ppxlcCurrRefY, botLineY, width);
memcpy (ppxlcCurrRefU, botLineU, (width>>1));
memcpy (ppxlcCurrRefV, botLineV, (width>>1));
ppxlcCurrRefY += width;
ppxlcCurrRefU += (width/2);
ppxlcCurrRefV += (width/2);
memcpy (ppxlcCurrRefY, botLineY, width); // two rows for Y
ppxlcCurrRefY += width;
}
}
/*****************************************************************/
void paddingMBleft1(unsigned char * reference, short mb_y, short width,short height)
{
char ic,edge;
//short offsetY,offsetUV;
unsigned char *ppxlcCurrRefY;
unsigned char *ppxlcCurrRefU;
unsigned char *ppxlcCurrRefV;
edge=16;
//offsetY = width * edge;
//offsetUV = (width>>1) * (edge>>1);
ppxlcCurrRefY = reference + (mb_y*MB_SIZE)*width;
ppxlcCurrRefU = reference + width*height + (mb_y*BLOCK_SIZE) * width/2;
ppxlcCurrRefV = reference + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 ;
for (ic = 0; ic < 8; ic++) {
memset (ppxlcCurrRefY, ppxlcCurrRefY[16], edge);
memset (ppxlcCurrRefU, ppxlcCurrRefU[8], edge/2);
memset (ppxlcCurrRefV, ppxlcCurrRefV[8], edge/2);
ppxlcCurrRefY += width;
ppxlcCurrRefU += (width/2);
ppxlcCurrRefV += (width/2);
memset (ppxlcCurrRefY, ppxlcCurrRefY[16], edge); // two rows for Y
ppxlcCurrRefY += width;
}
}
void paddingMBright1(unsigned char * reference, short mb_y, short width,short height)
{
char ic,edge,halfedge;
//short offsetY,offsetUV,halfwidth;
short halfwidth;
unsigned char *ppxlcCurrRefY;
unsigned char *ppxlcCurrRefU;
unsigned char *ppxlcCurrRefV;
edge=16;
halfedge = edge>>1;
halfwidth = width>>1;
//offsetY = width * edge + (width - edge);
//offsetUV = (halfwidth) * (halfedge) + (halfwidth - halfedge);
ppxlcCurrRefY = reference + (mb_y*MB_SIZE)*width;
ppxlcCurrRefU = reference + width*height + (mb_y*BLOCK_SIZE) * width/2;
ppxlcCurrRefV = reference + (width*height/4)*5 + (mb_y*BLOCK_SIZE) * width/2 ;
for (ic = 0; ic < 8; ic++) {
memset (ppxlcCurrRefY, *(ppxlcCurrRefY-1), edge);
memset (ppxlcCurrRefU, *(ppxlcCurrRefU-1), halfedge);
memset (ppxlcCurrRefV, *(ppxlcCurrRefV-1), halfedge);
ppxlcCurrRefY += width;
ppxlcCurrRefU += halfwidth;
ppxlcCurrRefV += halfwidth;
memset (ppxlcCurrRefY, *(ppxlcCurrRefY-1), edge); // two rows for Y
ppxlcCurrRefY += width;
}
}
void paddingVOPTop1(unsigned char * reference, short width,short height)
{
char ic;
//unsigned short offsetY,offsetUV;
unsigned char * topLineY;
unsigned char * topLineU;
unsigned char * topLineV;
unsigned char *ppxlcCurrRefY;
unsigned char *ppxlcCurrRefU;
unsigned char *ppxlcCurrRefV;
// edge=16;
//offsetY = width * edge;
//offsetUV = (width>>1) * (edge>>1);
ppxlcCurrRefY = reference;
ppxlcCurrRefU = reference + width*height;
ppxlcCurrRefV = reference + (width*height/4)*5;
topLineY = ppxlcCurrRefY;
topLineU = ppxlcCurrRefU;
topLineV = ppxlcCurrRefV;
for (ic = 0; ic < 8; ic++) {
memcpy (ppxlcCurrRefY, topLineY, width);
memcpy (ppxlcCurrRefU, topLineU, (width>>1));
memcpy (ppxlcCurrRefV, topLineV, (width>>1));
ppxlcCurrRefY += width;
ppxlcCurrRefU += (width/2);
ppxlcCurrRefV += (width/2);
memcpy (ppxlcCurrRefY, topLineY, width); // two rows for Y
ppxlcCurrRefY += width;
}
}
void paddingVOPBottom1(unsigned char * reference, short width,short height)
{
char ic;
//unsigned int offsetY,offsetUV;
unsigned char * botLineY;
unsigned char * botLineU;
unsigned char * botLineV;
unsigned char *ppxlcCurrRefY ;
unsigned char *ppxlcCurrRefU ;
unsigned char *ppxlcCurrRefV;
// edge=16;
//offsetY = width * (height - edge);
//offsetUV = (width>>1) * ((height>>1) - (edge>>1));
ppxlcCurrRefY = reference ;
ppxlcCurrRefU = reference + width*height ;
ppxlcCurrRefV = reference + (width*height/4)*5 ;
botLineY = ppxlcCurrRefY - width;
botLineU = ppxlcCurrRefU - (width>>1);
botLineV = ppxlcCurrRefV - (width>>1);
for (ic = 0; ic < 8; ic++) {
memcpy (ppxlcCurrRefY, botLineY, width);
memcpy (ppxlcCurrRefU, botLineU, (width>>1));
memcpy (ppxlcCurrRefV, botLineV, (width>>1));
ppxlcCurrRefY += width;
ppxlcCurrRefU += (width/2);
ppxlcCurrRefV += (width/2);
memcpy (ppxlcCurrRefY, botLineY, width); // two rows for Y
ppxlcCurrRefY += width;
}
}
/*****************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -