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

📄 predict.cc

📁 Motion JPEG编解码器源代码
💻 CC
字号:
/* predict.cc, motion compensated prediction                                 *//* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose.  In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders.  Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * *//* Modifications and enhancements (C) 2000/2001 Andrew Stevens *//* These modifications are free software; you can redistribute it *  and/or modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version 2 of *  the License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * */#include "config.h"#include <assert.h>#include "mjpeg_logging.h"#include "mpeg2encoder.hh"#include "mpeg2syntaxcodes.h"#include "picture.hh"#include "macroblock.hh"#include "predict_ref.h"/* predict a rectangular block (all three components) * * src:     source frame (Y,U,V) * sfield:  source field select (0: frame or top field, 1: bottom field) * dst:     destination frame (Y,U,V) * dfield:  destination field select (0: frame or top field, 1: bottom field) * * the following values are in luminance picture (frame or field) dimensions * lx:      distance of vertically adjacent pels (selects frame or field pred.) * w,h:     width and height of block (only 16x16 or 16x8 are used) * x,y:     coordinates of destination block * dx,dy:   half pel motion vector * addflag: store or add (= average) prediction */void pred (	uint8_t *src[], int sfield,			uint8_t *dst[], int dfield,			int lx, int w, int h, int x, int y, 			int dx, int dy, bool addflag	){	int cc;	for (cc=0; cc<3; cc++)	{		if (cc==1)		{			/* scale for color components */			/* vertical */			h >>= 1; y >>= 1; dy /= 2;			/* horizontal */			w >>= 1; x >>= 1; dx /= 2;			lx >>= 1;		}		ppred_comp(	src[cc]+(sfield?lx>>1:0),dst[cc]+(dfield?lx>>1:0),					lx,w,h,x,y,dx,dy, (int)addflag);	}}/* calculate derived motion vectors (DMV) for dual prime prediction * dmvector[2]: differential motion vectors (-1,0,+1) * mvx,mvy: motion vector (for same parity) * * DMV[2][2]: derived motion vectors (for opposite parity) * * uses global variables pict_struct and topfirst * * Notes: *  - all vectors are in field coordinates (even for frame pictures) * */#ifndef DEBUG_DPMEstatic#endifvoid calc_DMV( const Picture &picture, /*int pict_struct,  int topfirst,*/					  MotionVector DMV[Parity::dim],					  MotionVector &dmvector, 					  int mvx, int mvy	){	if (picture.pict_struct==FRAME_PICTURE)	{		if (picture.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 (picture.pict_struct==TOP_FIELD)			DMV[0][1]--;		else			DMV[0][1]++;	}}/* form prediction for one macroblock * * lx:     frame width (identical to global var `width') * * Notes: * - when predicting a P type picture which is the second field of *   a frame, the same parity reference field is in oldref, while the *   opposite parity reference field is assumed to be in newref! * - intra macroblocks are modelled to have a constant prediction of 128 *   for all pels; this results in a DC DCT coefficient symmetric to 0 * - vectors for field prediction in frame pictures are in half pel frame *   coordinates (vertical component is twice the field value and always *   even) * * already covers dual prime (not yet used) */void MacroBlock::Predict(){	const Picture &picture = ParentPicture();	const int bx = TopleftX();	const int by = TopleftY();	uint8_t **fwd_rec = picture.fwd_rec;	// Forward prediction	uint8_t **bwd_rec = picture.bwd_rec;	// Backward prediction	uint8_t **cur = picture.pred;      // Frame to predict	int lx = picture.encparams.phy_width;	int lx2 = picture.encparams.phy_width;	bool addflag;	int currentfield;	uint8_t **predframe;	MotionVector DMV[Parity::dim /*pred*/];	if (final_me.mb_type&MB_INTRA)	{		clearblock( cur,bx,by, 					picture.pict_struct==BOTTOM_FIELD ? lx : 0,					lx2);		return;	}	addflag = false; /* first prediction is stored, second is added and averaged */	if ((final_me.mb_type & MB_FORWARD) || (picture.pict_type==P_TYPE))	{		/* forward prediction, including zero MV in P pictures */		if (picture.pict_struct==FRAME_PICTURE)		{			/* frame picture */			if ( (final_me.motion_type==MC_FRAME) 				 || !(final_me.mb_type & MB_FORWARD))			{				/* frame-based prediction in frame picture */				pred( fwd_rec,0,cur,0,					 lx,16,16,bx,by,final_me.MV[0][0][0],final_me.MV[0][0][1],false);			}			else if (final_me.motion_type==MC_FIELD)			{				/* field-based prediction in frame picture				 *				 * note scaling of the vertical coordinates (by, MV[][0][1])				 * from frame to field!				 */				/* top field prediction */				pred(fwd_rec,final_me.field_sel[0][0],cur,0,					 lx<<1,16,8,bx,by>>1,					 final_me.MV[0][0][0],final_me.MV[0][0][1]>>1,false);				/* bottom field prediction */				pred(fwd_rec,final_me.field_sel[1][0],cur,1,					 lx<<1,16,8,bx,by>>1,					 final_me.MV[1][0][0],final_me.MV[1][0][1]>>1,false);			}			else if (final_me.motion_type==MC_DMV)			{				/* dual prime prediction calculate derived motion vectors */				calc_DMV(picture,						 DMV,						 final_me.dualprimeMV,						 final_me.MV[0][0][0],						 final_me.MV[0][0][1]>>1);				/* predict top field from top field */				pred(fwd_rec,0,cur,0,					 lx<<1,16,8,bx,by>>1,					 final_me.MV[0][0][0],final_me.MV[0][0][1]>>1,false);      				/* predict bottom field from bottom field */				pred(fwd_rec,1,cur,1,					 lx<<1,16,8,bx,by>>1,					 final_me.MV[0][0][0],final_me.MV[0][0][1]>>1,false);				/* predict and add to top field from bottom field */				pred(fwd_rec,1,cur,0,					 lx<<1,16,8,bx,by>>1,					 DMV[0][0],DMV[0][1],true);				/* predict and add to bottom field from top field */				pred(fwd_rec,0,cur,1,					 lx<<1,16,8,bx,by>>1,					 DMV[1][0],DMV[1][1],true);			}			else			{				/* invalid motion_type in frame picture */				mjpeg_error_exit1("Internal: invalid motion_type");			}		}		else /* TOP_FIELD or BOTTOM_FIELD */		{			/* field picture */			currentfield = (picture.pict_struct==BOTTOM_FIELD);			/* determine which frame to use for prediction */			if ((picture.pict_type==P_TYPE) && picture.secondfield				&& (currentfield!=final_me.field_sel[0][0]))				predframe = bwd_rec; /* same frame */			else				predframe = fwd_rec; /* previous frame */			if ( final_me.motion_type==MC_FIELD				 || !(final_me.mb_type & MB_FORWARD))			{				/* field-based prediction in field picture */				pred(predframe,final_me.field_sel[0][0],cur,currentfield,					 lx<<1,16,16,bx,by,					 final_me.MV[0][0][0],final_me.MV[0][0][1],false);			}			else if (final_me.motion_type==MC_16X8)			{				/* 16 x 8 motion compensation in field picture */				/* upper half */				pred(predframe,final_me.field_sel[0][0],cur,currentfield,					 lx<<1,16,8,bx,by,					 final_me.MV[0][0][0],final_me.MV[0][0][1],false);				/* determine which frame to use for lower half prediction */				if ((picture.pict_type==P_TYPE) && picture.secondfield					&& (currentfield!=final_me.field_sel[1][0]))					predframe = bwd_rec; /* same frame */				else					predframe = fwd_rec; /* previous frame */				/* lower half */				pred(predframe,final_me.field_sel[1][0],cur,currentfield,					 lx<<1,16,8,bx,by+8,					 final_me.MV[1][0][0],final_me.MV[1][0][1],false);			}			else if (final_me.motion_type==MC_DMV)			{				/* dual prime prediction */				/* determine which frame to use for prediction */				if (picture.secondfield)					predframe = bwd_rec; /* same frame */				else					predframe = fwd_rec; /* previous frame */				/* calculate derived motion vectors */				calc_DMV(picture,						 DMV,final_me.dualprimeMV,						 final_me.MV[0][0][0],						 final_me.MV[0][0][1]);				/* predict from field of same parity */				pred(fwd_rec,currentfield,cur,currentfield,					 lx<<1,16,16,bx,by,					 final_me.MV[0][0][0],final_me.MV[0][0][1],false);				/* predict from field of opposite parity */				pred(predframe,!currentfield,cur,currentfield,					 lx<<1,16,16,bx,by,					 DMV[0][0],DMV[0][1],true);			}			else			{				/* invalid motion_type in field picture */				mjpeg_error_exit1("Internal: invalid motion_type");			}		}		addflag = true; /* next prediction (if any) will be averaged with this one */	}	if (final_me.mb_type & MB_BACKWARD)	{		/* backward prediction */		if (picture.pict_struct==FRAME_PICTURE)		{			/* frame picture */			if (final_me.motion_type==MC_FRAME)			{				/* frame-based prediction in frame picture */				pred(bwd_rec,0,cur,0,					 lx,16,16,bx,by,					 final_me.MV[0][1][0],final_me.MV[0][1][1],addflag);			}			else			{				/* field-based prediction in frame picture				 *				 * note scaling of the vertical coordinates (by, MV[][1][1])				 * from frame to field!				 */				/* top field prediction */				pred(bwd_rec,final_me.field_sel[0][1],cur,0,					 lx<<1,16,8,bx,by>>1,					 final_me.MV[0][1][0],final_me.MV[0][1][1]>>1,addflag);				/* bottom field prediction */				pred(bwd_rec,final_me.field_sel[1][1],cur,1,					 lx<<1,16,8,bx,by>>1,					 final_me.MV[1][1][0],final_me.MV[1][1][1]>>1,addflag);			}		}		else /* TOP_FIELD or BOTTOM_FIELD */		{			/* field picture */			currentfield = (picture.pict_struct==BOTTOM_FIELD);			if (final_me.motion_type==MC_FIELD)			{				/* field-based prediction in field picture */				pred(bwd_rec,final_me.field_sel[0][1],cur,currentfield,					 lx<<1,16,16,bx,by,					 final_me.MV[0][1][0],final_me.MV[0][1][1],addflag);			}			else if (final_me.motion_type==MC_16X8)			{				/* 16 x 8 motion compensation in field picture */				/* upper half */				pred(bwd_rec,final_me.field_sel[0][1],cur,currentfield,					 lx<<1,16,8,bx,by,					 final_me.MV[0][1][0],final_me.MV[0][1][1],addflag);				/* lower half */				pred(bwd_rec,final_me.field_sel[1][1],cur,currentfield,					 lx<<1,16,8,bx,by+8,					 final_me.MV[1][1][0],final_me.MV[1][1][1],addflag);			}			else			{				/* invalid motion_type in field picture */				mjpeg_error_exit1("Internal: invalid motion_type");			}		}	}}

⌨️ 快捷键说明

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