⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fame_syntax_mpeg4.c

📁 一个很好用的MPEG1/4的开源编码器
💻 C
📖 第 1 页 / 共 5 页
字号:
    mv[0].dx = mv_pred[0].dx;    mv[0].dy = mv_pred[0].dy;  }}static void inline mpeg4_arithmetic_bit(fame_syntax_cae_t *cae, unsigned char bit){  *cae->sequence++ = bit;  /* avoid start code emulation */  if (bit == 0) {    cae->nzeros--;    if (cae->nzeros == 0)    {      *cae->sequence++ = 1;      cae->nonzero = 1;      cae->nzeros = CAE_MAX_MIDDLE;    }  } else {    cae->nonzero = 1;    cae->nzeros = CAE_MAX_MIDDLE;  }}static void inline mpeg4_arithmetic_follow(fame_syntax_cae_t *cae, unsigned char bit){  if (!cae->first_bit)    mpeg4_arithmetic_bit(cae, bit);  else    cae->first_bit = 0;  while(cae->bits_to_follow > 0) {    mpeg4_arithmetic_bit(cae, !bit);    cae->bits_to_follow--;  }}static void inline mpeg4_arithmetic_renormalize(fame_syntax_cae_t *cae) {  while (cae->range < CAE_1_4) {    if (cae->lower >= CAE_1_2) {       mpeg4_arithmetic_follow(cae, 1);      cae->lower -= CAE_1_2;    } else {      if (cae->lower + cae->range <= CAE_1_2)	mpeg4_arithmetic_follow(cae, 0);      else {	cae->bits_to_follow++;	cae->lower -= CAE_1_4;      }    }    cae->lower += cae->lower;    cae->range += cae->range;  }}static void inline mpeg4_arithmetic_enter(fame_syntax_cae_t *cae){  cae->lower = 0;  cae->range = CAE_1_2 - 1;  cae->bits_to_follow = 0;  cae->first_bit = 1;  cae->nzeros = CAE_MAX_HEADING;  cae->nonzero = 0;  cae->sequence = cae->buffer;}static void inline mpeg4_arithmetic_leave(fame_syntax_cae_t *cae){  int a = (cae->lower) >> 29;  int b = (cae->range + cae->lower) >> 29;  int nbits, bits, i;  if (b == 0) b = 8;  if (b - a >= 4 || (b - a == 3 && (a & 1))) {    nbits = 2;    bits = (a >> 1) + 1;  } else {    nbits = 3;    bits = a + 1;  }  for (i = 1; i <= nbits; i++)    mpeg4_arithmetic_follow(cae, (bits >> (nbits - i)) & 1);  if (cae->nzeros < CAE_MAX_MIDDLE - CAE_MAX_TRAILING ||      cae->nonzero == 0) {    mpeg4_arithmetic_follow(cae, 1);  }  *cae->sequence++ = 0xff;}static void inline mpeg4_arithmetic_code(fame_syntax_cae_t *cae, int cLPS){  signed long rLPS;  rLPS = (cae->range >> 16) * cLPS;  if (rLPS > 0) {    cae->lower += cae->range - rLPS;    cae->range = rLPS;  }  else    cae->range += rLPS;  mpeg4_arithmetic_renormalize(cae);}static void inline mpeg4_write_intra_bab(fame_syntax_t *syntax,					 int mb_x, int mb_y,					 unsigned char *bab,					 unsigned char *prev_bab,					 fame_bab_t bab_type){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  int i, j;  int line;  unsigned char *ptr_h, *ptr_v;  int pitch = syntax_mpeg4->mb_width + 2;  int addr;  int prev_addr[4];  /* initialize arithmetic encoders */  mpeg4_arithmetic_enter(syntax_mpeg4->cae_h);  mpeg4_arithmetic_enter(syntax_mpeg4->cae_v);  /* compute current bab address, add 1 for borders */  addr = mb_y * pitch + pitch + mb_x + 1;  /* compute addresses of previous babs */  prev_addr[0] = addr - 1;  prev_addr[1] = addr - pitch + 1;  prev_addr[2] = addr - pitch;  prev_addr[3] = addr - pitch - 1;  /* compute context number for vlc table indexation */  /* bab = 0 if not_coded */  /* bab = 1 if all_coded */  /* bab = 2 if cae_coded */  /* context = 27*bab[i-1,j-1]+9*bab[i,j-1]+3*bab[i+1,j-1]+bab[i-1,j] */  /* TODO: fix context computation in case of multiple slice */  /* TODO: wrong for P frames */  i = 0;  for(j = 0; j < 4; j++) {    switch(prev_bab[prev_addr[j]]) {      case bab_not_coded:      break;      case bab_all_coded:	i += bab_type_intra_context_weight[j];      break;      case bab_border_16x16:      case bab_border_8x8:      case bab_border_4x4:	i += bab_type_intra_context_weight[j];	i += bab_type_intra_context_weight[j];      break;    }  }  /* save current bab_type for further context computing */  prev_bab[addr] = bab_type;  /* write vlc */  switch(bab_type)  {    case bab_not_coded:      bitbuffer_write(&syntax_mpeg4->buffer, 1, bab_type_intra_vl[i][0]);    return;    case bab_all_coded:      bitbuffer_write(&syntax_mpeg4->buffer, 1, bab_type_intra_vl[i][1]);    return;    case bab_border_16x16:    case bab_border_8x8:    case bab_border_4x4:      bitbuffer_write(&syntax_mpeg4->buffer, 1, bab_type_intra_vl[i][2]);    break;  }  /* no MVDs */  /* horizontal raster order context */#define CIH0  ((*(ptr_h         ))<<0)#define CIH1  ((*(ptr_h       -1))<<1)#define CIH2  ((*(ptr_h       -2))<<2)#define CIH3  ((*(ptr_h-1*line+2))<<3)#define CIH4  ((*(ptr_h-1*line+1))<<4)#define CIH5  ((*(ptr_h-1*line  ))<<5)#define CIH6  ((*(ptr_h-1*line-1))<<6)#define CIH7  ((*(ptr_h-1*line-2))<<7)#define CIH8  ((*(ptr_h-2*line+1))<<8)#define CIH9  ((*(ptr_h-2*line  ))<<9)#define CIH10 ((*(ptr_h-2*line-1))<<10)#define CIH (CIH0|CIH1|CIH2|CIH3|CIH4|CIH5|CIH6|CIH7|CIH8|CIH9|CIH10)  /* vertical raster order context */#define CIV0  ((*(ptr_v         ))<<0)#define CIV1  ((*(ptr_v  -1*line))<<1)#define CIV2  ((*(ptr_v  -2*line))<<2)#define CIV3  ((*(ptr_v-1+2*line))<<3)#define CIV4  ((*(ptr_v-1+1*line))<<4)#define CIV5  ((*(ptr_v-1       ))<<5)#define CIV6  ((*(ptr_v-1-1*line))<<6)#define CIV7  ((*(ptr_v-1-2*line))<<7)#define CIV8  ((*(ptr_v-2+1*line))<<8)#define CIV9  ((*(ptr_v-2       ))<<9)#define CIV10 ((*(ptr_v-2-1*line))<<10)#define CIV (CIV0|CIV1|CIV2|CIV3|CIV4|CIV5|CIV6|CIV7|CIV8|CIV9|CIV10)  switch(bab_type)  {    case bab_border_16x16:      if(!syntax_mpeg4->change_conv_ratio_disable)	bitbuffer_write(&syntax_mpeg4->buffer, 0, 1); /* CR = 1 */      line = 20;      ptr_h = ptr_v = bab+2*line+2; /* skip border */      for(i = 0; i < 16; i++) {	for(j = 0; j < 16; j++) {	  mpeg4_arithmetic_code(syntax_mpeg4->cae_h, 				syntax_mpeg4->symbol[CIH]);	  mpeg4_arithmetic_code(syntax_mpeg4->cae_v,				syntax_mpeg4->symbol[CIV]);	  ptr_h++;	  ptr_v+=line;	}	ptr_h += 4;	ptr_v += -(line<<4) + 1;      }    break;    case bab_border_8x8:      bitbuffer_write(&syntax_mpeg4->buffer, 2, 2); /* CR = 2 */      line = 12;      ptr_h = ptr_v = bab+2*line+2; /* skip border */      for(i = 0; i < 8; i++) {	for(j = 0; j < 8; j++) {	  mpeg4_arithmetic_code(syntax_mpeg4->cae_h, 				syntax_mpeg4->symbol[CIH]);	  mpeg4_arithmetic_code(syntax_mpeg4->cae_v,				syntax_mpeg4->symbol[CIV]);	  ptr_h++;	  ptr_v+=line;	}	ptr_h += 4;	ptr_v += -(line<<3) + 1;      }    break;    case bab_border_4x4:      bitbuffer_write(&syntax_mpeg4->buffer, 3, 2); /* CR = 4 */      line = 8;      ptr_h = ptr_v = bab+2*line+2; /* skip border */      for(i = 0; i < 4; i++) {	for(j = 0; j < 4; j++) {	  mpeg4_arithmetic_code(syntax_mpeg4->cae_h, 				syntax_mpeg4->symbol[CIH]);	  mpeg4_arithmetic_code(syntax_mpeg4->cae_v,				syntax_mpeg4->symbol[CIV]);	  ptr_h++;	  ptr_v+=line;	}	ptr_h += 4;	ptr_v += -(line<<2) + 1;      }    break;    default:    break;  }  mpeg4_arithmetic_leave(syntax_mpeg4->cae_h);  mpeg4_arithmetic_leave(syntax_mpeg4->cae_v);  /* keep the smallest code */  syntax_mpeg4->cae_h->sequence = syntax_mpeg4->cae_h->buffer;  syntax_mpeg4->cae_v->sequence = syntax_mpeg4->cae_v->buffer;  for(i = 0; syntax_mpeg4->cae_h->sequence[i] != 0xff; i++);  for(j = 0; syntax_mpeg4->cae_v->sequence[j] != 0xff; j++);  if(i <= j) {    /* horizontal */    bitbuffer_write(&syntax_mpeg4->buffer, 1, 1); /* don't transpose */    for(j = 0; j < i; j++) {      bitbuffer_write(&syntax_mpeg4->buffer,		      syntax_mpeg4->cae_h->sequence[j], 1);    }  }  else {    /* vertical */    bitbuffer_write(&syntax_mpeg4->buffer, 0, 1); /* transpose */    for(i = 0; i < j; i++) {       bitbuffer_write(&syntax_mpeg4->buffer,		      syntax_mpeg4->cae_v->sequence[i], 1);    }  }}static void mpeg4_block_intra(fame_syntax_t *syntax,				     short *block,				     fame_vlc_t const *table,				     short v,    				     unsigned char *zigzag,				     unsigned char coded){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  short i;  unsigned long last;  fame_vlc_t const *vlc;  fame_bitbuffer_t * const buffer = &syntax_mpeg4->buffer;  unsigned char * data = buffer->data;  unsigned long shift = buffer->shift;  /* encode DC coefficient */  fast_bitbuffer_write(data, shift, table[v+255].code, table[v+255].length);  /* encode AC coefficients */  if(coded) {    i = 1;    last = 1;    /* i < 64 checking not needed as all-zero block is not coded */    while((v = block[zigzag[i]]) == 0) i++;    do {      /* count zeroes */      vlc = syntax_mpeg4->intra_table +	    (mpeg4_table_clip[v] << 6) +	    i - last;      last = ++i;      while(i < 64 && (v = block[zigzag[i]]) == 0) i++;      /* write code */      if(i != 64) {	fast_bitbuffer_write(data, shift, vlc->code, vlc->length);      } else {	vlc += 64*511;	fast_bitbuffer_write(data, shift, vlc->code, vlc->length);	break;      }    } while(1);  }  buffer->data = data;  buffer->shift = shift;}static int mpeg4_write_intra_mb(fame_syntax_t *syntax,				 int mb_x,				 int mb_y,				 short *blocks[6],				 unsigned char *bab,				 unsigned char *bab_map,				 fame_bab_t bab_type,				 int dquant,				 unsigned char pattern){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  int coded[6];  int i, j;  int cbp, bc;  short *a, *b, *c;  short *p[6];  short ys, cs, qs;  short *d[6];  short o[6];  short ac_sad;  unsigned char *zigzag[6];  int retval;  p[0] = syntax_mpeg4->pred[0];  p[1] = syntax_mpeg4->pred[1];  p[2] = syntax_mpeg4->pred[2];  p[3] = syntax_mpeg4->pred[3];  p[4] = syntax_mpeg4->pred[4];  p[5] = syntax_mpeg4->pred[5];  d[0] = syntax_mpeg4->diff[0];  d[1] = syntax_mpeg4->diff[1];  d[2] = syntax_mpeg4->diff[2];  d[3] = syntax_mpeg4->diff[3];  d[4] = syntax_mpeg4->diff[4];  d[5] = syntax_mpeg4->diff[5];  o[0] = o[1] = o[3] = o[4] = o[4] = o[5] = TOP_PREDICTED;  FASTCOPY16(p[0], syntax_mpeg4->pred_default);  FASTCOPY16(p[2], syntax_mpeg4->pred_default);  FASTCOPY16(p[1], syntax_mpeg4->pred_default);  FASTCOPY16(p[3], syntax_mpeg4->pred_default);  FASTCOPY16(p[4], syntax_mpeg4->pred_default);  FASTCOPY16(p[5], syntax_mpeg4->pred_default);  if(syntax_mpeg4->video_object_layer_shape !=     MPEG4_Video_Object_Layer_Shape_Rectangular)    mpeg4_write_intra_bab(syntax, mb_x, mb_y, bab, bab_map, bab_type);  if(bab_type != bab_not_coded) { /* not transparent */    if(syntax_mpeg4->vop_coding_type != MPEG4_I_FRAME)      bitbuffer_write(&syntax_mpeg4->buffer, 0, 1);     syntax_mpeg4->quant_scale += dquant;    qs = syntax_mpeg4->quant_scale;    ys = syntax_mpeg4->y_dc_scaler[qs];    cs = syntax_mpeg4->c_dc_scaler[qs];        /* prediction */    if(!mb_x) { /* start of line, reset horizontal predictors */      FASTCOPY16(syntax_mpeg4->y_pred_h[0], syntax_mpeg4->pred_default);      FASTCOPY16(syntax_mpeg4->y_pred_h[1], syntax_mpeg4->pred_default);      FASTCOPY16(syntax_mpeg4->y_pred_h[2], syntax_mpeg4->pred_default);      FASTCOPY16(syntax_mpeg4->cb_pred_h[0], syntax_mpeg4->pred_default);      FASTCOPY16(syntax_mpeg4->cb_pred_h[1], syntax_mpeg4->pred_default);      FASTCOPY16(syntax_mpeg4->cr_pred_h[0], syntax_mpeg4->pred_default);      FASTCOPY16(syntax_mpeg4->cr_pred_h[1], syntax_mpeg4->pred_default);    }    ac_sad = 0;    /* Y (0,0) block */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -