From 15318cad33835e4e2dc620d033e43cd930676cdd Mon Sep 17 00:00:00 2001 From: kergoth Date: Fri, 25 Jan 2002 22:14:26 +0000 Subject: Initial revision --- (limited to 'core/multimedia/opieplayer/libmpeg3/video/macroblocks.c') diff --git a/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c new file mode 100644 index 0000000..11e17c1 --- a/dev/null +++ b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c @@ -0,0 +1,338 @@ +#include "../libmpeg3.h" +#include "../mpeg3protos.h" +#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) +{ +// ### This looks wrong. +// slice_buffer is used without being initialised and slice is not used +// mpeg3_slice_buffer_t *slice_buffer = slice_buffer; +// I think this would make more sense and might be what is intended + 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; +} -- cgit v0.9.0.2