www.pudn.com > NETVIDEO.rar > macroblocks.c


#include "mpeg3video.h" 
#include "slice.h" 
#include "vlc.h" 
 
#include  
 
int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice) 
{ 
	int code, val = 0; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
  	while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24) 
	{ 
/* Is not macroblock_stuffing */ 
    	if(code != 15) 
		{      
/* Is macroblock_escape */ 
      		if(code == 8) 
			{ 
        		val += 33; 
      		} 
      		else  
			{ 
/*        		fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment code\n"); */ 
        		slice->fault = 1; 
        		return 1; 
      		} 
    	} 
 
    	mpeg3slice_flushbits(slice_buffer, 11); 
  	} 
 
  	if(code >= 1024) 
	{ 
    	mpeg3slice_flushbit(slice_buffer); 
    	return val + 1; 
  	} 
 
  	if(code >= 128) 
	{ 
    	code >>= 6; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len); 
    	return val + mpeg3_MBAtab1[code].val; 
  	} 
 
  	code -= 24; 
  	mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len); 
 
  	return val + mpeg3_MBAtab2[code].val; 
} 
 
/* macroblock_type for pictures with spatial scalability */ 
 
static __inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice) 
{ 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
  	unsigned int code = mpeg3slice_showbits(slice_buffer, 4); 
	if(!code) 
	{ 
/*    	fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type code\n"); */ 
    	slice->fault = 1; 
    	return 0; 
  	} 
 
  	mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len); 
  	return mpeg3_spIMBtab[code].val; 
} 
 
static __inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice) 
{ 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
  	int code = mpeg3slice_showbits(slice_buffer, 7); 
	if(code < 2) 
	{ 
/*    	fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type code\n"); */ 
    	slice->fault = 1; 
    	return 0; 
  	} 
 
  	if(code >= 16) 
	{ 
    	code >>= 3; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len); 
 
    	return mpeg3_spPMBtab0[code].val; 
  	} 
 
  	mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len); 
  	return mpeg3_spPMBtab1[code].val; 
} 
 
static __inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice) 
{ 
  	mpeg3_VLCtab_t *p; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
  	int code = mpeg3slice_showbits9(slice_buffer); 
 
  	if(code >= 64)  
		p = &mpeg3_spBMBtab0[(code >> 5) - 2]; 
  	else  
	if(code >= 16)  
		p = &mpeg3_spBMBtab1[(code >> 2) - 4]; 
  	else  
	if(code >= 8)   
		p = &mpeg3_spBMBtab2[code - 8]; 
  	else  
	{ 
/*    	fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type code\n"); */ 
    	slice->fault = 1; 
    	return 0; 
  	} 
 
  	mpeg3slice_flushbits(slice_buffer, p->len); 
  	return p->val; 
} 
 
static __inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice) 
{ 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
	if(mpeg3slice_getbit(slice_buffer)) 
	{ 
    	return 1; 
  	} 
 
  	if(!mpeg3slice_getbit(slice_buffer)) 
	{ 
/*    	fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type code\n"); */ 
    	slice->fault = 1; 
  	} 
 
  	return 17; 
} 
 
static __inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice) 
{ 
  	int code; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
  	if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) 
	{ 
    	code >>= 3; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len); 
    	return mpeg3_PMBtab0[code].val; 
  	} 
 
  	if(code == 0) 
	{ 
/*    	fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type code\n"); */ 
    	slice->fault = 1; 
    	return 0; 
  	} 
 
  	mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len); 
  	return mpeg3_PMBtab1[code].val; 
} 
 
static __inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice) 
{ 
  	int code; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
 
  	if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8) 
	{ 
    	code >>= 2; 
    	mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len); 
    	return mpeg3_BMBtab0[code].val; 
  	} 
 
  	if(code == 0) 
	{ 
/*    	fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type code\n"); */ 
    	slice->fault = 1; 
    	return 0; 
  	} 
 
  	mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len); 
 
	return mpeg3_BMBtab1[code].val; 
} 
 
static __inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice) 
{ 
  	if(!mpeg3slice_getbit(slice->slice_buffer)) 
	{ 
/*    	fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type code\n"); */ 
    	slice->fault=1; 
  	} 
 
  	return 1; 
} 
 
 
static __inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice) 
{ 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
    int code = mpeg3slice_showbits(slice_buffer, 3); 
 
    if(code == 0) 
    { 
/*      fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type code\n"); */ 
        slice->fault = 1; 
        return 0; 
    } 
 
    mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len); 
    return mpeg3_SNRMBtab[code].val; 
} 
 
int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video) 
{ 
	if(video->scalable_mode == SC_SNR) 
	{ 
		return mpeg3video_get_snrmb_type(slice); 
	} 
	else 
	{ 
    	switch(video->pict_type) 
		{ 
    		case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice); 
    		case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice); 
    		case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice); 
    		case D_TYPE: return mpeg3video_get_dmb_type(slice); 
    		default:  
				/*fprintf(stderr, "mpeg3video_getmbtype: unknown coding type\n"); */ 
				break; 
/* MPEG-1 only, not implemented */ 
	  	} 
  	} 
 
  	return 0; 
} 
 
int mpeg3video_macroblock_modes(mpeg3_slice_t *slice,  
		mpeg3video_t *video,  
		int *pmb_type,  
		int *pstwtype,  
		int *pstwclass,  
		int *pmotion_type,  
		int *pmv_count,  
		int *pmv_format,  
		int *pdmv,  
		int *pmvscale, 
		int *pdct_type) 
{ 
	int mb_type; 
	int stwtype, stwcode, stwclass; 
	int motion_type = 0, mv_count, mv_format, dmv, mvscale; 
	int dct_type; 
	mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer; 
	static unsigned char stwc_table[3][4] 
    	= { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} }; 
	static unsigned char stwclass_table[9] 
    	= {0, 1, 2, 1, 1, 2, 3, 3, 4}; 
 
/* get macroblock_type */ 
  	mb_type = mpeg3video_get_mb_type(slice, video); 
 
  	if(slice->fault) return 1; 
 
/* get spatial_temporal_weight_code */ 
  	if(mb_type & MB_WEIGHT) 
  	{ 
    	if(video->stwc_table_index == 0) 
      		stwtype = 4; 
    	else 
    	{ 
      		stwcode = mpeg3slice_getbits2(slice_buffer); 
      		stwtype = stwc_table[video->stwc_table_index - 1][stwcode]; 
    	} 
  	} 
  	else 
    	stwtype = (mb_type & MB_CLASS4) ? 8 : 0; 
 
/* derive spatial_temporal_weight_class (Table 7-18) */ 
  	stwclass = stwclass_table[stwtype]; 
 
/* get frame/field motion type */ 
  	if(mb_type & (MB_FORWARD | MB_BACKWARD)) 
	{ 
    	if(video->pict_struct == FRAME_PICTURE) 
		{  
/* frame_motion_type */ 
      		motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer); 
    	} 
    	else  
		{  
/* field_motion_type */ 
      		motion_type = mpeg3slice_getbits2(slice_buffer); 
    	} 
  	} 
  	else  
	if((mb_type & MB_INTRA) && video->conceal_mv) 
  	{ 
/* concealment motion vectors */ 
    	motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD; 
  	} 
 
/* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */ 
  	if(video->pict_struct == FRAME_PICTURE) 
  	{ 
    	mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1; 
    	mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD; 
  	} 
  	else 
  	{ 
    	mv_count = (motion_type == MC_16X8) ? 2 : 1; 
    	mv_format = MV_FIELD; 
  	} 
 
  	dmv = (motion_type == MC_DMV); /* dual prime */ 
 
/* field mv predictions in frame pictures have to be scaled */ 
  	mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE)); 
 
/* get dct_type (frame DCT / field DCT) */ 
  	dct_type = (video->pict_struct == FRAME_PICTURE) &&  
             	(!video->frame_pred_dct) &&  
             	(mb_type & (MB_PATTERN | MB_INTRA)) ?  
             	mpeg3slice_getbit(slice_buffer) : 0; 
 
/* return values */ 
	*pmb_type = mb_type; 
	*pstwtype = stwtype; 
	*pstwclass = stwclass; 
	*pmotion_type = motion_type; 
	*pmv_count = mv_count; 
	*pmv_format = mv_format; 
	*pdmv = dmv; 
	*pmvscale = mvscale; 
	*pdct_type = dct_type; 
	return 0; 
}