📄 mvdecodec.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 + -