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

📄 motionest.cc

📁 Motion JPEG编解码器源代码
💻 CC
📖 第 1 页 / 共 4 页
字号:
 * bestfld: location and distance of best field prediction * best8u: location of best 16x8 pred. for upper half of mb * best8lp: location of best 16x8 pred. for lower half of mb * bdestsp: location and distance of best same parity field *                    prediction (needed for dual prime, only valid if *                    ipflag==0) */static void field_estimate (	const Picture &picture,	uint8_t *toporg,	uint8_t *topref, 	uint8_t *botorg, 	uint8_t *botref,	SubSampledImg *ssmb,	int i, int j, int sx, int sy,	MotionCand *bestfld,	MotionCand *best8u,	MotionCand *best8l,	MotionCand *bestsp){    const EncoderParams &eparams = picture.encparams;	MotionCand topfld_mc;	MotionCand botfld_mc;	int dt, db;	int notop, nobot;	SubSampledImg botssmb;	botssmb.mb = ssmb->mb+eparams.phy_width;	botssmb.umb = ssmb->umb+(eparams.phy_width>>1);	botssmb.vmb = ssmb->vmb+(eparams.phy_width>>1);	botssmb.fmb = ssmb->fmb+(eparams.phy_width>>1);	botssmb.qmb = ssmb->qmb+(eparams.phy_width>>2);	/* if ipflag is set, predict from field of opposite parity only */	notop = picture.ipflag && (picture.pict_struct==TOP_FIELD);	nobot = picture.ipflag && (picture.pict_struct==BOTTOM_FIELD);	/* field prediction */	/* predict current field from top field */	if (notop)		topfld_mc.sad = dt = 65536; /* infinity */	else		mb_me_search(eparams,                     toporg,topref,0,ssmb,                     eparams.phy_width<<1, i,j,sx,sy>>1,16,                     eparams.enc_width,eparams.enc_height>>1, &topfld_mc);	dt = topfld_mc.sad;	/* predict current field from bottom field */	if (nobot)		botfld_mc.sad = db = 65536; /* infinity */	else		mb_me_search(eparams,                     botorg,botref,eparams.phy_width,ssmb,                     eparams.phy_width<<1, i,j,sx,sy>>1,16,                     eparams.enc_width,eparams.enc_height>>1, &botfld_mc);	db = botfld_mc.sad;	/* Set correct field selectors */	topfld_mc.fieldsel = 0;	botfld_mc.fieldsel = 1;	topfld_mc.fieldoff = 0;	botfld_mc.fieldoff = eparams.phy_width;	/* same parity prediction (only valid if ipflag==0) */	if (picture.pict_struct==TOP_FIELD)	{		*bestsp = topfld_mc;	}	else	{		*bestsp = botfld_mc;	}	/* select field prediction */	if (dt<=db)	{		*bestfld = topfld_mc;	}	else	{		*bestfld = botfld_mc;	}	/* 16x8 motion estimation */	/* predict upper half field from top field */	if (notop)		topfld_mc.sad = dt = 65536;	else		mb_me_search(eparams,                     toporg,topref,0,ssmb,                     eparams.phy_width<<1, i,j,sx,sy>>1,8,                     eparams.enc_width,eparams.enc_height>>1,&topfld_mc);	dt = topfld_mc.sad;	/* predict upper half field from bottom field */	if (nobot)		botfld_mc.sad = db = 65536;	else		mb_me_search(eparams,                     botorg,botref,eparams.phy_width,ssmb,                     eparams.phy_width<<1, i,j,sx,sy>>1,8,                     eparams.enc_width,                     eparams.enc_height>>1,&botfld_mc);	db = botfld_mc.sad;	/* Set correct field selectors */	topfld_mc.fieldsel = 0;	botfld_mc.fieldsel = 1;	topfld_mc.fieldoff = 0;	botfld_mc.fieldoff = eparams.phy_width;	/* select prediction for upper half field */	if (dt<=db)	{		*best8u = topfld_mc;	}	else	{		*best8u = botfld_mc;	}	/* predict lower half field from top field */	/*	  N.b. For interlaced data width<<4 (width*16) takes us 8 rows	  down in the same field.  	  Thus for the fast motion data (2*2	  sub-sampled) we need to go 4 rows down in the same field.	  This requires adding width*4 = (width<<2).	  For the 4*4 sub-sampled motion data we need to go down 2 rows.	  This requires adding width = width	 	*/	if (notop)		topfld_mc.sad = dt = 65536;	else		mb_me_search(eparams,                     toporg,topref,0,&botssmb,                     eparams.phy_width<<1, i,j+8,sx,sy>>1,8,                     eparams.enc_width,eparams.enc_height>>1, &topfld_mc);	dt = topfld_mc.sad;	/* predict lower half field from bottom field */	if (nobot)		botfld_mc.sad = db = 65536;	else		mb_me_search(eparams,                     botorg,botref,eparams.phy_width,&botssmb,                     eparams.phy_width<<1,i,j+8,sx,sy>>1,8,                     eparams.enc_width,eparams.enc_height>>1, &botfld_mc);	db = botfld_mc.sad;	/* Set correct field selectors */	topfld_mc.fieldsel = 0;	botfld_mc.fieldsel = 1;	topfld_mc.fieldoff = 0;	botfld_mc.fieldoff = eparams.phy_width;	/* select prediction for lower half field */	if (dt<=db)	{		*best8l = topfld_mc;	}	else	{		*best8l = botfld_mc;	}} /* Hierarchical block matching motion estimation search * * A.Stevens 2000: This is now a big misnomer.  The search is now a * hierarchical/sub-sampling search not a full search.  However, * experiments have shown it is always close to optimal and almost * always very close or optimal. * * org: top left pel of source reference frame * ref: top left pel of reconstructed reference frame * fieldoff - Offset to top left pel relevant field in org and ref *          if we're doing by-field matching  * ssblk: top-left element of macro block to be motion compensated *        at 1*1,2*2 and 4*4 subsampling * lx: distance (in bytes) of vertically adjacent pels in ref,blk *     This is twice the physical line length if we're doing by-field *     matching otherwise the physical line length * i0,j0: center of search window * sx,sy: half widths of search window * h: height of macro block * xmax,ymax: right/bottom limits of search area for macro block * res: pointers to where the result is stored *      N.b. as in the original code result is given as *      half pel offset from ref(0,0) not the position relative to i0 j0 *      as will actually be used. * * TODO: SHould use half-pel co-ordinates relative to i0,j0 for motion vectors * throughout the motion estimation code but this would be damn fiddly to * do without introducing lots of tricky-to-find bugs. * */ #ifdef DEBUG_MOTION_ESTstatic void log_result_set( me_result_set *rs ){    int i;    for( i = 0; i < rs->len; ++i )        printf( "%03d: %6d %3d %3d\n",                 i, rs->mests[i].weight,                 2*rs->mests[i].x, 2*rs->mests[i].y );}static int hash( uint8_t *blk, int stride ){    int i,j;    int sum = 0;    for( j= 0; j <16; ++j )        for( i = 0; i <16 ; ++i)            sum += *(blk+i+j*stride);    return sum;}static int dump( uint8_t *blk, int stride ){    int i,j;    int sum = 0;    for( j= 0; j <16; ++j )    {        for( i = 0; i <16 ; ++i)            printf( "%02x ", *(blk+i+j*stride) );        if( j & 1 )            printf( "\n" );            }    return sum;}#endifstatic void mb_me_search(    const EncoderParams &eparams,	uint8_t *org,	uint8_t *ref,    int fieldoff,	SubSampledImg *ssblk,	int lx, int i0, int j0, 	int sx, int sy, int h,	int xmax, int ymax,	MotionCand *res	){	me_result_s best;	int i,j,ilow,ihigh,jlow,jhigh;	int x,y;	int d;	/* NOTE: Surprisingly, the initial motion estimation search	   works better when the original image not the reference (reconstructed)	   image is used. 	*/	uint8_t *s22org = (uint8_t*)(org+eparams.fsubsample_offset+(fieldoff>>1));	uint8_t *s44org = (uint8_t*)(org+eparams.qsubsample_offset+(fieldoff>>2));	uint8_t *orgblk;    uint8_t *reffld = ref+fieldoff;	int flx = lx >> 1;	int qlx = lx >> 2;	int fh = h >> 1;	int qh = h >> 2;	me_result_set sub44set;	me_result_set sub22set;	/* xmax and ymax into more useful form... */	xmax -= 16;	ymax -= h;      	/* The search radii are *always* multiples of 4 to avoid messiness	   in the initial 4*4 pel search.  This is handled by the	   parameter checking/processing code in readparmfile() */  	/* Create a distance-order mests of possible motion estimations	  based on the fast estimation data - 4*4 pel sums (4*4	  sub-sampled) rather than actual pel's.  1/16 the size...  */	jlow = j0-sy;	jlow = jlow < 0 ? 0 : jlow;	jhigh =  j0+(sy-1);	jhigh = jhigh > ymax ? ymax : jhigh;	ilow = i0-sx;	ilow = ilow < 0 ? 0 : ilow;	ihigh =  i0+(sx-1);	ihigh = ihigh > xmax ? xmax : ihigh;	/* 	   Very rarely this may fail to find matchs due to all the good	   looking ones being over threshold. hence we make sure we	   fall back to a 0 motion estimation in this case.	   		 The sad for the 0 motion estimation is also very useful as		 a basis for setting thresholds for rejecting really dud 4*4		 and 2*2 sub-sampled matches.	*/	best.weight = psad_00(reffld+i0+j0*lx,ssblk->mb,lx,h,INT_MAX);	best.x = 0;	best.y = 0;	/* Generate the best matches at 4*4 sub-sampling. 	   The precise fraction of the matches included is	   controlled by eparams.44_red	   Note: we use the original picture here for the match...	 */	pbuild_sub44_mests( &sub44set,                        ilow, jlow, ihigh, jhigh,                        i0, j0,                        best.weight,                        s44org,                         ssblk->qmb, qlx, qh,                        eparams.me44_red); #ifdef DEBUG_MOTION_EST    if( trace_me )        log_result_set( &sub44set );#endif		/* Generate the best 2*2 sub-sampling matches from the	   immediate 2*2 neighbourhoods of the 4*4 sub-sampling matches.	   The precise fraction of the matches included is controlled	   by eparams.22_red.	   Note: we use the original picture here for the match...	*/	pbuild_sub22_mests( &sub44set, &sub22set,                        i0, j0,                         ihigh,  jhigh,                         best.weight,                        s22org, ssblk->fmb, flx, fh,                        eparams.me22_red);#ifdef DEBUG_MOTION_EST    if( trace_me )        log_result_set( &sub22set );#endif		    /* Now choose best 1-pel match from the 2*2 neighbourhoods	   of the best 2*2 sub-sampled matches.	   Note that here we start using the reference picture not the	   original.	*/		pfind_best_one_pel( &sub22set,                        reffld, ssblk->mb,                         i0, j0,                        ihigh, jhigh,                         lx, h, &best );#ifdef DEBUG_MOTION_EST    if( trace_me )    {        printf( "BST: %6d %3d %3d @ %6d %7d (%7d)\n",                 best.weight,                 2*best.x, 2*best.y,                (i0+best.x)+lx*(j0+best.y),                hash(reffld+(i0+best.x)+lx*(j0+best.y), lx),                hash(ssblk->mb, lx)                            );        dump( reffld+(i0+best.x)+lx*(j0+best.y), lx );    };#endif	/* Final polish: half-pel search of best 1*1 against	   reconstructed image. 	*/	res->sad = INT_MAX;	x = (i0+best.x)<<1;	y = (j0+best.y)<<1;	/* Narrow search box to half-pel's around best 1-pel match - half-pel	   units....*/	ilow = x - (x>(ilow<<1));	ihigh = x + (x<((ihigh)<<1));	jlow = y - (y>(jlow<<1));	jhigh =  y+ (y<((jhigh)<<1));	for (j=jlow; j<=jhigh; j++)	{		for (i=ilow; i<=ihigh; i++)		{			orgblk = reffld+(i>>1)+((j>>1)*lx);			if( i&1 )			{				if( j & 1 )					d = psad_11(orgblk,ssblk->mb,lx,h);				else					d = psad_01(orgblk,ssblk->mb,lx,h);			}			else			{				if( j & 1 )					d = psad_10(orgblk,ssblk->mb,lx,h);				else					d = psad_00(orgblk,ssblk->mb,lx,h,res->sad);			}            // TODO: Mismatches motionsearch...#ifdef DEBUG_MOTION_EST            if( trace_me )                printf( "BSS: %6d %3d %3d @ %6d %7d\n",                         d,                         i, j,                        orgblk-reffld,                        hash(orgblk, lx) );#endif			d += mv_coding_penalty(i-(i0<<1),j-(j0<<1));			if (d<res->sad)			{				res->sad = d;				res->pos.x = i;				res->pos.y = j;				res->blk = orgblk;				res->hx = i&1;				res->hy = j&1;			}		}	}	res->var = psumsq(res->blk, ssblk->mb, lx, res->hx, res->hy, h);}/*  * Local variables: *  c-file-style: "stroustrup" *  tab-width: 4 *  indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

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