macroblocks.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "mpeg3video.h"
  2. #include "slice.h"
  3. #include "vlc.h"
  4. #include <stdio.h>
  5. int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice)
  6. {
  7. int code, val = 0;
  8. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  9.    while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24)
  10. {
  11. /* Is not macroblock_stuffing */
  12.      if(code != 15)
  13. {     
  14. /* Is macroblock_escape */
  15.        if(code == 8)
  16. {
  17.          val += 33;
  18.        }
  19.        else 
  20. {
  21. /*         fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment coden"); */
  22.          slice->fault = 1;
  23.          return 1;
  24.        }
  25.      }
  26.      mpeg3slice_flushbits(slice_buffer, 11);
  27.    }
  28.    if(code >= 1024)
  29. {
  30.      mpeg3slice_flushbit(slice_buffer);
  31.      return val + 1;
  32.    }
  33.    if(code >= 128)
  34. {
  35.      code >>= 6;
  36.      mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len);
  37.      return val + mpeg3_MBAtab1[code].val;
  38.    }
  39.    code -= 24;
  40.    mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len);
  41.    return val + mpeg3_MBAtab2[code].val;
  42. }
  43. /* macroblock_type for pictures with spatial scalability */
  44. static __inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice)
  45. {
  46. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  47.    unsigned int code = mpeg3slice_showbits(slice_buffer, 4);
  48. if(!code)
  49. {
  50. /*     fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type coden"); */
  51.      slice->fault = 1;
  52.      return 0;
  53.    }
  54.    mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len);
  55.    return mpeg3_spIMBtab[code].val;
  56. }
  57. static __inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice)
  58. {
  59. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  60.    int code = mpeg3slice_showbits(slice_buffer, 7);
  61. if(code < 2)
  62. {
  63. /*     fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type coden"); */
  64.      slice->fault = 1;
  65.      return 0;
  66.    }
  67.    if(code >= 16)
  68. {
  69.      code >>= 3;
  70.      mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len);
  71.      return mpeg3_spPMBtab0[code].val;
  72.    }
  73.    mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len);
  74.    return mpeg3_spPMBtab1[code].val;
  75. }
  76. static __inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice)
  77. {
  78.    mpeg3_VLCtab_t *p;
  79. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  80.    int code = mpeg3slice_showbits9(slice_buffer);
  81.    if(code >= 64) 
  82. p = &mpeg3_spBMBtab0[(code >> 5) - 2];
  83.    else 
  84. if(code >= 16) 
  85. p = &mpeg3_spBMBtab1[(code >> 2) - 4];
  86.    else 
  87. if(code >= 8)  
  88. p = &mpeg3_spBMBtab2[code - 8];
  89.    else 
  90. {
  91. /*     fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type coden"); */
  92.      slice->fault = 1;
  93.      return 0;
  94.    }
  95.    mpeg3slice_flushbits(slice_buffer, p->len);
  96.    return p->val;
  97. }
  98. static __inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice)
  99. {
  100. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  101. if(mpeg3slice_getbit(slice_buffer))
  102. {
  103.      return 1;
  104.    }
  105.    if(!mpeg3slice_getbit(slice_buffer))
  106. {
  107. /*     fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type coden"); */
  108.      slice->fault = 1;
  109.    }
  110.    return 17;
  111. }
  112. static __inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice)
  113. {
  114.    int code;
  115. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  116.    if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
  117. {
  118.      code >>= 3;
  119.      mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len);
  120.      return mpeg3_PMBtab0[code].val;
  121.    }
  122.    if(code == 0)
  123. {
  124. /*     fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type coden"); */
  125.      slice->fault = 1;
  126.      return 0;
  127.    }
  128.    mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len);
  129.    return mpeg3_PMBtab1[code].val;
  130. }
  131. static __inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice)
  132. {
  133.    int code;
  134. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  135.    if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
  136. {
  137.      code >>= 2;
  138.      mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len);
  139.      return mpeg3_BMBtab0[code].val;
  140.    }
  141.    if(code == 0)
  142. {
  143. /*     fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type coden"); */
  144.      slice->fault = 1;
  145.      return 0;
  146.    }
  147.    mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len);
  148. return mpeg3_BMBtab1[code].val;
  149. }
  150. static __inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice)
  151. {
  152.    if(!mpeg3slice_getbit(slice->slice_buffer))
  153. {
  154. /*     fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type coden"); */
  155.      slice->fault=1;
  156.    }
  157.    return 1;
  158. }
  159. static __inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice)
  160. {
  161. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  162.     int code = mpeg3slice_showbits(slice_buffer, 3);
  163.     if(code == 0)
  164.     {
  165. /*      fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type coden"); */
  166.         slice->fault = 1;
  167.         return 0;
  168.     }
  169.     mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len);
  170.     return mpeg3_SNRMBtab[code].val;
  171. }
  172. int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video)
  173. {
  174. if(video->scalable_mode == SC_SNR)
  175. {
  176. return mpeg3video_get_snrmb_type(slice);
  177. }
  178. else
  179. {
  180.      switch(video->pict_type)
  181. {
  182.      case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice);
  183.      case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice);
  184.      case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice);
  185.      case D_TYPE: return mpeg3video_get_dmb_type(slice);
  186.      default: 
  187. /*fprintf(stderr, "mpeg3video_getmbtype: unknown coding typen"); */
  188. break;
  189. /* MPEG-1 only, not implemented */
  190.    }
  191.    }
  192.    return 0;
  193. }
  194. int mpeg3video_macroblock_modes(mpeg3_slice_t *slice, 
  195. mpeg3video_t *video, 
  196. int *pmb_type, 
  197. int *pstwtype, 
  198. int *pstwclass, 
  199. int *pmotion_type, 
  200. int *pmv_count, 
  201. int *pmv_format, 
  202. int *pdmv, 
  203. int *pmvscale,
  204. int *pdct_type)
  205. {
  206. int mb_type;
  207. int stwtype, stwcode, stwclass;
  208. int motion_type = 0, mv_count, mv_format, dmv, mvscale;
  209. int dct_type;
  210. mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
  211. static unsigned char stwc_table[3][4]
  212.      = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} };
  213. static unsigned char stwclass_table[9]
  214.      = {0, 1, 2, 1, 1, 2, 3, 3, 4};
  215. /* get macroblock_type */
  216.    mb_type = mpeg3video_get_mb_type(slice, video);
  217.    if(slice->fault) return 1;
  218. /* get spatial_temporal_weight_code */
  219.    if(mb_type & MB_WEIGHT)
  220.    {
  221.      if(video->stwc_table_index == 0)
  222.        stwtype = 4;
  223.      else
  224.      {
  225.        stwcode = mpeg3slice_getbits2(slice_buffer);
  226.        stwtype = stwc_table[video->stwc_table_index - 1][stwcode];
  227.      }
  228.    }
  229.    else
  230.      stwtype = (mb_type & MB_CLASS4) ? 8 : 0;
  231. /* derive spatial_temporal_weight_class (Table 7-18) */
  232.    stwclass = stwclass_table[stwtype];
  233. /* get frame/field motion type */
  234.    if(mb_type & (MB_FORWARD | MB_BACKWARD))
  235. {
  236.      if(video->pict_struct == FRAME_PICTURE)
  237. /* frame_motion_type */
  238.        motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer);
  239.      }
  240.      else 
  241. /* field_motion_type */
  242.        motion_type = mpeg3slice_getbits2(slice_buffer);
  243.      }
  244.    }
  245.    else 
  246. if((mb_type & MB_INTRA) && video->conceal_mv)
  247.    {
  248. /* concealment motion vectors */
  249.      motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD;
  250.    }
  251. /* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */
  252.    if(video->pict_struct == FRAME_PICTURE)
  253.    {
  254.      mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1;
  255.      mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD;
  256.    }
  257.    else
  258.    {
  259.      mv_count = (motion_type == MC_16X8) ? 2 : 1;
  260.      mv_format = MV_FIELD;
  261.    }
  262.    dmv = (motion_type == MC_DMV); /* dual prime */
  263. /* field mv predictions in frame pictures have to be scaled */
  264.    mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE));
  265. /* get dct_type (frame DCT / field DCT) */
  266.    dct_type = (video->pict_struct == FRAME_PICTURE) && 
  267.               (!video->frame_pred_dct) && 
  268.               (mb_type & (MB_PATTERN | MB_INTRA)) ? 
  269.               mpeg3slice_getbit(slice_buffer) : 0;
  270. /* return values */
  271. *pmb_type = mb_type;
  272. *pstwtype = stwtype;
  273. *pstwclass = stwclass;
  274. *pmotion_type = motion_type;
  275. *pmv_count = mv_count;
  276. *pmv_format = mv_format;
  277. *pdmv = dmv;
  278. *pmvscale = mvscale;
  279. *pdct_type = dct_type;
  280. return 0;
  281. }