📄 mpg2encdlg.cpp
字号:
}
}
else
{
/* No MC */
var = v0;
mbi->mb_type = 0;
mbi->motion_type = MC_FIELD;
mbi->MV[0][0][0] = 0;
mbi->MV[0][0][1] = 0;
mbi->mv_field_sel[0][0] = (pict_struct==BOTTOM_FIELD);
}
}
}
else /* if (pict_type==B_TYPE) */
{
/* forward prediction */
field_estimate(oldorg,oldref,oldorg+width,oldref+width,mb,
i,j,sxf,syf,0,
&iminf,&jminf,&imin8uf,&jmin8uf,&imin8lf,&jmin8lf,
&dmcfieldf,&dmc8f,&self,&sel8uf,&sel8lf,&imins,&jmins,&ds);
/* backward prediction */
field_estimate(neworg,newref,neworg+width,newref+width,mb,
i,j,sxb,syb,0,
&iminr,&jminr,&imin8ur,&jmin8ur,&imin8lr,&jmin8lr,
&dmcfieldr,&dmc8r,&selr,&sel8ur,&sel8lr,&imins,&jmins,&ds);
/* calculate distances for bidirectional prediction */
/* field */
dmcfieldi = bdist1(oldref + (self?width:0) + (iminf>>1) + w2*(jminf>>1),
newref + (selr?width:0) + (iminr>>1) + w2*(jminr>>1),
mb,w2,iminf&1,jminf&1,iminr&1,jminr&1,16);
/* 16x8 upper half block */
dmc8i = bdist1(oldref + (sel8uf?width:0) + (imin8uf>>1) + w2*(jmin8uf>>1),
newref + (sel8ur?width:0) + (imin8ur>>1) + w2*(jmin8ur>>1),
mb,w2,imin8uf&1,jmin8uf&1,imin8ur&1,jmin8ur&1,8);
/* 16x8 lower half block */
dmc8i+= bdist1(oldref + (sel8lf?width:0) + (imin8lf>>1) + w2*(jmin8lf>>1),
newref + (sel8lr?width:0) + (imin8lr>>1) + w2*(jmin8lr>>1),
mb+8*w2,w2,imin8lf&1,jmin8lf&1,imin8lr&1,jmin8lr&1,8);
/* select prediction type of minimum distance */
if (dmcfieldi<dmc8i && dmcfieldi<dmcfieldf && dmcfieldi<dmc8f
&& dmcfieldi<dmcfieldr && dmcfieldi<dmc8r)
{
/* field, interpolated */
mbi->mb_type = MB_FORWARD|MB_BACKWARD;
mbi->motion_type = MC_FIELD;
vmc = bdist2(oldref + (self?width:0) + (iminf>>1) + w2*(jminf>>1),
newref + (selr?width:0) + (iminr>>1) + w2*(jminr>>1),
mb,w2,iminf&1,jminf&1,iminr&1,jminr&1,16);
}
else if (dmc8i<dmcfieldf && dmc8i<dmc8f
&& dmc8i<dmcfieldr && dmc8i<dmc8r)
{
/* 16x8, interpolated */
mbi->mb_type = MB_FORWARD|MB_BACKWARD;
mbi->motion_type = MC_16X8;
/* upper half block */
vmc = bdist2(oldref + (sel8uf?width:0) + (imin8uf>>1) + w2*(jmin8uf>>1),
newref + (sel8ur?width:0) + (imin8ur>>1) + w2*(jmin8ur>>1),
mb,w2,imin8uf&1,jmin8uf&1,imin8ur&1,jmin8ur&1,8);
/* lower half block */
vmc+= bdist2(oldref + (sel8lf?width:0) + (imin8lf>>1) + w2*(jmin8lf>>1),
newref + (sel8lr?width:0) + (imin8lr>>1) + w2*(jmin8lr>>1),
mb+8*w2,w2,imin8lf&1,jmin8lf&1,imin8lr&1,jmin8lr&1,8);
}
else if (dmcfieldf<dmc8f && dmcfieldf<dmcfieldr && dmcfieldf<dmc8r)
{
/* field, forward */
mbi->mb_type = MB_FORWARD;
mbi->motion_type = MC_FIELD;
vmc = dist2(oldref + (self?width:0) + (iminf>>1) + w2*(jminf>>1),
mb,w2,iminf&1,jminf&1,16);
}
else if (dmc8f<dmcfieldr && dmc8f<dmc8r)
{
/* 16x8, forward */
mbi->mb_type = MB_FORWARD;
mbi->motion_type = MC_16X8;
/* upper half block */
vmc = dist2(oldref + (sel8uf?width:0) + (imin8uf>>1) + w2*(jmin8uf>>1),
mb,w2,imin8uf&1,jmin8uf&1,8);
/* lower half block */
vmc+= dist2(oldref + (sel8lf?width:0) + (imin8lf>>1) + w2*(jmin8lf>>1),
mb+8*w2,w2,imin8lf&1,jmin8lf&1,8);
}
else if (dmcfieldr<dmc8r)
{
/* field, backward */
mbi->mb_type = MB_BACKWARD;
mbi->motion_type = MC_FIELD;
vmc = dist2(newref + (selr?width:0) + (iminr>>1) + w2*(jminr>>1),
mb,w2,iminr&1,jminr&1,16);
}
else
{
/* 16x8, backward */
mbi->mb_type = MB_BACKWARD;
mbi->motion_type = MC_16X8;
/* upper half block */
vmc = dist2(newref + (sel8ur?width:0) + (imin8ur>>1) + w2*(jmin8ur>>1),
mb,w2,imin8ur&1,jmin8ur&1,8);
/* lower half block */
vmc+= dist2(newref + (sel8lr?width:0) + (imin8lr>>1) + w2*(jmin8lr>>1),
mb+8*w2,w2,imin8lr&1,jmin8lr&1,8);
}
/* select between intra and non-intra coding */
if (vmc>var && vmc>=9*256)
mbi->mb_type = MB_INTRA;
else
{
var = vmc;
if (mbi->motion_type==MC_FIELD)
{
/* forward */
mbi->MV[0][0][0] = iminf - (i<<1);
mbi->MV[0][0][1] = jminf - (j<<1);
mbi->mv_field_sel[0][0] = self;
/* backward */
mbi->MV[0][1][0] = iminr - (i<<1);
mbi->MV[0][1][1] = jminr - (j<<1);
mbi->mv_field_sel[0][1] = selr;
}
else /* MC_16X8 */
{
/* forward */
mbi->MV[0][0][0] = imin8uf - (i<<1);
mbi->MV[0][0][1] = jmin8uf - (j<<1);
mbi->mv_field_sel[0][0] = sel8uf;
mbi->MV[1][0][0] = imin8lf - (i<<1);
mbi->MV[1][0][1] = jmin8lf - ((j+8)<<1);
mbi->mv_field_sel[1][0] = sel8lf;
/* backward */
mbi->MV[0][1][0] = imin8ur - (i<<1);
mbi->MV[0][1][1] = jmin8ur - (j<<1);
mbi->mv_field_sel[0][1] = sel8ur;
mbi->MV[1][1][0] = imin8lr - (i<<1);
mbi->MV[1][1][1] = jmin8lr - ((j+8)<<1);
mbi->mv_field_sel[1][1] = sel8lr;
}
}
}
mbi->var = var;
}
/////////////////////////////////////////////////////////////////////////////////
void motion_estimation(unsigned char *oldorg,unsigned char *neworg,unsigned char *oldref,unsigned char *newref,
unsigned char *cur,unsigned char *curref,
int sxf,int syf,int sxb,int syb,
struct mbinfo *mbi,
int secondfield,int ipflag)
{
int i, j;
/* 对所有的宏块进行循环操作 */
for (j=0; j<height2; j+=16)
{
for (i=0; i<width; i+=16)
{
/*根据图像结构的类型来判断是进行帧预测还是场预测*/
if (pict_struct==FRAME_PICTURE)
frame_ME(oldorg,neworg,oldref,newref,cur,i,j,sxf,syf,sxb,syb,mbi);
else
field_ME(oldorg,neworg,oldref,newref,cur,curref,i,j,sxf,syf,sxb,syb,
mbi,secondfield,ipflag);
mbi++;
}
if (!quiet)
{
putc('.',stderr);
fflush(stderr);
}
}
if (!quiet)
putc('\n',stderr);
}
//////////////////////////////////////////////////////////////////////////////////////
static void calc_DMV(int DMV[][2],int *dmvector,int mvx, int mvy)
{
if (pict_struct==FRAME_PICTURE)
{
if (topfirst)
{
/* vector for prediction of top field from bottom field */
DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1;
/* vector for prediction of bottom field from top field */
DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
}
else
{
/* vector for prediction of top field from bottom field */
DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
/* vector for prediction of bottom field from top field */
DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1;
}
}
else
{
/* vector for prediction from field of opposite 'parity' */
DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
/* correct for vertical field shift */
if (pict_struct==TOP_FIELD)
DMV[0][1]--;
else
DMV[0][1]++;
}
}
////////////////////////////////////////////////////////////////////
static void clearblock(unsigned char *cur[],int i0, int j0)
{
int i, j, w, h;
unsigned char *p;
p = cur[0] + ((pict_struct==BOTTOM_FIELD) ? width : 0) + i0 + width2*j0;
for (j=0; j<16; j++)
{
for (i=0; i<16; i++)
p[i] = 128;
p+= width2;
}
w = h = 16;
if (chroma_format!=CHROMA444)
{
i0>>=1; w>>=1;
}
if (chroma_format==CHROMA420)
{
j0>>=1; h>>=1;
}
p = cur[1] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
+ chrom_width2*j0;
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
p[i] = 128;
p+= chrom_width2;
}
p = cur[2] + ((pict_struct==BOTTOM_FIELD) ? chrom_width : 0) + i0
+ chrom_width2*j0;
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
p[i] = 128;
p+= chrom_width2;
}
}
/////////////////////////////////////////////////////////////
/* 低等级预测
* src: 源帧(Y,U,V)
* dst: 目标帧(Y,U,V)
*
* lx: 相邻像素的垂直距离
* w,h: 块的宽度和高度
* x,y: 目标块的坐标
* dx,dy: 半像素运动向量
* addflag: 存储或加预测*/
static void pred_comp(unsigned char *src,unsigned char *dst,int lx,int w,
int h,int x, int y,int dx,int dy,int addflag)
{
int xint, xh, yint, yh;
int i, j;
unsigned char *s, *d;
/* half pel scaling */
xint = dx>>1; /* integer part */
xh = dx & 1; /* half pel flag */
yint = dy>>1;
yh = dy & 1;
/* origins */
s = src + lx*(y+yint) + (x+xint); /* motion vector */
d = dst + lx*y + x;
if (!xh && !yh)
if (addflag)
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = (unsigned int)(d[i]+s[i]+1)>>1;
s+= lx;
d+= lx;
}
else
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = s[i];
s+= lx;
d+= lx;
}
else if (!xh && yh)
if (addflag)
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = (d[i] + ((unsigned int)(s[i]+s[i+lx]+1)>>1)+1)>>1;
s+= lx;
d+= lx;
}
else
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = (unsigned int)(s[i]+s[i+lx]+1)>>1;
s+= lx;
d+= lx;
}
else if (xh && !yh)
if (addflag)
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+1)>>1)+1)>>1;
s+= lx;
d+= lx;
}
else
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = (unsigned int)(s[i]+s[i+1]+1)>>1;
s+= lx;
d+= lx;
}
else /* if (xh && yh) */
if (addflag)
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = (d[i] + ((unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2)+1)>>1;
s+= lx;
d+= lx;
}
else
for (j=0; j<h; j++)
{
for (i=0; i<w; i++)
d[i] = (unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2;
s+= lx;
d+= lx;
}
}
/////////////////////////////////////////////
/* 预测矩形块
* src: 源帧(Y,U,V)
* sfield: 源场选择(0: 帧或上半场, 1: 下半场)
* dst: 目标帧(Y,U,V)
* dfield: 目标场选择
*
* 下面的数值是亮度图像的参数
* lx: 相邻像素的垂直距离
* w,h: 块的宽度和高度
* x,y: 目标块的坐标
* dx,dy: 半像素运动向量
* addflag: 存储或加预测*//* 预测矩形块
* src: 源帧(Y,U,V)
* sfield: 源场选择(0: 帧或上半场, 1: 下半场)
* dst: 目标帧(Y,U,V)
* dfield: 目标场选择
*
* 下面的数值是亮度图像的参数
* lx: 相邻像素的垂直距离
* w,h: 块的宽度和高度
* x,y: 目标块的坐标
* dx,dy: 半像素运动向量
* addflag: 存储或加预测*/
static void pred(unsigned char *src[],int sfield,unsigned char *dst[],int dfield,
int lx,int w, int h,int x, int y,int dx, int dy,int addflag)
{
int cc;
for (cc=0; cc<3; cc++)
{
if (cc==1)
{
/* scale for color components */
if (chroma_format==CHROMA420)
{
/* vertical */
h >>= 1; y >>= 1; dy /= 2;
}
if (chroma_format!=CHROMA444)
{
/* horizontal */
w >>= 1; x >>= 1; dx /= 2;
lx >>= 1;
}
}
pred_comp(src[cc]+(sfield?lx>>1:0),dst[cc]+(dfield?lx>>1:0),
lx,w,h,x,y,dx,dy,addflag);
}
}
///////////////////////////////////////////////
/* 为一个宏块形成预测
oldref: 用来进行前向预测的参考帧
newref: 用来进行后向预测的参考帧
cur: 目标帧(即当前要预测的帧)
lx: 帧的宽度(与全局变量"width"一致)
bx、by: 要被预测的宏块的图像坐标(可以是场,也可以是帧)
pict_type: 图像类型,就是I、P或B
pict_struct: 图像的结构,就是帧图像(FRAME_PICTURE),上部分的场图像
(TOP_FIELD)和下部分的场图像(BOTTOM_FIELD)
mb_type: 宏块类型,可以是前向(MB_FORWARD),也可以是后向(MB_BACKWARD)
或是帧内(MB_INTRA)宏块
motion_type: 运动类型,主要用值MC_FRAME, MC_FIELD、MC_16X8、MC_DMV表示
secondfield: 预测帧的第二个场图像
PMV[2][2][2]: 运动向量(以半像素图像坐标为单位)
mv_field_sel[2][2]: 垂直运动场选择(针对场预测)
dmvector: 差分运动向量*/
static void predict_mb(unsigned char *oldref[],unsigned char *newref[],unsigned char *cur[],
int lx,int bx,int by,int pict_type,int pict_struct,int mb_type,
int motion_type,int se
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -