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

📄 fame_syntax_mpeg4.c

📁 一个很好用的MPEG1/4的开源编码器
💻 C
📖 第 1 页 / 共 5 页
字号:
	         } else    {      /* Binary Only not (yet) supported */    }    /* Next Start Code */    mpeg4_next_start_code(buff);    /* User Data */      } }static void mpeg4_start_GOP(fame_syntax_t *syntax, int frame){#ifndef OPENDIVX_COMPATIBILITY  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  fame_bitbuffer_t *buff;  int fps_num, fps_den;  fps_num = syntax_mpeg4->fps_num;  fps_den = syntax_mpeg4->fps_den;    buff =     &syntax_mpeg4->buffer;  /* Group Of VOP default values */  syntax_mpeg4->closed_gov=1;  syntax_mpeg4->broken_link=0;  syntax_mpeg4->vop_time_increment=0;    bitbuffer_write(buff,MPEG4_GVOP_START_CODE, 32);  /* timecount hours                      */  bitbuffer_write(buff, (frame*fps_den/(3600*fps_num)) & 0x1f, 5);  /* timecount minutes                    */  bitbuffer_write(buff, ((frame*fps_den/(60*fps_num))%60) & 0x3f, 6);  /* marker                               */  bitbuffer_write(buff, 1, 1);  /* timecount seconds                    */  bitbuffer_write(buff, ((frame*fps_den/fps_num)%60) & 0x3f, 6);  bitbuffer_write(buff, syntax_mpeg4->closed_gov, 1);  bitbuffer_write(buff, syntax_mpeg4->broken_link, 1);  /* Next Start Code */  mpeg4_next_start_code(buff);#endif}static void mpeg4_start_picture(fame_syntax_t *syntax,				char frame_type,				int frame_number,				fame_box_t *box,				int rounding_control,				int search_range){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  fame_bitbuffer_t *buff;  int tmp;  unsigned int modulo_time_base;    buff =     &syntax_mpeg4->buffer;  switch(frame_type) {    case 'I':      syntax_mpeg4->vop_coding_type = MPEG4_I_FRAME;    break;    case 'P':      syntax_mpeg4->vop_coding_type = MPEG4_P_FRAME;    break;    default:      FAME_ERROR("Unsupported picture coding type %c", frame_type);      return;  }  /* Video Object Plane */  syntax_mpeg4->vop_rounding_type = rounding_control;   syntax_mpeg4->vop_reduced_resolution = 0;  syntax_mpeg4->vop_horizontal_mc_spatial_ref=box->x;  syntax_mpeg4->vop_vertical_mc_spatial_ref=box->y;  syntax_mpeg4->vop_width=box->w;  syntax_mpeg4->vop_height=box->h;  syntax_mpeg4->vop_constant_alpha=0;  syntax_mpeg4->vop_constant_alpha_value=128;  syntax_mpeg4->intra_dc_vlc_thr=0; /* use intra DC vlc for all DC coefficients */  tmp = (box->w+15)/16 * (box->h+15)/16;    syntax_mpeg4->macroblock_number_size = get_min_bit(tmp);  /* compute fcode */  syntax_mpeg4->vop_fcode_forward =   syntax_mpeg4->vop_fcode_backward =     fame_max(1, get_min_bit(search_range-1)-3);  if(syntax_mpeg4->vop_fcode_forward > 7) {    FAME_WARNING("vop_fcode_forward > 7, search range too big.\n");    syntax_mpeg4->vop_fcode_forward = 7;  }  if(syntax_mpeg4->vop_fcode_backward > 7) {    FAME_WARNING("vop_fcode_backward > 7, search range too big.\n");    syntax_mpeg4->vop_fcode_backward = 7;  }  bitbuffer_write(buff, MPEG4_VOP_START_CODE, 32);   /* picture start code                   */  bitbuffer_write(buff, syntax_mpeg4->vop_coding_type,2);    /* Modulo time base  */  modulo_time_base = syntax_mpeg4->vop_time_increment / syntax_mpeg4->vop_time_increment_resolution;  if (modulo_time_base) {    bitbuffer_write(buff, ((1 << modulo_time_base) - 1), modulo_time_base);    syntax_mpeg4->vop_time_increment %= syntax_mpeg4->vop_time_increment_resolution;  }  bitbuffer_write(buff,0,1); /* end of modulo time base */  bitbuffer_write(buff,1,1); /* Marker */  bitbuffer_write(buff,syntax_mpeg4->vop_time_increment%syntax_mpeg4->vop_time_increment_resolution, get_min_bit(syntax_mpeg4->vop_time_increment_resolution));    syntax_mpeg4->vop_time_increment += syntax_mpeg4->fixed_vop_time_increment;  bitbuffer_write(buff,1,1);  bitbuffer_write(buff,1,1); /* VOP coded */  if(syntax_mpeg4->newpred_enable)  {    /* not supported */  }  if( (syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_BinaryOnly ) &&      (syntax_mpeg4->vop_coding_type == MPEG4_P_FRAME))    bitbuffer_write(buff,syntax_mpeg4->vop_rounding_type,1);  if ( (syntax_mpeg4->reduced_resolution_vop_enable) &&       (syntax_mpeg4->video_object_layer_shape == MPEG4_Video_Object_Layer_Shape_Rectangular ) &&       ((syntax_mpeg4->vop_coding_type == MPEG4_I_FRAME) || (syntax_mpeg4->vop_coding_type == MPEG4_P_FRAME )))    bitbuffer_write(buff,syntax_mpeg4->vop_reduced_resolution,1);  if(syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_Rectangular )  {    /* TODO: test Sprite */    {      bitbuffer_write(buff,syntax_mpeg4->vop_width & 0x1fff,13);      bitbuffer_write(buff,1,1); /* Marker */      bitbuffer_write(buff,syntax_mpeg4->vop_height & 0x1fff,13);      bitbuffer_write(buff,1,1); /* Marker */      bitbuffer_write(buff,syntax_mpeg4->vop_horizontal_mc_spatial_ref & 0x1fff,13);      bitbuffer_write(buff,1,1); /* Marker */      bitbuffer_write(buff,syntax_mpeg4->vop_vertical_mc_spatial_ref & 0x1fff,13);      bitbuffer_write(buff,1,1); /* Marker */    }    bitbuffer_write(buff,syntax_mpeg4->change_conv_ratio_disable,1);    bitbuffer_write(buff,syntax_mpeg4->vop_constant_alpha,1);    if(syntax_mpeg4->vop_constant_alpha)      bitbuffer_write(buff,syntax_mpeg4->vop_constant_alpha_value,8)  }    if (syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_BinaryOnly )    if (!syntax_mpeg4->complexity_estimation_disable)    {      /* not supported */    }  if (syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_BinaryOnly )  {    bitbuffer_write(buff,syntax_mpeg4->intra_dc_vlc_thr,3);    if(syntax_mpeg4->interlaced)    {      /* not supported */    }  }  /* TODO: sprites */  {      }    syntax_mpeg4->flag_video_packet_header = 0;    /* restart motion predictor */  syntax_mpeg4->mv_pred = syntax_mpeg4->motion_pred;}static void inline mpeg4_reset_pred(fame_syntax_t *syntax){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  int i;  /* 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->cr_pred_h[0], syntax_mpeg4->pred_default);  FASTCOPY16(syntax_mpeg4->cr_pred_h[1], 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);  /* vertical predictors */  for(i = 0; i < syntax_mpeg4->mb_width; i++) {    FASTCOPY16(syntax_mpeg4->y_pred_v[0][i], syntax_mpeg4->pred_default);    FASTCOPY16(syntax_mpeg4->y_pred_v[1][i], syntax_mpeg4->pred_default);    FASTCOPY16(syntax_mpeg4->cr_pred_v[i], syntax_mpeg4->pred_default);    FASTCOPY16(syntax_mpeg4->cb_pred_v[i], syntax_mpeg4->pred_default);  }    /* motion predictors */  memset(syntax_mpeg4->motion_pred, 0,	 4*syntax_mpeg4->mb_height*	 syntax_mpeg4->mb_width*sizeof(fame_motion_vector_t));}static void mpeg4_start_slice(fame_syntax_t *syntax,			      int vpos,			      int length,			      unsigned char qscale){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  fame_bitbuffer_t *buff;    /* compute dc_scaler */  if(qscale == 0 || qscale > 31) {    FAME_WARNING("Invalid quantisation scale %d (1-31), setting to 8.\n",		 qscale);  }  buff =     &syntax_mpeg4->buffer;  /* Video Packet default value */  syntax_mpeg4->vop_quant = syntax_mpeg4->quant_scale = qscale;  syntax_mpeg4->vop_shape_coding_type = 0; /* always intra shape coding */  syntax_mpeg4->header_extension_code = 0;  syntax_mpeg4->macroblock_number = vpos * ((syntax_mpeg4->vop_width+15) / 16);  if (!syntax_mpeg4->flag_video_packet_header)  {    if (syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_BinaryOnly )    {      bitbuffer_write(buff,syntax_mpeg4->vop_quant & ((1 << syntax_mpeg4->quant_precision)-1),syntax_mpeg4->quant_precision);      if (syntax_mpeg4->video_object_layer_shape == MPEG4_Video_Object_Layer_Shape_Grayscale )      {        /* Not supported */      }      if (syntax_mpeg4->vop_coding_type != MPEG4_I_FRAME )        bitbuffer_write(buff,syntax_mpeg4->vop_fcode_forward & 7,3);      if (syntax_mpeg4->vop_coding_type == MPEG4_B_FRAME )        bitbuffer_write(buff,syntax_mpeg4->vop_fcode_backward & 7,3);      if(!syntax_mpeg4->scalability)      {        if ((syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_Rectangular) &&	     (syntax_mpeg4->vop_coding_type != MPEG4_I_FRAME ))	  bitbuffer_write(buff,syntax_mpeg4->vop_shape_coding_type,1);      }else      {        /* Not supported */      }    } else     {      /* Not supported */    }    syntax_mpeg4->flag_video_packet_header=1;	      } else  {    int resync_length = 0;    /* compute resync marker length */    if (syntax_mpeg4->vop_coding_type == MPEG4_I_FRAME ||	syntax_mpeg4->video_object_layer_shape == MPEG4_Video_Object_Layer_Shape_BinaryOnly)      resync_length = 16;    else {      if(syntax_mpeg4->vop_coding_type == MPEG4_P_FRAME)	resync_length = 15+syntax_mpeg4->vop_fcode_forward;      if(syntax_mpeg4->vop_coding_type == MPEG4_B_FRAME)	resync_length = fame_max(15+fame_max(syntax_mpeg4->vop_fcode_forward, syntax_mpeg4->vop_fcode_backward), 17);    }    /* resync marker */    bitbuffer_write(buff, 0, resync_length);    bitbuffer_write(buff, 1, 1);    if(syntax_mpeg4->video_object_layer_shape != MPEG4_Video_Object_Layer_Shape_Rectangular)      bitbuffer_write(buff,syntax_mpeg4->header_extension_code,1);    if(syntax_mpeg4->header_extension_code) /* TODO: test sprite_enable */    {      /* Not implemented */    }    bitbuffer_write(buff,syntax_mpeg4->macroblock_number,syntax_mpeg4->macroblock_number_size);    if(syntax_mpeg4->video_object_layer_shape!= MPEG4_Video_Object_Layer_Shape_BinaryOnly)      bitbuffer_write(buff,syntax_mpeg4->quant_scale & 0x1f, 5);    if(syntax_mpeg4->video_object_layer_shape == MPEG4_Video_Object_Layer_Shape_Rectangular)      bitbuffer_write(buff,syntax_mpeg4->header_extension_code,1);    if(syntax_mpeg4->header_extension_code)     {      /* Not Implemented */    }    if (syntax_mpeg4->newpred_enable)    {      /* Not implemented */    }      }  /* reset the DC predictors to their original values */  mpeg4_reset_pred(syntax);}static void mpeg4_end_slice(fame_syntax_t *syntax) {  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  mpeg4_next_start_code(&syntax_mpeg4->buffer); /* next start code */}static void mpeg4_end_sequence(fame_syntax_t *syntax){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  /* end sequence code                    */  bitbuffer_write(&syntax_mpeg4->buffer, MPEG4_SEQUENCE_END_CODE, 32);}static void mpeg4_predict_vector(fame_syntax_t *syntax,				 int mb_x,				 int mb_y,				 int k,				 fame_motion_vector_t *mv){#define MEDIAN(a,b,c) ((b)<(a))?(((c)>(a))?(a):(((c)<(b))?(b):(c))):(((c)<(a))?(a):(((c)>(b))?(b):(c)))  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  fame_motion_vector_t *predictor1, *predictor2, *predictor3, *mv_pred;  int pitch;  int border1, border2, border3;  int mb_addr, slice_addr;  /* HACK: we use count as a flag for vector validity */  /* TODO: thus, checking borders is probably not needed anymore */  /*       though checking video packets boundaries is. */  pitch = syntax_mpeg4->mb_width;  slice_addr = syntax_mpeg4->macroblock_number;  mb_addr = mb_y*syntax_mpeg4->mb_width+mb_x;  border1 = (mb_x == 0) || (mb_addr <= slice_addr);  border2 = (mb_addr - pitch < slice_addr);  border3 = (mb_x == pitch - 1) || (mb_addr - pitch + 1 < slice_addr);  pitch = syntax_mpeg4->mb_width*4;  mv_pred = syntax_mpeg4->mv_pred;  switch(k) {    case 0:      predictor1 = mv_pred - 3;      predictor2 = mv_pred - pitch + 2;      predictor3 = mv_pred - pitch + 6;    break;    /* WARNING: count must be valid in 'mv' past this point */    case 1:      predictor1 = &mv[0]; border1 = 0;      predictor2 = mv_pred - pitch + 3;      predictor3 = mv_pred - pitch + 6;    break;    case 2:      predictor1 = mv_pred - 1;      predictor2 = &mv[0]; border2 = 0;      predictor3 = &mv[1]; border3 = 0;    break;    case 3:      predictor1 = &mv[2]; border1 = 0;      predictor2 = &mv[0]; border2 = 0;      predictor3 = &mv[1]; border3 = 0;    break;    default: /* invalid k */      predictor1 = predictor2 = predictor3 = NULL;    break;  }  if(border1 || !predictor1->count) {    if(border2 || !predictor2->count) {      if(border3 || !predictor3->count) {	/* no pred */	mv_pred[k].dx = 0;	mv_pred[k].dy = 0;      } else {	/* only p3 */	mv_pred[k].dx = predictor3->dx;	mv_pred[k].dy = predictor3->dy;      }    } else {      if(border3 || !predictor3->count) {	/* p2 only */	mv_pred[k].dx = predictor2->dx;	mv_pred[k].dy = predictor2->dx;      } else {	/* p2, p3 */	mv_pred[k].dx = MEDIAN(0,predictor2->dx,predictor3->dx);	mv_pred[k].dy = MEDIAN(0,predictor2->dy,predictor3->dy);      }    }  } else if(border3 || !predictor3->count) {    if(border2 || !predictor2->count) {      /* p1 only */      mv_pred[k].dx = predictor1->dx;      mv_pred[k].dy = predictor1->dy;    } else {      /* p1, p2 */      mv_pred[k].dx = MEDIAN(predictor1->dx,predictor2->dx,0);      mv_pred[k].dy = MEDIAN(predictor1->dy,predictor2->dy,0);    }  } else {    if(border2 || !predictor2->count) {      /* p1, p3 */      mv_pred[k].dx = MEDIAN(predictor1->dx,0,predictor3->dx);      mv_pred[k].dy = MEDIAN(predictor1->dx,0,predictor3->dx);    } else {      /* p1, p2, p3 */      mv_pred[k].dx = MEDIAN(predictor1->dx, predictor2->dx, predictor3->dx);      mv_pred[k].dy = MEDIAN(predictor1->dy, predictor2->dy, predictor3->dy);    }  }  if(k == 0) { /* HACK: fill in the 16x16 vector with the predictor */

⌨️ 快捷键说明

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