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

📄 getpicture.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "../mpeg3private.h"
#include "mpeg3video.h"
#include "vlc.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int mpeg3video_get_cbp(mpeg3_slice_t *slice)
{
  	int code;
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;

  	if((code = mpeg3slice_showbits9(slice_buffer)) >= 128)
	{
    	code >>= 4;
    	mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab0[code].len);
    	return mpeg3_CBPtab0[code].val;
  	}

  	if(code >= 8)
	{
    	code >>= 1;
    	mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab1[code].len);
    	return mpeg3_CBPtab1[code].val;
  	}

  	if(code < 1)
	{
/*    	fprintf(stderr,"mpeg3video_get_cbp: invalid coded_block_pattern code\n"); */
    	slice->fault = 1;
    	return 0;
  	}

  	mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab2[code].len);
  	return mpeg3_CBPtab2[code].val;
}


/* set block to zero */
int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size)
{
	slice->sparse[comp] = 1;

/* Compiler error with 2.95 required hard coding the size to 6 */

	memset(slice->block[comp], 0, sizeof(short) * 64 * size);
	return 0;
}

static __inline int mpeg3video_getdclum(mpeg3_slice_buffer_t *slice_buffer)
{
	int code, size, val;
/* decode length */
	code = mpeg3slice_showbits5(slice_buffer);

	if(code < 31)
	{
    	size = mpeg3_DClumtab0[code].val;
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab0[code].len);
	}
	else 
	{
    	code = mpeg3slice_showbits9(slice_buffer) - 0x1f0;
    	size = mpeg3_DClumtab1[code].val;
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab1[code].len);
	}

	if(size == 0) val = 0;
	else 
	{
    	val = mpeg3slice_getbits(slice_buffer, size);
    	if((val & (1 << (size - 1))) == 0)  val -= (1 << size) - 1;
	}

	return val;
}


int mpeg3video_getdcchrom(mpeg3_slice_buffer_t *slice_buffer)
{
	int code, size, val;

/* decode length */
	code = mpeg3slice_showbits5(slice_buffer);

	if(code < 31)
	{
    	size = mpeg3_DCchromtab0[code].val;
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab0[code].len);
	}
	else 
	{
    	code = mpeg3slice_showbits(slice_buffer, 10) - 0x3e0;
    	size = mpeg3_DCchromtab1[code].val;
    	mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab1[code].len);
	}

	if(size == 0) val = 0;
	else 
	{
      val = mpeg3slice_getbits(slice_buffer, size);
      if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1;
	}

	return val;
}


/* decode one intra coded MPEG-1 block */

int mpeg3video_getintrablock(mpeg3_slice_t *slice, 
		mpeg3video_t *video,
		int comp, 
		int dc_dct_pred[])
{
	int val, i, j, sign;
	unsigned int code;
	mpeg3_DCTtab_t *tab = 0;
	short *bp = slice->block[comp];
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;

/* decode DC coefficients */
  	if(comp < 4)         
  		bp[0] = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)) << 3;
  	else 
  	if(comp == 4)   
  		bp[0] = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)) << 3;
	else                
  		bp[0] = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)) << 3;

#ifdef HAVE_MMX
	if(video->have_mmx)
  		bp[0] <<= 4;
#endif

  	if(slice->fault) return 1;

/* decode AC coefficients */
  	for(i = 1; ; i++)
	{
    	code = mpeg3slice_showbits16(slice_buffer);
    	if(code >= 16384)
			tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
    	else 
		if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
    	else 
		if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
    	else 
		if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
    	else 
		if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
    	else 
		if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
    	else 
		if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
    	else 
		if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
    	else 
		{
/*    	  	fprintf(stderr, "mpeg3video_getintrablock: invalid Huffman code\n"); */
    	  	slice->fault = 1;
    	  	return 0;
    	}

    	mpeg3slice_flushbits(slice_buffer, tab->len);

    	if(tab->run == 64) break;  /* end_of_block */

    	if(tab->run == 65)
		{
/* escape */
    		i += mpeg3slice_getbits(slice_buffer, 6);

    		if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0) 
				val = mpeg3slice_getbits(slice_buffer, 8);
    		else 
			if(val == 128)         
				val = mpeg3slice_getbits(slice_buffer, 8) - 256;
    		else 
			if(val > 128)          
				val -= 256;

    		if((sign = (val < 0)) != 0) val= -val;
    	}
    	else 
		{
    		i += tab->run;
    		val = tab->level;
    		sign = mpeg3slice_getbit(slice_buffer);
    	}

		if(i < 64)
	    	j = video->mpeg3_zigzag_scan_table[i];
		else
		{
    	  	slice->fault = 1;
    	  	return 0;
		}
			

#ifdef HAVE_MMX
		if(video->have_mmx)
		{
    		val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) << 1;
    		val = (val - 16) | 16;
		}
		else
#endif
		{
    		val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) >> 3;
    		val = (val - 1) | 1;
		}

    	bp[j] = sign ? -val : val;
	}

	if(j != 0) 
	{
/* not a sparse matrix ! */
       slice->sparse[comp] = 0;
	}
	return 0;
}


/* decode one non-intra coded MPEG-1 block */

int mpeg3video_getinterblock(mpeg3_slice_t *slice, 
		mpeg3video_t *video, 
		int comp)
{
	int val, i, j, sign;
	unsigned int code;
	mpeg3_DCTtab_t *tab; 
	short *bp = slice->block[comp];
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;

/* decode AC coefficients */
	for(i = 0; ; i++)
	{
    	code = mpeg3slice_showbits16(slice_buffer);
    	if(code >= 16384)
		{
    	    if(i == 0) 
				tab = &mpeg3_DCTtabfirst[(code >> 12) - 4];
    	    else      
				tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
    	}
    	else 
		if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
    	else 
		if(code >= 512)  tab = &mpeg3_DCTtab1[(code >> 6) - 8];
    	else 
		if(code >= 256)  tab = &mpeg3_DCTtab2[(code >> 4) - 16];
    	else 
		if(code >= 128)  tab = &mpeg3_DCTtab3[(code >> 3) - 16];
    	else 
		if(code >= 64)   tab = &mpeg3_DCTtab4[(code >> 2) - 16];
    	else 
		if(code >= 32)   tab = &mpeg3_DCTtab5[(code >> 1) - 16];
    	else 
		if(code >= 16)   tab = &mpeg3_DCTtab6[code - 16];
    	else 
		{
// invalid Huffman code
    		slice->fault = 1;
    		return 1;
    	}

    	mpeg3slice_flushbits(slice_buffer, tab->len);

/* end of block */
    	if(tab->run == 64)
    	   break;   

    	if(tab->run == 65)
		{          
/* escape  */
    		i += mpeg3slice_getbits(slice_buffer, 6);
    		if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0) 
				val = mpeg3slice_getbits(slice_buffer, 8);
    		else 
			if(val == 128)  
				val = mpeg3slice_getbits(slice_buffer, 8) - 256;
    		else 
			if(val > 128) 
				val -= 256;

    		if((sign = (val < 0)) != 0) val = -val;
    	}
    	else 
		{
    		i += tab->run;
    		val = tab->level;
    		sign = mpeg3slice_getbit(slice_buffer);
    	}

    	j = video->mpeg3_zigzag_scan_table[i];

#ifdef HAVE_MMX
		if(video->have_mmx)
		{
    		val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]);
    		val = (val - 16) | 16;
		}
		else
#endif
		{
    		val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]) >> 4;
    		val = (val - 1) | 1;
		}

    	bp[j] = sign ? -val : val;
	}

	if(j != 0) 
	{
/* not a sparse matrix ! */
       slice->sparse[comp] = 0;
	}
	return 0;
}


/* decode one intra coded MPEG-2 block */
int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice, 
		mpeg3video_t *video, 
		int comp, 
		int dc_dct_pred[])
{
	int val, i, j, sign, nc;
	unsigned int code;
	mpeg3_DCTtab_t *tab;
	short *bp;
	int *qmat;
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;

/* with data partitioning, data always goes to base layer */
  	bp = slice->block[comp];

  	qmat = (comp < 4 || video->chroma_format == CHROMA420)
         ? video->intra_quantizer_matrix
         : video->chroma_intra_quantizer_matrix;

/* decode DC coefficients */
	if(comp < 4)           
		val = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer));
	else 
	if((comp & 1) == 0) 
		val = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer));
	else                  
		val = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer));

  	if(slice->fault) return 0;
#ifdef HAVE_MMX
	if(video->have_mmx)
  		bp[0] = val << (7 - video->dc_prec);
	else
#endif
  		bp[0] = val << (3 - video->dc_prec);

  	nc = 0;

/* decode AC coefficients */
  	for(i = 1; ; i++)
	{
    	code = mpeg3slice_showbits16(slice_buffer);

    	if(code >= 16384 && !video->intravlc)
			tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
    	else 
		if(code >= 1024)
		{
    		if(video->intravlc) 
				tab = &mpeg3_DCTtab0a[(code >> 8) - 4];
    		else 
				tab = &mpeg3_DCTtab0[(code >> 8) - 4];
    	}
    	else 
		if(code >= 512)
		{
    		if(video->intravlc)     
		  	  	tab = &mpeg3_DCTtab1a[(code >> 6) - 8];
    		else              
				tab = &mpeg3_DCTtab1[(code >> 6) - 8];
    	}
    	else 
		if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];

⌨️ 快捷键说明

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