macroblocks.c
资源名称:NETVIDEO.rar [点击查看]
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:9k
源码类别:
流媒体/Mpeg4/MP4
开发平台:
Visual C++
- #include "mpeg3video.h"
- #include "slice.h"
- #include "vlc.h"
- #include <stdio.h>
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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 coden"); */
- 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 typen"); */
- 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;
- }