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

📄 picture.c

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

#define mmax(a, b)      ((a) > (b) ? (a) : (b))
#define mmin(a, b)      ((a) < (b) ? (a) : (b))

#define DEC_MBC         45
#define DEC_MBR         36
extern int	MV[2][6][DEC_MBR+1][DEC_MBC+2];


extern int mba;
extern int mb_xpos;
extern int mb_ypos;
extern int mba_size;
extern int coded_picture_width;
extern int chrom_width;
extern int chrom_height;
extern short block[64];
extern	char * outputname;
extern int width;
extern int height;
extern int horizontal_size;
extern int picnum;

//extern int blockintra_num;

extern unsigned char	*edged_ref[3],
									*edged_for[3],
									*frame_ref[3],
									*frame_for[3],
									*display_frame[3];

extern int macroblock();
void transferIDCT_copy(short *sourceS16, unsigned char *destU8, int stride);
void transferIDCT_add(short *sourceS16, unsigned char *destU8, int stride);
void PictureDisplay (unsigned char *bmp, unsigned int stride, int render_flag);

static void make_edge (unsigned char *frame_pic, int width, int height, int edge);

#define RGB_GET
#ifdef RGB_GET
void storeframe_rgb();
#define RGB
#endif

int  nextbits_bytealigned(int nbit);

void get_mp4picture (unsigned char *bmp, unsigned int stride, int render_flag)
{
    mba = 0;
	mb_xpos = 0;
	mb_ypos = 0;
	
	//blockintra_num=0;
 	
	do {
		macroblock();
		mba++; 

	} while ((nextbits_bytealigned(23) != 0) &&
		(mba < mba_size));
		
	// add edge to decoded fram	make_edge (frame_ref[0], mp4_state->coded_picture_width, mp4_state->coded_picture_height, 32);
	make_edge (frame_ref[1], chrom_width, chrom_height, 16);
	make_edge (frame_ref[2], chrom_width, chrom_height, 16);
	
	PictureDisplay(bmp, stride, render_flag);
	
	// exchange ref and for frames
	{
		int i;
		unsigned char *tmp;
		for (i = 0; i < 3; i++) {
			tmp = frame_ref[i];
			frame_ref[i] = frame_for[i];
			frame_for[i] = tmp;
		}
	} 

}//first end


void addblockIntra (int comp, int bx, int by)
{
  int cc, iincr;
  unsigned char *rfp;
  short *bp;
  unsigned char *curr[3];
  
  curr[0] = frame_ref[0];
  curr[1] = frame_ref[1];
  curr[2] = frame_ref[2];
  
  bp=block;
  
  cc = (comp < 4) ? 0 : (comp & 1) + 1; /* color component index */
  
  if (cc == 0) // luminance
  {
		// pixel coordinates
		bx <<= 4;
		by <<= 4;
    // frame DCT coding

		rfp = curr[0] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
    iincr = coded_picture_width;
  } 
  else // chrominance
  {
    // pixel coordinates
		bx <<= 3;
		by <<= 3;
    // frame DCT coding
		rfp = curr[cc] + chrom_width * by + bx;
    iincr = chrom_width;
  }
  
   transferIDCT_copy(bp, rfp, iincr); 
}

/***/
void addblockInter (int comp, int bx, int by)
{
  int cc, iincr;
  unsigned char *rfp;
  short *bp;
  unsigned char *curr[3];

	curr[0] = frame_ref[0];
	curr[1] = frame_ref[1];
	curr[2] = frame_ref[2];

  bp =  block;

  cc = (comp < 4) ? 0 : (comp & 1) + 1; /* color component index */

  if (cc == 0) // luminance
  {
		// pixel coordinates
		bx <<= 4;
		by <<= 4;
    // frame DCT coding

		rfp = curr[0] + coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
    iincr = coded_picture_width;
  } 
  else // chrominance
  {
    // pixel coordinates
		bx <<= 3;
		by <<= 3;
    // frame DCT coding
		rfp = curr[cc] + chrom_width * by + bx;
    iincr = chrom_width;
  }
/***
  for (int i = 0; i < 8; i++)
  {
    rfp[0] = clp[bp[0] + rfp[0]];
    rfp[1] = clp[bp[1] + rfp[1]];
    rfp[2] = clp[bp[2] + rfp[2]];
    rfp[3] = clp[bp[3] + rfp[3]];
    rfp[4] = clp[bp[4] + rfp[4]];
    rfp[5] = clp[bp[5] + rfp[5]];
    rfp[6] = clp[bp[6] + rfp[6]];
    rfp[7] = clp[bp[7] + rfp[7]];
    bp += 8;
    rfp += iincr;
  }
***/ transferIDCT_add(bp, rfp, iincr);
}

/***/
// Purpose: compute motion vector prediction
int find_pmv (int block_num, int comp)
{
  int p1, p2, p3;
  int xin1, xin2, xin3;
  int yin1, yin2, yin3;                   
  int vec1, vec2, vec3;

	int x = mb_xpos;
	int y = mb_ypos;
	
	if ((y == 0) && ((block_num == 0) || (block_num == 1)))
	{
		if ((x == 0) && (block_num == 0))
			return 0;
		else if (block_num == 1)
			return MV[comp][0][y+1][x+1];
		else // block == 0
			return MV[comp][1][y+1][x+1-1];
	}
	else
	{
		// considerate border (avoid increment inside each single array index)
		x++;
		y++;

		switch (block_num)
		{
			case 0: 
				vec1 = 1;	yin1 = y;		xin1 = x-1;
				vec2 = 2;	yin2 = y-1;	xin2 = x;
				vec3 = 2;	yin3 = y-1;	xin3 = x+1;
				break;
			case 1:
				vec1 = 0;	yin1 = y;		xin1 = x;
				vec2 = 3;	yin2 = y-1;	xin2 = x;
				vec3 = 2;	yin3 = y-1;	xin3 = x+1;
				break;
			case 2:
				vec1 = 3;	yin1 = y;		xin1 = x-1;
				vec2 = 0;	yin2 = y;	  xin2 = x;
				vec3 = 1;	yin3 = y;		xin3 = x;
				break;
			default: // case 3
				vec1 = 2;	yin1 = y;		xin1 = x;
				vec2 = 0;	yin2 = y;		xin2 = x;
				vec3 = 1;	yin3 = y;		xin3 = x;
				break;
		}
		p1 = MV[comp][vec1][yin1][xin1];
		p2 = MV[comp][vec2][yin2][xin2];
		p3 = MV[comp][vec3][yin3][xin3];

		// return p1 + p2 + p3 - mmax (p1, mmax (p2, p3)) - mmin (p1, mmin (p2, p3));
		return mmin(mmax(p1, p2), mmin(mmax(p2, p3), mmax(p1, p3)));
	}
}

/***/

void make_edge (unsigned char *frame_pic,
                int edged_width, int edged_height, int edge)
{
  int j;

	int width = edged_width - (2*edge);
	int height = edged_height - (2*edge);
	
	unsigned char *p_border;
	unsigned char *p_border_top, *p_border_bottom;
	unsigned char *p_border_top_ref, *p_border_bottom_ref;

	// left and right edges
	p_border = frame_pic;

	for (j = 0; j < height; j++)
	{
		unsigned char border_left = *(p_border);
		unsigned char border_right = *(p_border + (width-1));

		memset((p_border - edge), border_left, edge);
		memset((p_border + width), border_right, edge);

		p_border += edged_width;
	}

	// top and bottom edges
	p_border_top_ref = frame_pic;
	p_border_bottom_ref = frame_pic + (edged_width * (height -1));
	p_border_top = p_border_top_ref - (edge * edged_width);
	p_border_bottom = p_border_bottom_ref + edged_width;

	for (j = 0; j < edge; j++)
	{
		memcpy(p_border_top, p_border_top_ref, width);
		memcpy(p_border_bottom, p_border_bottom_ref, width);

		p_border_top += edged_width;
		p_border_bottom += edged_width;
	}

  // corners
	{
		unsigned char * p_left_corner_top = frame_pic - edge - (edge * edged_width);
		unsigned char * p_right_corner_top = p_left_corner_top + edge + width;
		unsigned char * p_left_corner_bottom = frame_pic + (edged_width * height) - edge;
		unsigned char * p_right_corner_bottom = p_left_corner_bottom + edge + width;

		char left_corner_top = *(frame_pic);
		char right_corner_top = *(frame_pic + (width-1));
		char left_corner_bottom = *(frame_pic + (edged_width * (height-1)));
		char right_corner_bottom = *(frame_pic + (edged_width * (height-1)) + (width-1));

		for (j = 0; j < edge; j++)
		{
			memset(p_left_corner_top, left_corner_top, edge);
			memset(p_right_corner_top, right_corner_top, edge);
			memset(p_left_corner_bottom, left_corner_bottom, edge);
			memset(p_right_corner_bottom, right_corner_bottom, edge);

			p_left_corner_top += edged_width;
			p_right_corner_top += edged_width;
			p_left_corner_bottom += edged_width;
			p_right_corner_bottom += edged_width;
		}
	}
}

/***/
void PictureDisplay(unsigned char *bmp, unsigned int stride, int render_flag)
{ 

	storeframe_rgb (frame_ref,coded_picture_width, width, height);

}

void storeframe_rgb (unsigned char *src[], int width_off,int width, int height)
{
    int offset_x,offset_y;
	int hor_size = horizontal_size;
	int r,g,b;
	int y,u,v;
	FILE *outfile;
	const char *mode="wb";
	
	if ((outfile = fopen (outputname, mode)) == NULL)
  {
    printf ("\n%d Frames are decoded!", picnum);
    exit(0);
  }
  
#ifdef RGB
  for(offset_y=0;offset_y<height;offset_y++)
  {
	  for(offset_x=0;offset_x<width;offset_x++)
	  {
		  y=(int)src[0][offset_y*width_off+offset_x];
		  u=(int)src[1][(offset_y>>1)*(width_off>>1)+(offset_x>>1)]-128;
		  v=(int)src[2][(offset_y>>1)*(width_off>>1)+(offset_x>>1)]-128;
          
		  u=(u>127) ? 127 :((u<-128) ? -128 : u);
          v=(v>127) ? 127 :((v<-128) ? -128 : v);
		  r=(int)(y+1.402*v);
		  g=(int)(y-0.34414*u-0.71414*v);
		  b=(int)(y+1.772*u);

		  r=(r<0) ? 0 : r;
		  r=(r>255) ? 255 : r;  
		  g=(g<0) ? 0 : g;
		  g=(g>255) ? 255 : g;
		  
		  b=(b<0) ? 0 : b;
		  b=(b>255) ? 255 : b;
		  fputc(r,outfile);
		  putc(g,outfile);
		  putc(b,outfile);

	  }
  }
#endif

   fclose(outfile);
   
     outputname[6]++;
	  if(outputname[6]>57)
	  {
		  outputname[6]-=10;
		  outputname[5]++;
		  if(outputname[5]>57)
		  {
			  outputname[5]-=10;
			  outputname[4]++;
			  if(outputname[4]>48)
			  {
				picnum++;
				printf("\n the decoded picnum is\n");
		        printf("%d",picnum);
				//finish = clock();
               // duration = (double)(finish - start) / 1000;
		       // printf("\n time to decode these frames is\n ");
             //   printf( "%f seconds\n", duration ); 
                exit(0);
			  }
		  }
	  }


}

⌨️ 快捷键说明

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