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

📄 mvdecodec.c

📁 优化过的xvid1.1.2源代码
💻 C
字号:
#include <string.h>
#include "MVCommon.h"
#include "MVTable.h"

#include "MVBitstream.h"
#include "MVIdct.h"
#include "MVMemoryalloc.h"
#include "MVImage.h"
#include "MVVolVop.h"

/* except the two interface functions, 
* other functins are initate some matrix and tables
* 20070122 wuhaibin 
*/
  
/* from the xvid.c file, the parameter is delete. 20070122 wuhaibin*/
static int xvid_gbl_init()
{
	/* Initialize the function pointers */
	idct_int32_init();
	init_vlc_tables();

	/* this version delete some functions pointer,
	   and use function , because the version in a fixed plateform
	   20070122 wuhaibin*/

	 return(0);
}

/*from the decoder.c 20070122 wuhaibin*/
static int decoder_resize(DECODER * dec)
{
	/* free existing */
	image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
	image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
	image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
	image_destroy(&dec->tmp, dec->edged_width, dec->edged_height);
	image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height);

	image_destroy(&dec->gmc, dec->edged_width, dec->edged_height);

  	image_null(&dec->cur);
  	image_null(&dec->refn[0]);
  	image_null(&dec->refn[1]);
  	image_null(&dec->tmp);
  	image_null(&dec->qtmp);
  	image_null(&dec->gmc);


  	xvid_free(dec->last_mbs);
  	xvid_free(dec->mbs);
  	xvid_free(dec->qscale);
  	dec->last_mbs = NULL;
  	dec->mbs = NULL;
  	dec->qscale = NULL;

	/* realloc */
	dec->mb_width = (dec->width + 15) / 16;
	dec->mb_height = (dec->height + 15) / 16;

	dec->edged_width = 16 * dec->mb_width + 2 * EDGE_SIZE;
	dec->edged_height = 16 * dec->mb_height + 2 * EDGE_SIZE;

	if (   image_create(&dec->cur, dec->edged_width, dec->edged_height) 
	    || image_create(&dec->refn[0], dec->edged_width, dec->edged_height)
	    || image_create(&dec->refn[1], dec->edged_width, dec->edged_height) 	/* Support B-frame to reference last 2 frame */
	    || image_create(&dec->tmp, dec->edged_width, dec->edged_height)
	    || image_create(&dec->qtmp, dec->edged_width, dec->edged_height)
      	    || image_create(&dec->gmc, dec->edged_width, dec->edged_height) )
    		goto memory_error;

	dec->mbs =
		xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
					CACHE_LINE);
	if (dec->mbs == NULL)
	  goto memory_error;
	memset(dec->mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);

	/* For skip MB flag */
	dec->last_mbs =
		xvid_malloc(sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height,
					CACHE_LINE);
	if (dec->last_mbs == NULL)
	  goto memory_error;
	memset(dec->last_mbs, 0, sizeof(MACROBLOCK) * dec->mb_width * dec->mb_height);

	/* nothing happens if that fails */
	dec->qscale =
		xvid_malloc(sizeof(int) * dec->mb_width * dec->mb_height, CACHE_LINE);
	
	if (dec->qscale)
		memset(dec->qscale, 0, sizeof(int) * dec->mb_width * dec->mb_height);

	return 0;

memory_error:
        /* Most structures were deallocated / nullifieded, so it should be safe */
        /* decoder_destroy(dec) minus the write_timer */
  xvid_free(dec->mbs);
  image_destroy(&dec->cur, dec->edged_width, dec->edged_height);
  image_destroy(&dec->refn[0], dec->edged_width, dec->edged_height);
  image_destroy(&dec->refn[1], dec->edged_width, dec->edged_height);
  image_destroy(&dec->tmp, dec->edged_width, dec->edged_height);
  image_destroy(&dec->qtmp, dec->edged_width, dec->edged_height);

  xvid_free(dec);
  return XVID_ERR_MEMORY;
}

/* from the decoder.c wuhaibin 20070122*/
static int decoder_create(void ** ppHandle)
{
	  DECODER *dec;
	
	  dec = xvid_malloc(sizeof(DECODER), CACHE_LINE);
	  if (dec == NULL) {
	    return XVID_ERR_MEMORY;
	  }
	
	  memset(dec, 0, sizeof(DECODER));
	
	  dec->mpeg_quant_matrices = xvid_malloc(sizeof(uint16_t) * 64 * 8, CACHE_LINE);
	  if (dec->mpeg_quant_matrices == NULL) 
	  {
		    xvid_free(dec);
		    return XVID_ERR_MEMORY;
	  }
	
	  *ppHandle = dec;
	
	  dec->width = 0;//create->width;
	  dec->height = 0;//create->height;
	
	  image_null(&dec->cur);
	  image_null(&dec->refn[0]);
	  image_null(&dec->refn[1]);
	  image_null(&dec->tmp);
	  image_null(&dec->qtmp);
	
	  /* image based GMC */
	  image_null(&dec->gmc);
	
	  dec->mbs = NULL;
	  dec->last_mbs = NULL;
	  dec->qscale = NULL;
	
	  //init_postproc(&dec->postproc);
	  init_mpeg_matrix(dec->mpeg_quant_matrices);
	
	  /* For B-frame support (used to save reference frame's time */
	  dec->frames = 0;
	  dec->time = dec->time_base = dec->last_time_base = 0;
	  dec->low_delay = 0;
	  dec->packed_mode = 0;
	  dec->time_inc_resolution = 1; /* until VOL header says otherwise */
	  dec->ver_id = 1;
	
	  dec->bs_version = 0xffff; /* Initialize to very high value -> assume bugfree stream */
	
	  dec->fixed_dimensions = (dec->width > 0 && dec->height > 0);
	
	  if (dec->fixed_dimensions)
	    return decoder_resize(dec);
	  else
	    return 0;
}

/* the function is created by decoder_decode,
* it is decode procecssion control function
* wuhaibin 20070122
*/
static int mavrix_decode(DECODER* p_dec_handle,   void * p_in_buf, int in_len,
	              void * p_out_buf, int * p_out_len)
{
	  int           ret = 0;
  
	  Bitstream bs;
	  uint32_t rounding;
	  uint32_t quant = 2;
	  uint32_t fcode_forward;
	  uint32_t fcode_backward;
	  uint32_t intra_dc_threshold;
	  WARPPOINTS gmc_warp;
	  int coding_type, info_header;
	 
	  /* initate the bitstream struction*/
	  BitstreamInit(&bs, p_in_buf, in_len);

	  /* find the VOL or VOP header from the bitstream*/
	  info_header = mavrix_fine_start_code(&bs);
	 
	  while(info_header == VIDOBJLAY_START_CODE)//if find VOL header
	  {
		  //read VOL information
		  ret = mavrix_read_vol(&bs, p_dec_handle, &rounding,
								&quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, &gmc_warp);
		  if (!ret)  
			   return (BitstreamPos(&bs)+7)/8;
          //if now is start, it must apply memory 
		  if(!p_dec_handle->frames)
			   decoder_resize(p_dec_handle);
		  
		  //find the VOL or VOP header
		  info_header = mavrix_fine_start_code(&bs);
	  }
                     
	  if(info_header != VOP_START_CODE)
           return (BitstreamPos(&bs)+7)/8;

	  p_dec_handle->p_bmv.x = p_dec_handle->p_bmv.y = p_dec_handle->p_fmv.y = p_dec_handle->p_fmv.y = 0;  /* init pred vector to 0 */
  
	  //read the VOP information 
	  coding_type = mavtrix_read_vop(& bs, p_dec_handle, & rounding,
  													  &quant, &fcode_forward, &fcode_backward, &intra_dc_threshold, &gmc_warp);
	  if(coding_type != B_VOP)
	  {
		  switch(coding_type)
		  {
			   case I_VOP :   decoder_iframe(p_dec_handle, &bs, quant, intra_dc_threshold);
	                          break;

			   case P_VOP :   decoder_pframe(p_dec_handle, &bs, rounding, quant,
										   fcode_forward, intra_dc_threshold, NULL);
							  break;

			   case S_VOP :  decoder_pframe(p_dec_handle, &bs, rounding, quant,
						                    fcode_forward, intra_dc_threshold, &gmc_warp);
							  break;

			   case N_VOP:   image_copy(&p_dec_handle->cur, &p_dec_handle->refn[0], p_dec_handle->edged_width, p_dec_handle->height);
							 SWAP(MACROBLOCK *, p_dec_handle->mbs, p_dec_handle->last_mbs);

			}

		  if(p_dec_handle->frames)//if has some frame, it should output the previous frame
			image_output(&p_dec_handle->refn[0], p_dec_handle->width, p_dec_handle->height,
				       p_dec_handle->edged_width, p_out_buf, p_dec_handle->width, (uint32_t *)p_out_len, 0);


		  image_swap(&p_dec_handle->refn[0], &p_dec_handle->refn[1]);
          p_dec_handle->is_edged[1] = p_dec_handle->is_edged[0];
          image_swap(&p_dec_handle->cur, &p_dec_handle->refn[0]);
          p_dec_handle->is_edged[0] = 0;
          SWAP(MACROBLOCK *, p_dec_handle->mbs, p_dec_handle->last_mbs);
          p_dec_handle->last_coding_type = coding_type;
	  }
	  else
	  {
          if(p_dec_handle->frames < 2)
                return (BitstreamPos(&bs)+7)/8; 
          
		  //decode the b frame
		  decoder_bframe(p_dec_handle, &bs, quant, fcode_forward, fcode_backward);
		  
		  image_output(&p_dec_handle->cur, p_dec_handle->width, p_dec_handle->height,
				       p_dec_handle->edged_width, p_out_buf, p_dec_handle->width, (uint32_t *)p_out_len, 0);

	  }
    
    	p_dec_handle->frames++;

	  return (BitstreamPos(&bs)+7)/8; 

}

int  mavrix_mp4_dec_open(void ** pp_handle)
{
       int ret;

	ret = xvid_gbl_init();

	if(ret)
	   return ret;
	
    return decoder_create(pp_handle);
	
}


int mavrix_mp4_dec_decode(void* p_handle, void * p_in_buf, int in_len,
	                                      void * p_out_buf, int * p_out_len)
{
    uint32_t used_bytes;   
	*p_out_len = 0;
	used_bytes = mavrix_decode((DECODER*)p_handle,  p_in_buf,  in_len,
                                                    p_out_buf, p_out_len);

	return used_bytes;

}

⌨️ 快捷键说明

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