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

📄 vop_code.c

📁 <VC++视频音频开发>一书的光盘资料。
💻 C
字号:
#include "vop_code.h"
#include "mot_est_comp.h"
#include "bitstream.h"
#include "rate_ctl.h"
#define SCENE_CHANGE_THREADHOLD 50
#define MB_RATIO_THREADHOLD 0.40
extern FILE *ftrace;
UInt  	BitstreamPutVopHeader (	Vop *vop,
			Float time,
			VolConfig *vol_config
	);
Void ImageRepetitivePadding(Image *image, Int edge);
Double compute_MAD(Vop *vop);
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) 
	{
		
		MotionEstimationCompensation(curr, reference,
			enable_8x8_mv, edge ,f_code_for,
			reconstruct, &mad_P, &mot_x,&mot_y,&MB_decisions);
		
		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)))
	{
		
		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);
	} else {
		
		
		curr->prediction_type = I_VOP;
		curr->rounding_type = 1;
		#ifdef _RC_
		fprintf(ftrace, "Coding mode : INTRA\n");
		#endif
		
		
		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);
		
		VopCodeShapeTextIntraCom(curr,
			reference,
			NULL
		);
	} 
	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;
}												  
UInt
BitstreamPutVopHeader(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;
	
	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);
	
	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;
	
	BitstreamPutBits(buffer,1,1);
	BitstreamPutBits(buffer,(Int)(time_inc+0.001),bits);
	
	BitstreamPutBits(buffer,1,1);
	if (GetVopWidth(vop)==0)
	{
		printf("Empty VOP at %.2f\n",time);		  
		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)	  
		BitstreamPutBits(buffer,GetVopIntraQuantizer(vop),GetVopQuantPrecision(vop));
	else   
		BitstreamPutBits(buffer,GetVopQuantizer(vop),GetVopQuantPrecision(vop));
	if (GetVopPredictionType(vop)!=I_VOP)
	{
		BitstreamPutBits(buffer,GetVopFCodeFor(vop),3);
	}
	return(num_bits_header);
}
Void ImageRepetitivePadding(Image *image, Int edge)
{
	SInt *p, left, right;
	Int width, height, x, y;
	p = image->f;
	width = image->x;
	height = image->y;
	
	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;
		}
    }
	
    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;
}
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;
	
	switch (GetImageType(error_vop->y_chan))
	{
		case SHORT_TYPE:
			
			
			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; 
				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 + -