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

📄 block.c

📁 代码实现了基于ARM7的MPEG-4视频解码器
💻 C
字号:
//*******************************************
//File name:  block.c
//Author:     Anna
//Date:
//*******************************************
#include <stdio.h>
#include <math.h>

#define TOP 1
#define LEFT 0

extern void AAN_INT(short *s);
void idct(short *block);

extern unsigned int zig_zag_scan[64];
extern unsigned int alternate_horizontal_scan[64];
extern unsigned int alternate_vertical_scan[64];

static int getDCsizeLum();
static int getDCsizeChr();
static int getDCdiff();
static void setDCscaler(int block_num);

extern void clearblock (short *psBlock);
extern unsigned int getbits (int n);
extern unsigned int showbits (int n);
extern void flushbits (int n);
extern void dc_recon(int block_num, short * dc_value);
extern void vld_intra_dct();
extern void ac_recon(int block_num, short * psBlock);
extern int ac_rescaling(int block_num, short * psBlock);
extern void ac_store(int block_num, short * psBlock);

extern void iquant(short * psblock, int intraFlag);

extern short block[64];

extern int quantizer; 
extern int dc_scaler;
extern int ac_pred_flag;
extern int predict_dir;
extern int intrablock_rescaled;
extern int quant_type;

extern int last;
extern int run;
extern int level;

typedef struct {
	int last;
	int run;
	int level;
} event_t;

extern event_t vld_inter_dct();


int blockIntra(int block_num,int coded)
{
    int i;
    int j;
    int dct_dc_size, dct_dc_diff;
    
     clearblock(block); // clearblock
  
   // dc coeff
 	setDCscaler(block_num); // calculate DC scaler
 	
 	if (block_num < 4) {
		dct_dc_size = getDCsizeLum();
		if (dct_dc_size != 0) 
			dct_dc_diff = getDCdiff(dct_dc_size);
		else 
			dct_dc_diff = 0;
		if (dct_dc_size > 8)
			getbits(1); // marker bit
	}
	else {
		dct_dc_size = getDCsizeChr();   
		if (dct_dc_size != 0)
			dct_dc_diff = getDCdiff(dct_dc_size);
		else 
			dct_dc_diff = 0;
		if (dct_dc_size > 8)
			getbits(1); // marker bit
	}
	block[0] = (short) dct_dc_diff;
	
	// dc reconstruction, prediction direction
	dc_recon(block_num, &block[0]);
	
	if (coded) 
	{
		unsigned int * zigzag; // zigzag scan dir

		if (ac_pred_flag == 1) {

			if (predict_dir == TOP)
				zigzag = alternate_horizontal_scan;
			else
				zigzag = alternate_vertical_scan;
		}
		else {
			zigzag = zig_zag_scan;
		}
		
	/*	for (j=0;j<64;j++)
	{
	    printf("%d,",block[j]);
	    if(j%8==7) printf("\n");
	}*/
		
		i=1;
		do
		{
		 vld_intra_dct();
		  
		  i+=run;
		  block[zigzag[i]] = (short) level;
		 
		  i++;
		}while (!last);   
		
	}	//if coded
	
/* for (j=0;j<64;j++)   //for debug
	{
	    printf("%d,",block[j]);
	    if(j%8==7) printf("\n");
	}*/
// ac reconstruction
	intrablock_rescaled = ac_rescaling(block_num, &block[0]);
	if (! intrablock_rescaled)
	{
	  ac_recon(block_num, &block[0]);
	}
	  ac_store(block_num, &block[0]);
	
	
  /* for (j=0;j<64;j++)   //for debug
	{
	    printf("%d,",block[j]);
	    if(j%8==7) printf("\n");
	}*/
	
	iquant(block,1);
	
	//idct(block);
	AAN_INT(block);
	
/*	for (j=0;j<64;j++)   //for debug
	{
	    printf("%d,",block[j]);
	    if(j%8==7) printf("\n");
	}*/
  
  return 1;
}//first end

/***/

int blockInter(int block_num, int coded)
{

 event_t event;
 unsigned int * zigzag = zig_zag_scan; // zigzag scan dir
	int i;
	
	int q_scale = quantizer;
		int q_2scale = q_scale << 1;
		int q_add = (q_scale & 1) ? q_scale : (q_scale - 1);
			
	
	clearblock(block); // clearblock
	
	// inverse quant type
	//if (quant_type == 0) 
	//{
		
		i = 0;
		do // event vld
		{
			event = vld_inter_dct();

			/***
			if (event.run == -1)
			{
			printf("Error: invalid vld code\n");
			exit(201);
			}
			***/			
			i+= event.run;
			if (event.level > 0) {
				block[zigzag[i]] = (q_2scale * event.level) + q_add;
			}
			else {
				block[zigzag[i]] = (q_2scale * event.level) - q_add;
			}
			
			// _Print("Vld Event: Run Level Last %d %d %d\n", event.run, event.level, event.last);
			
			i++;
		} while (! event.last);
	//}
	
	//idct(block);
	AAN_INT(block);
	
	return 1;

}


/***/
static void setDCscaler(int block_num) 
{
	int type = (block_num < 4) ? 0 : 1;
	int quant = quantizer;

	if (type == 0) {

		if (quant > 0 && quant < 5) 
			dc_scaler = 8;
		else if (quant > 4 && quant < 9) 
			dc_scaler = (2 * quant);
		else if (quant > 8 && quant < 25) 
			dc_scaler = (quant + 8);
		else 
			dc_scaler = (2 * quant - 16);
	}
  else {
		if (quant > 0 && quant < 5) 
			dc_scaler = 8;
		else if (quant > 4 && quant < 25) 
			dc_scaler = ((quant + 13) / 2);
		else 
			dc_scaler = (quant - 6);
	}
}

/***/
static int getDCsizeLum()
{
	int code;

	// [Ag][note] bad code

	if (showbits(11) == 1) {
		flushbits(11);
		return 12;
	}
  if (showbits(10) == 1) {
    flushbits(10);
    return 11;
  }
  if (showbits(9) == 1) {
    flushbits(9);
    return 10;
	}
	if (showbits(8) == 1) {
		flushbits(8);
		return 9;
	}
	if (showbits(7) == 1) {
		flushbits(7);
		return 8;
	}
	if (showbits(6) == 1) {
		flushbits(6);
		return 7;
	}  
	if (showbits(5) == 1) {
		flushbits(5);
		return 6;
	}
	if (showbits(4) == 1) {
		flushbits(4);
		return 5;
	}

	code = showbits(3);

	if (code == 1) {
		flushbits(3);
		return 4;
	} else if (code == 2) {
		flushbits(3);
		return 3;
	} else if (code == 3) {
		flushbits(3);
		return 0;
	}

  code = showbits(2);

  if (code == 2) {
		flushbits(2);
		return 2;
	} else if (code == 3) {
		flushbits(2);
		return 1;
	}     

	return 0;
}

/***/
static int getDCsizeChr()
{
	// [Ag][note] bad code

	if (showbits(12) == 1) {
		flushbits(12);
		return 12;
	}
	if (showbits(11) == 1) {
		flushbits(11);
		return 11;
	}
	if (showbits(10) == 1) {
		flushbits(10);
		return 10;
	}
	if (showbits(9) == 1) {
		flushbits(9);
		return 9;
	}
	if (showbits(8) == 1) {
		flushbits(8);
		return 8;
	}
	if (showbits(7) == 1) {
		flushbits(7);
		return 7;
	}
	if (showbits(6) == 1) {
		flushbits(6);
		return 6;
	}
	if (showbits(5) == 1) {
		flushbits(5);
		return 5;
	}
	if (showbits(4) == 1) {
		flushbits(4);
		return 4;
	} 
	if (showbits(3) == 1) {
		flushbits(3);
		return 3;
	} 

	return (3 - getbits(2));
}
/***/
static int getDCdiff(int dct_dc_size)
{
	int code = getbits(dct_dc_size);
	int msb = code >> (dct_dc_size - 1);
	int tmp = 1 << dct_dc_size;

	if (msb == 0) {
		//return (-1 * (code^((int) pow(2.0,(double)dct_dc_size) - 1)));
		return (-1 * (code^(tmp - 1)));
	}
  else { 
		return code;
	}
}


⌨️ 快捷键说明

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