self.c~

来自「实现在linux下的mpeg4编解码」· C~ 代码 · 共 893 行 · 第 1/2 页

C~
893
字号
	ref_curr = ref_last = ref;	while (ref_curr != NULL)	{		if (ref_curr->handle == handle) break;		ref_last = ref_curr;		ref_curr = ref_last->pnext;	}	// create a reference for the new handle when no match is found	if (ref_curr == NULL)	{		if (enc_opt & ENC_OPT_RELEASE) return ENC_OK;		ref_curr = (REFERENCE *)malloc(sizeof(REFERENCE));		ref_curr->handle = handle;		ref_curr->seq = 0;		ref_curr->curr_run = 0;		ref_curr->pnext = NULL;		if (ref) ref_last->pnext = ref_curr;		else ref = ref_curr;	}	// initialize for a handle if requested	if (enc_opt & ENC_OPT_INIT)	{#ifdef _RC_		ftrace = fopen("trace.txt", "w");		fflush(ftrace);#endif		init_fdct_enc();		init_idct_enc();		// initializing rate control		ref_curr->framerate = ((ENC_PARAM *)param1)->framerate;		ref_curr->bitrate = ((ENC_PARAM *)param1)->bitrate;		ref_curr->rc_period = ((ENC_PARAM *)param1)->rc_period;		ref_curr->rc_reaction_period = ((ENC_PARAM *)param1)->rc_reaction_period;		ref_curr->rc_reaction_ratio = ((ENC_PARAM *)param1)->rc_reaction_ratio;		ref_curr->x_dim = ((ENC_PARAM *)param1)->x_dim;		ref_curr->y_dim = ((ENC_PARAM *)param1)->y_dim;		ref_curr->max_key_interval = ((ENC_PARAM *)param1)->max_key_interval;		ref_curr->search_range = ((ENC_PARAM *)param1)->search_range;		ref_curr->max_quantizer = ((ENC_PARAM *)param1)->max_quantizer;		ref_curr->min_quantizer = ((ENC_PARAM *)param1)->min_quantizer;		ref_curr->current = AllocVop(ref_curr->x_dim, ref_curr->y_dim);		ref_curr->reference = AllocVop(ref_curr->x_dim + 2 * 16, 			ref_curr->y_dim + 2 * 16);		ref_curr->reconstruct = AllocVop(ref_curr->x_dim, ref_curr->y_dim);		ref_curr->error = AllocVop(ref_curr->x_dim, ref_curr->y_dim);		init_vop(ref_curr->current);		init_vop(ref_curr->reference);		init_vop(ref_curr->reconstruct);		init_vop(ref_curr->error);		ref_curr->reference->hor_spat_ref = -16;		ref_curr->reference->ver_spat_ref = -16;		SetConstantImage(ref_curr->reference->y_chan, 0);		vol_config = (VolConfig *)malloc(sizeof(VolConfig));		init_vol_config(vol_config);		vol_config->frame_rate = ref_curr->framerate;		vol_config->bit_rate = ref_curr->bitrate;		RateCtlInit(8 /* initial quant*/, vol_config->bit_rate / vol_config->frame_rate,			ref_curr->rc_period, ref_curr->rc_reaction_period, ref_curr->rc_reaction_ratio);		return ENC_OK;	}	// release the reference associated with the handle if requested	if (enc_opt & ENC_OPT_RELEASE)	{		if (ref_curr == ref) ref = NULL;		else ref_last->pnext = ref_curr->pnext;		if (ref_curr->current) FreeVop(ref_curr->current);		if (ref_curr->reference) FreeVop(ref_curr->reference);		if (ref_curr->reconstruct) FreeVop(ref_curr->reconstruct);		if (ref_curr->error) FreeVop(ref_curr->error);		free(ref_curr);		free(vol_config);		if (ftrace) {			fclose(ftrace);			ftrace = NULL;		};		return ENC_OK;	}	// initialize the parameters (need to be cleaned later)	max_quantizer = ref_curr->max_quantizer;	min_quantizer = ref_curr->min_quantizer;	x_dim = ref_curr->x_dim;	y_dim = ref_curr->y_dim;	size = x_dim * y_dim;	curr = ref_curr->current;	curr->width = x_dim;	curr->height = y_dim;	curr->sr_for = ref_curr->search_range;	curr->fcode_for = get_fcode(curr->sr_for);	// do transformation for the input image	// this is needed because the legacy MoMuSys code uses short int for each data	YUV2YUV(x_dim, y_dim, ((ENC_FRAME *)param1)->image,		curr->y_chan->f, curr->u_chan->f, curr->v_chan->f);	// adjust the rounding_type for the current image	curr->rounding_type = 1 - ref_curr->prev_rounding;	Bitstream_Init((void *)(((ENC_FRAME *)param1)->bitstream));	if (ref_curr->seq == 0) {		headerbits = PutVoVolHeader(x_dim, y_dim, curr->time_increment_resolution, ref_curr->framerate);	}	#ifdef _RC_	fflush(ftrace);	fprintf(ftrace, "\nCoding frame #%d\n", ref_curr->seq);#endif	if (ref_curr->curr_run % ref_curr->max_key_interval == 0) {		curr->prediction_type = I_VOP;#ifdef _RC_	fprintf(ftrace, "This frame is forced to be coded in INTRA.\n");	fprintf(ftrace, "It has been %d frame since the last INTRA.\n", ref_curr->curr_run);#endif	}	else curr->prediction_type = P_VOP;	// Code the image data (YUV) of the current image	VopCode(curr,		ref_curr->reference,		ref_curr->reconstruct,		ref_curr->error,		1, //enable_8x8_mv,		(float)ref_curr->seq/ref_curr->framerate,  // time		vol_config);	length = Bitstream_Close();	((ENC_FRAME *)param1)->length = length;	// update the rate control parameters	RateCtlUpdate(length * 8);	ref_curr->prev_rounding = curr->rounding_type;	ref_curr->seq ++;	ref_curr->curr_run ++;	if (curr->prediction_type == I_VOP) {		((ENC_RESULT *)param2)->isKeyFrame = 1;		ref_curr->curr_run = 1;	} else 		((ENC_RESULT *)param2)->isKeyFrame = 0;	return ENC_OK;}int encode(char infile[],char outfile[])//for encode{	printf("待编码文件%s\n",infile);	printf("编码后文件%s\n",outfile);	printf("读入文件\n");	FILE *f_in = fopen(infile,"rb");	FILE *f_out= fopen(outfile,"wb");	printf("设置参数值\n");	ENC_PARAM encParam;	encParam.x_dim = 352;	encParam.y_dim = 288;	encParam.framerate=30;	encParam.bitrate=800000;	encParam.rc_period=200;	encParam.rc_reaction_period=10;	encParam.rc_reaction_ratio=20;	encParam.max_key_interval=300;	encParam.max_quantizer=16;	encParam.min_quantizer=1;	encParam.search_range=15;      	printf("编码前检测\n");	encore(1, ENC_OPT_INIT, &encParam, NULL);//	startTimer();	clock_t   start,   finish; 	double   duration; 	printf("开始计时\n");	start   =   clock(); 	// decode frames	{		printf("编码参数配置");	        int size=encParam.x_dim*encParam.y_dim*3/2;		int frames,i;		ENC_FRAME encFrame;		ENC_RESULT Result;		                encFrame.image=(void *)malloc(size);	//	encFrame.bitstream=NULL;	        encFrame.bitstream=(void *)malloc(size);		encFrame.length=0;		Result.isKeyFrame=0;						printf("待编码文件重读入\n");                fseek(f_in,0,SEEK_END);		frames=ftell(f_in)/size;		fseek(f_in,0,SEEK_SET);		rewind(f_in);		printf("编码中。。。\n");		for(i=0;i<frames;i++) 		{				fread((char *)encFrame.image,1,size,f_in);			if(encore(1,ENC_OPT_WRITE, &encFrame, &Result) != ENC_OK) //编码时有错误检测			{		    		printf("Error accurs when encode Frame %d\n",i);		   		 return 0;		 	}			 fwrite((char *)encFrame.bitstream,1,encFrame.length,f_out);	       }  	}	encore(1, ENC_OPT_RELEASE, NULL, NULL);	printf("关闭文件\n");	fclose(f_in);	fclose(f_out);	finish   =   clock(); 	duration   =   (double)(finish   -   start)   /   CLOCKS_PER_SEC; 	printf(   "总共耗时%f秒 \n ",   duration   ); //	stopTimer();//	displayTimer(mp4_state->hdr.picnum);}int main (int argc, char *argv[],char argn[]){	if(argc == 1)	{	printf("用法:./mp4enc 目标文件名 生成文件名 n(1表示编码2解码)");	}	if(strcmp(argv[3],"enc")==0)	{		encode(argv[1],argv[2]);	}	else if(strcmp(argv[3],"dec")==0)	{printf("jie");		decode(argv[1],argv[2]);		}	return 1;}void init_vol_config(VolConfig *vol_config){	/* configure VOL */	vol_config->M = 1;	vol_config->frame_skip = 1;	vol_config->quantizer = 8;	vol_config->intra_quantizer = 8;	vol_config->modulo_time_base[0] =0;	vol_config->modulo_time_base[1] =0;	vol_config->frame_rate = 30;	vol_config->bit_rate = 800000;}void init_vop(Vop *vop){	/* initialize VOPs */	vop->quant_precision = 5;	vop->bits_per_pixel = 8;//	vop->time_increment_resolution = 15 ;	vop->time_increment_resolution = 30000;	vop->intra_acdc_pred_disable = 0;	vop->intra_dc_vlc_thr = 0;	vop->sr_for = 512;	vop->fcode_for = get_fcode(512);	vop->y_chan->type = SHORT_TYPE;	vop->u_chan->type = SHORT_TYPE;	vop->v_chan->type = SHORT_TYPE;	vop->hor_spat_ref = 0;	vop->ver_spat_ref = 0;}Int get_fcode (Int sr){	if (sr<=16) return 1;	else if (sr<=32) return 2;	else if (sr<=64) return 3;	else if (sr<=128) return 4;	else if (sr<=256) return 5;	else if (sr<=512) return 6;	else if (sr<=1024) return 7;	else return (-1);}int PutVoVolHeader(int vol_width, int vol_height, int time_increment_resolution, float frame_rate){	int written = 0;	int bits, fixed_vop_time_increment;	Bitstream_PutBits(VO_START_CODE_LENGTH, VO_START_CODE);	Bitstream_PutBits(5, 0);				/* vo_id = 0								*/	written += VO_START_CODE_LENGTH + 5;	Bitstream_PutBits(VOL_START_CODE_LENGTH, VOL_START_CODE);	Bitstream_PutBits(4, 0);				/* vol_id = 0								*/	written += VOL_START_CODE_LENGTH + 4;	Bitstream_PutBits(1, 0);				/* random_accessible_vol = 0				*/	Bitstream_PutBits(8, 1);				/* video_object_type_indication = 1 video	*/	Bitstream_PutBits(1, 1);				/* is_object_layer_identifier = 1			*/	Bitstream_PutBits(4, 2);				/* visual_object_layer_ver_id = 2			*/	Bitstream_PutBits(3, 1);				/* visual_object_layer_priority = 1			*/	written += 1 + 8 + 1 + 4 + 3;	Bitstream_PutBits(4, 1);				/* aspect_ratio_info = 1					*/	Bitstream_PutBits(1, 0);				/* vol_control_parameter = 0				*/	Bitstream_PutBits(2, 0);				/* vol_shape = 0 rectangular				*/	Bitstream_PutBits(1, 1);				/* marker									*/	written += 4 + 1 + 2 + 1;	Bitstream_PutBits(16, time_increment_resolution);	Bitstream_PutBits(1, 1);				/* marker									*/	Bitstream_PutBits(1, 1);				/* fixed_vop_rate = 1						*/	bits = (int)ceil(log((double)time_increment_resolution)/log(2.0));    if (bits<1) bits=1;	fixed_vop_time_increment = (int)(time_increment_resolution / frame_rate + 0.1);	Bitstream_PutBits(bits, fixed_vop_time_increment);	Bitstream_PutBits(1, 1);				/* marker									*/	written += 16 + 1 + 1 + bits + 1;	Bitstream_PutBits(13, vol_width);	Bitstream_PutBits(1, 1);				/* marker									*/	Bitstream_PutBits(13, vol_height);	Bitstream_PutBits(1, 1);				/* marker									*/	written += 13 + 1 + 13 + 1;	Bitstream_PutBits(1, 0);				/* interlaced = 0							*/	Bitstream_PutBits(1, 1);				/* OBMC_disabled = 1						*/	Bitstream_PutBits(2, 0);				/* vol_sprite_usage = 0						*/	Bitstream_PutBits(1, 0);				/* not_8_bit = 0							*/	written += 1 + 1 + 2 + 1;	Bitstream_PutBits(1, 0);				/* vol_quant_type = 0						*/	Bitstream_PutBits(1, 0);				/* vol_quarter_pixel = 0					*/	Bitstream_PutBits(1, 1);				/* complexity_estimation_disabled = 1		*/	Bitstream_PutBits(1, 1);				/* resync_marker_disabled = 1				*/	Bitstream_PutBits(1, 0);				/* data_partitioning_enabled = 0			*/	Bitstream_PutBits(1, 0);				/* scalability = 0							*/	written += 1 + 1 + 1 + 1 + 1 + 1;	written += Bitstream_NextStartCode();	return(written);}int YUV2YUV (int x_dim, int y_dim, void *yuv, void *y_out, void *u_out, void *v_out){	// All this conversion does is to turn data from unsigned char to short int,	// since legacy MoMuSys uses short int.	unsigned char *in;	short int *out;	long size;	in = yuv;		out = y_out;	size = x_dim * y_dim;	while (size --) *(out ++) = *(in ++);	out = u_out;	size = x_dim * y_dim / 4;	while (size --) *(out ++) = *(in ++);	out = v_out;	size = x_dim * y_dim / 4;	while (size --) *(out ++) = *(in ++);	return 0;}static void options (int *argcp, char **argvp[]){	(*argvp)++;	(*argcp)--;  while (*argcp > 1 && (*argvp)[1][0] == '-')  {    switch (toupper ((*argvp)[1][1]))    {      case 'O':				mp4_state->output_flag = 1;        mp4_state->outputname = (*argvp)[2];				(*argvp) += 2;				(*argcp) -= 2;				break;			case 'J':				mp4_state->juice_flag = 1;				mp4_state->juice_hor = atoi ((*argvp)[2]);				mp4_state->juice_ver = atoi ((*argvp)[3]);		    (*argvp) += 3;				(*argcp) -= 3;				break;      default:        printf ("Error: Undefined option -%c ignored\n", (*argvp)[1][1]);    }  }}/***/static void optionhelp(int *argcp){  if (*argcp < 2)  {    _Print ("Usage: opendivx_dec bitstream {options} \n");		_Print ("Options: -o {outputfilename} YUV concatenated file output\n");		_Print ("         -j {hor_size ver_size} juice stream and its picture format\n");    exit (0);  }}int dec_reinit(){  if (ld->infile != 0)    lseek (ld->infile, 0l, 0);  initbits (NULL, 0);	return 1;}/***/#endif // !_DECORE

⌨️ 快捷键说明

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