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

📄 vop_code.c

📁 实现在linux下的mpeg4编解码
💻 C
字号:
/************************************************************************** *                                                                        * * This code is developed by Adam Li.  This software is an                * * implementation of a part of one or more MPEG-4 Video tools as          * * specified in ISO/IEC 14496-2 standard.  Those intending to use this    * * software module in hardware or software products are advised that its  * * use may infringe existing patents or copyrights, and any such use      * * would be at such party's own risk.  The original developer of this     * * software module and his/her company, and subsequent editors and their  * * companies (including Project Mayo), will have no liability for use of  * * this software or modifications or derivatives thereof.                 * *                                                                        * * Project Mayo gives users of the Codec a license to this software       * * module or modifications thereof for use in hardware or software        * * products claiming conformance to the MPEG-4 Video Standard as          * * described in the Open DivX license.                                    * *                                                                        * * The complete Open DivX license can be found at                         * * http://www.projectmayo.com/opendivx/license.php .                      * *                                                                        * **************************************************************************//************************************************************************** * *  vop_code.c * *  Copyright (C) 2001  Project Mayo * *  Adam Li * *  DivX Advance Research Center <darc@projectmayo.com> * **************************************************************************//* This file contains some functions to do coding of one VOP.            */#include "vop_code.h"#include "mot_est_comp.h"//#include "rc_q2.h"#include "bitstream.h"#include "rate_ctl.h"#define SCENE_CHANGE_THREADHOLD 50#define MB_RATIO_THREADHOLD 0.40extern FILE *ftrace;UInt  	BitstreamPutVopHeader (	Vop *vop,			Float time,			VolConfig *vol_config	);Void ImageRepetitivePadding(Image *image, Int edge);Double compute_MAD(Vop *vop);/***********************************************************CommentBegin****** * * -- VopCode -- Shape, texture and motion coding of the vop * * Purpose : * This function performs shape, texture and motion coding of the * vop passed to it. The input vop is assumed to be BOUNDED. * * Arguments in : * Vop *curr - pointer to vop to be coded * Vop *prev - pointer the last occurence of this vop * Vop *rec_prev - pointer to last coded occurence of this vop * Int enable_8x8_mv - 8x8 motion vectors flag (SpSc) * Int intra_dcpred_disable - disable intradc prediction * Float time - * VolConfig *vol_config - * * Arguments in/out : * Vop *rec_curr - coded vop * Bitcount num_bits - BitCount structures  * ***********************************************************CommentEnd********/Void VopCode(Vop *curr,Vop *reference,Vop *reconstruct,Vop *error,Int enable_8x8_mv,Float time,VolConfig *vol_config){	ImageF    *mot_x=NULL, *mot_y=NULL;	Image     *MB_decisions=NULL;	Int       edge,f_code_for=1;	Vop       *error_vop=NULL;	Int       vop_quantizer;	Float	  mad_P = 0., mad_I = 0.;	Float	  IntraMBRatio = 1.;	Int		  numberMB, i, IntraMB;	edge = 0;	f_code_for = curr->fcode_for;	if (curr->prediction_type == P_VOP) 	{		/* Carry out motion estimation and compensation*/		MotionEstimationCompensation(curr, reference,			enable_8x8_mv, edge ,f_code_for,			reconstruct, &mad_P, &mot_x,&mot_y,&MB_decisions);		/* Calculate the percentage of the MBs that are Intra */		IntraMB = 0;		numberMB = MB_decisions->x * MB_decisions->y;		for (i = 0; i < numberMB; i ++)			if (MB_decisions->f[i] == MBM_INTRA) IntraMB ++;		IntraMBRatio = (float)IntraMB / (float)numberMB;		#ifdef _RC_		fprintf(ftrace, "ME with MAD : %f\n", mad_P);		fprintf(ftrace, "%4.2f of the MBs are I-MBs.\n", IntraMBRatio);		#endif	}	else		mad_P = SCENE_CHANGE_THREADHOLD * 2;	if ((mad_P < SCENE_CHANGE_THREADHOLD / 3) || 		((mad_P < SCENE_CHANGE_THREADHOLD) && (IntraMBRatio < MB_RATIO_THREADHOLD)))	{		// mad is fine. continue to code as P_VOP		curr->prediction_type = P_VOP;		error->prediction_type = P_VOP;		#ifdef _RC_		fprintf(ftrace, "Coding mode : INTER\n");		#endif		vop_quantizer = RateCtlGetQ(mad_P);		curr->quantizer = vop_quantizer;		error->quantizer = vop_quantizer;		#ifdef _RC_DEBUG_		fprintf(stdout, "RC: >>>>> New quantizer= %d\n", vop_quantizer);		#endif		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); 		BitstreamPutVopHeader(curr,time,vol_config);		VopShapeMotText(error, reconstruct, MB_decisions,			mot_x, mot_y, f_code_for, 			GetVopIntraACDCPredDisable(curr), reference,			NULL/*mottext_bitstream*/);	} else {		// mad is too large. 		// the coding mode should be I_VOP		curr->prediction_type = I_VOP;		curr->rounding_type = 1;		#ifdef _RC_		fprintf(ftrace, "Coding mode : INTRA\n");		#endif		// 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.		if (mad_I == 0.) mad_I = (Float) compute_MAD(curr);		vop_quantizer = RateCtlGetQ(mad_I);		curr->intra_quantizer = vop_quantizer;		curr->rounding_type = 1;		BitstreamPutVopHeader(curr,time,vol_config);		/* Code Texture in Intra mode */		VopCodeShapeTextIntraCom(curr,			reference,			NULL/*texture_bitstream*/		);	} 	if (MB_decisions) FreeImage(MB_decisions);	if (mot_x) FreeImage(mot_x);	if (mot_y) FreeImage(mot_y);	ImageRepetitivePadding(reference->y_chan, 16);	ImageRepetitivePadding(reference->u_chan, 8);	ImageRepetitivePadding(reference->v_chan, 8);	Bitstream_NextStartCode();	  	return;}												  /* CodeVop() *//***********************************************************CommentBegin****** * * -- BitstreamPutVopHeader -- Writes all fields of the vop header syntax * * Purpose : *	This function writes all fields of the vop header syntax to the * bitstream disk file. * * Arguments in : *	Vop *vop - pointer to vop containing header information * * Return values : *	UInt num_bits - number of bits written * * Description : *	The vop header (start_code, vop_ID, etc.) is first *	written to an intermediate integer level bitstream data structure. *	This intermediate bitstream data structure is then written to disk. * ***********************************************************CommentEnd********/UIntBitstreamPutVopHeader(Vop *vop,Float time, VolConfig *vol_config){	Image *buffer = NULL;	Int bits;	Int   time_modulo;	Float time_inc;	Int   index;	UInt  num_bits_header=0;	/* 	 *	 * Write all syntax fields in vop header to data structure	 *	 */	BitstreamPutBits(buffer,VOP_START_CODE,VOP_START_CODE_LENGTH);	BitstreamPutBits(buffer,GetVopPredictionType(vop),2);	index = GetVolConfigModTimeBase(vol_config, 1);	time_modulo = (int)time - index*1000;	while(time_modulo >= 1000)	{		BitstreamPutBits(buffer,1,1);		time_modulo = time_modulo - 1000;		index++;		printf("time modulo : 1\n");	}	BitstreamPutBits(buffer,0,1);	/* Store this modulo time base */	PutVolConfigModTimeBase(index,vol_config);	time_inc = (time - index*1000);	bits = (int)ceil(log((double)GetVopTimeIncrementResolution(vop))/log(2.0));	if (bits<1) bits=1;	time_inc=time_inc*GetVopTimeIncrementResolution(vop)/1000.0f;	/* marker bit */	BitstreamPutBits(buffer,1,1);	BitstreamPutBits(buffer,(Int)(time_inc+0.001),bits);	/* marker bit */	BitstreamPutBits(buffer,1,1);	if (GetVopWidth(vop)==0)	{		printf("Empty VOP at %.2f\n",time);		  /* MW 30-NOV-1998 */		BitstreamPutBits(buffer,0L,1L);		num_bits_header += Bitstream_NextStartCode();		return(num_bits_header);	}	else		BitstreamPutBits(buffer,1L,1L);	if( GetVopPredictionType(vop) == P_VOP )		BitstreamPutBits(buffer,GetVopRoundingType(vop),1);	BitstreamPutBits(buffer,GetVopIntraDCVlcThr(vop),3);	if (GetVopPredictionType(vop) == I_VOP)	  /* I_VOP */		BitstreamPutBits(buffer,GetVopIntraQuantizer(vop),GetVopQuantPrecision(vop));	else   /* P_VOP */		BitstreamPutBits(buffer,GetVopQuantizer(vop),GetVopQuantPrecision(vop));	if (GetVopPredictionType(vop)!=I_VOP)	{		BitstreamPutBits(buffer,GetVopFCodeFor(vop),3);	}	return(num_bits_header);}// do repetitive padding for image// make sure set edge = 16 for Y and 8 for UVVoid ImageRepetitivePadding(Image *image, Int edge){	SInt *p, left, right;	Int width, height, x, y;	p = image->f;	width = image->x;	height = image->y;	/* Horizontal Padding */	for( y=edge; y<height-edge; y++)    {		left = p[y*width+edge];		right = p[y*width+width-edge-1];		for(x=0; x<edge; x++)		{			p[y*width+x] = left;			p[y*width+width-edge+x] = right;		}    }	/* Vertical Padding */    for(y=0; y<edge; y++)        for(x=0; x<width; x++)            p[y*width+x] = p[edge*width+x];			for(y=height-edge; y<height; y++)		for(x=0; x<width; x++)			p[y*width+x] = p[(height-1-edge)*width+x];		return;}/***********************************************************CommentBegin****** * * -- compute_MAD -- * * Purpose : *      Calculate the MAD of a VOP * * Arguments in : *      Vop    *error_vop  - Vop with error residue * ***********************************************************CommentEnd********/// This function is now only called when the coding mode is I_VOP.Double compute_MAD(Vop  *error_vop){	SInt  *curr_in,		*curr_end;	Float *curr_fin,		*curr_fend;	UInt   sxy_in;	Double mad=0.0, dc = 0.0;	Int    cnt=0;	/* Calculate the MAD */	switch (GetImageType(error_vop->y_chan))	{		case SHORT_TYPE:			/* change to AC MAD */			/* calculate average first */			curr_in = (SInt*)GetImageData(error_vop->y_chan);			sxy_in = GetImageSize(error_vop->y_chan);			curr_end = curr_in + sxy_in;			cnt = 0;			while (curr_in != curr_end)			{				dc += *curr_in; //abs(*curr_in);				cnt++;				curr_in++;			}			dc /= cnt;			curr_in = (SInt*)GetImageData(error_vop->y_chan);			sxy_in = GetImageSize(error_vop->y_chan);			curr_end = curr_in + sxy_in;			cnt = 0;			while (curr_in != curr_end)			{				mad += fabs(*curr_in - dc);				cnt++;				curr_in++;			}			mad /= cnt;			break;		case FLOAT_TYPE:			curr_fin = (Float*)GetImageData(error_vop->y_chan);			sxy_in = GetImageSize(error_vop->y_chan);			curr_fend = curr_fin + sxy_in;			cnt = 0;			while (curr_fin != curr_fend)			{				mad += fabs(*curr_fin);				cnt++;				curr_fin++;			}			mad /= cnt;			break;		default: break;	}#ifdef _RC_	fprintf(ftrace, "The MAD of the VOP to be coded is %f.\n", mad);#endif	return mad;}

⌨️ 快捷键说明

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