Merge remote-tracking branch 'x264/master'
authorPhillip Blucas <pblucas@gmail.com>
Thu, 20 Oct 2011 00:30:00 +0000 (19:30 -0500)
committerPhillip Blucas <pblucas@gmail.com>
Thu, 20 Oct 2011 00:30:00 +0000 (19:30 -0500)
Conflicts:
common/common.c
common/common.h
common/quant.c
common/quant.h
encoder/macroblock.c
encoder/ratecontrol.c
encoder/set.c

26 files changed:
1  2 
Makefile
common/bitstream.h
common/common.c
common/common.h
common/dct.c
common/dct.h
common/frame.c
common/frame.h
common/mc.c
common/mc.h
common/predict.c
common/predict.h
common/quant.c
common/quant.h
common/set.h
encoder/analyse.c
encoder/encoder.c
encoder/macroblock.c
encoder/macroblock.h
encoder/me.c
encoder/ratecontrol.c
encoder/rdo.c
encoder/set.c
encoder/slicetype.c
x264.c
x264.h

diff --cc Makefile
index e8c02fd,560ba90..b861cd4
mode 100755,100644..100755
+++ b/Makefile
index 74592a2,8920b89..869943a
mode 100755,100644..100755
@@@ -56,30 -56,17 +56,31 @@@ typedef struct bs_
  typedef struct
  {
      int     last;
 -    dctcoef level[16];
 -    uint8_t run[16];
 +    dctcoef level[64];
 +    uint8_t run[64];
  } x264_run_level_t;
  
- extern const vlc_t x264_coeff0_token[5];
- extern const vlc_t x264_coeff_token[5][16][4];
+ extern const vlc_t x264_coeff0_token[6];
+ extern const vlc_t x264_coeff_token[6][16][4];
  extern const vlc_t x264_total_zeros[15][16];
- extern const vlc_t x264_total_zeros_dc[3][4];
+ extern const vlc_t x264_total_zeros_2x2_dc[3][4];
+ extern const vlc_t x264_total_zeros_2x4_dc[7][8];
  extern const vlc_t x264_run_before[7][16];
  
 +extern const vlc_t x262_mb_addr_inc[34];
 +extern const vlc_t x262_cbp[64];
 +extern const vlc_t x262_i_frame_mb_type[2];
 +
 +extern const vlc_t x262_i_mb_type[3][2];
 +extern const vlc_t x262_p_mb_type[2][2][2];
 +extern const vlc_t x262_b_mb_type[3][2][2];
 +extern const vlc_large_t x262_dc_luma_code[12];
 +extern const vlc_large_t x262_dc_chroma_code[12];
 +extern const vlc_t x262_dmvector[3];
 +extern const vlc_large_t x262_motion_code[33];
 +extern const vlc_large_t dct_vlcs[2][41][32];
 +extern const uint8_t dct_vlc_largest_run[41];
 +
  typedef struct
  {
      uint8_t *(*nal_escape) ( uint8_t *dst, uint8_t *src, uint8_t *end );
diff --cc common/common.c
@@@ -431,79 -426,72 +431,123 @@@ void x264_param_apply_fastfirstpass( x2
      }
  }
  
 -static int profile_string_to_int( const char *str )
++static int profile_string_to_int( const char *str, int b_mpeg2 )
+ {
+     if( !strcasecmp( str, "baseline" ) )
 -        return PROFILE_BASELINE;
++        return b_mpeg2 ? -1 : PROFILE_BASELINE;
++    if( !strcasecmp( str, "simple" ) )
++        return b_mpeg2 ? MPEG2_PROFILE_SIMPLE : -1;
+     if( !strcasecmp( str, "main" ) )
 -        return PROFILE_MAIN;
++        return b_mpeg2 ? MPEG2_PROFILE_MAIN : PROFILE_MAIN;
+     if( !strcasecmp( str, "high" ) )
 -        return PROFILE_HIGH;
++        return b_mpeg2 ? MPEG2_PROFILE_HIGH : PROFILE_HIGH;
+     if( !strcasecmp( str, "high10" ) )
 -        return PROFILE_HIGH10;
++        return b_mpeg2 ? -1 : PROFILE_HIGH10;
+     if( !strcasecmp( str, "high422" ) )
 -        return PROFILE_HIGH422;
++        return b_mpeg2 ? -1 : PROFILE_HIGH422;
+     if( !strcasecmp( str, "high444" ) )
 -        return PROFILE_HIGH444_PREDICTIVE;
++        return b_mpeg2 ? -1 : PROFILE_HIGH444_PREDICTIVE;
+     return -1;
+ }
  int x264_param_apply_profile( x264_param_t *param, const char *profile )
  {
 +    /* Force MPEG-2 settings */
 +    if( param->b_mpeg2 )
 +    {
 +        param->analyse.b_transform_8x8 = 0;
 +        param->analyse.intra = 0;
 +        param->analyse.inter = 0;
 +        param->analyse.i_weighted_pred = 0;
 +        param->analyse.b_weighted_bipred = 0;
 +        param->analyse.b_dct_decimate = 0;
 +        param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE;
 +        param->analyse.b_mixed_references = 0;
 +        param->analyse.i_trellis = 0;
 +        param->b_constrained_intra = 0;
 +        param->b_aud = 0;
 +        param->i_bframe_pyramid = X264_B_PYRAMID_NONE;
 +        param->b_deblocking_filter = 0;
 +        param->i_nal_hrd = X264_NAL_HRD_NONE;
 +        param->b_cabac = 0;
 +        param->i_slice_max_size = 0;
 +        param->i_slice_max_mbs = 0;
 +        param->i_slice_count = 0;
 +        param->b_sliced_threads = 0;
 +        param->i_frame_reference = 1;
 +    }
 +
      if( !profile )
          return 0;
  
-     if( !param->b_mpeg2 )
 -    int p = profile_string_to_int( profile );
++    int p = profile_string_to_int( profile, param->b_mpeg2 );
+     if( p < 0 )
      {
- #if BIT_DEPTH > 8
-         if( !strcasecmp( profile, "baseline" ) || !strcasecmp( profile, "main" ) ||
-             !strcasecmp( profile, "high" ) )
-         {
-             x264_log( NULL, X264_LOG_ERROR, "%s profile doesn't support a bit depth of %d.\n", profile, BIT_DEPTH );
-             return -1;
-         }
- #endif
-         if( !strcasecmp( profile, "baseline" ) )
+         x264_log( NULL, X264_LOG_ERROR, "invalid profile: %s\n", profile );
+         return -1;
+     }
++
++    if( param->b_mpeg2 )
++    {
++        if( p == MPEG2_PROFILE_SIMPLE )
 +        {
-             param->analyse.b_transform_8x8 = 0;
-             param->b_cabac = 0;
-             param->i_cqm_preset = X264_CQM_FLAT;
-             param->psz_cqm_file = NULL;
 +            param->i_bframe = 0;
-             param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
++            param->i_intra_dc_precision = X264_INTRA_DC_8_BIT;
 +            if( param->b_interlaced )
 +            {
-                 x264_log( NULL, X264_LOG_ERROR, "baseline profile doesn't support interlacing\n" );
-                 return -1;
-             }
-             if( param->b_fake_interlaced )
-             {
-                 x264_log( NULL, X264_LOG_ERROR, "baseline profile doesn't support fake interlacing\n" );
++                x264_log( NULL, X264_LOG_ERROR, "simple profile doesn't support interlacing\n" );
 +                return -1;
 +            }
 +        }
++        else if( p == MPEG2_PROFILE_MAIN )
++            param->i_intra_dc_precision = x264_clip3( param->i_intra_dc_precision,
++                                                      X264_INTRA_DC_8_BIT, X264_INTRA_DC_10_BIT );
++        return 0;
++    }
++    
+     if( p < PROFILE_HIGH444_PREDICTIVE && ((param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant <= 0) ||
+         (param->rc.i_rc_method == X264_RC_CRF && (int)(param->rc.f_rf_constant + QP_BD_OFFSET) <= 0)) )
+     {
+         x264_log( NULL, X264_LOG_ERROR, "%s profile doesn't support lossless\n", profile );
+         return -1;
+     }
+     if( p < PROFILE_HIGH444_PREDICTIVE && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I444 )
+     {
+         x264_log( NULL, X264_LOG_ERROR, "%s profile doesn't support 4:4:4\n", profile );
+         return -1;
+     }
+     if( p < PROFILE_HIGH422 && (param->i_csp & X264_CSP_MASK) >= X264_CSP_I422 )
+     {
+         x264_log( NULL, X264_LOG_ERROR, "%s profile doesn't support 4:2:2\n", profile );
+         return -1;
+     }
+     if( p < PROFILE_HIGH10 && BIT_DEPTH > 8 )
+     {
+         x264_log( NULL, X264_LOG_ERROR, "%s profile doesn't support a bit depth of %d\n", profile, BIT_DEPTH );
+         return -1;
+     }
  
-         else if( !strcasecmp( profile, "main" ) )
+     if( p == PROFILE_BASELINE )
+     {
+         param->analyse.b_transform_8x8 = 0;
+         param->b_cabac = 0;
+         param->i_cqm_preset = X264_CQM_FLAT;
+         param->psz_cqm_file = NULL;
+         param->i_bframe = 0;
+         param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
+         if( param->b_interlaced )
          {
 -            x264_log( NULL, X264_LOG_ERROR, "baseline profile doesn't support interlacing\n" );
 -            return -1;
 +            param->analyse.b_transform_8x8 = 0;
 +            param->i_cqm_preset = X264_CQM_FLAT;
 +            param->psz_cqm_file = NULL;
          }
 -        if( param->b_fake_interlaced )
 +        else if( !strcasecmp( profile, "high" ) || !strcasecmp( profile, "high10" ) )
          {
 -            x264_log( NULL, X264_LOG_ERROR, "baseline profile doesn't support fake interlacing\n" );
 +            /* Default H.264 */
 +        }
 +        else
 +        {
 +            x264_log( NULL, X264_LOG_ERROR, "invalid profile: %s\n", profile );
              return -1;
          }
      }
diff --cc common/common.h
@@@ -56,15 -59,12 +59,15 @@@ do {
  #define X264_BFRAME_MAX 16
  #define X264_REF_MAX 16
  #define X264_THREAD_MAX 128
- #define X264_PCM_COST ((384<<CHROMA444)*BIT_DEPTH+16)
+ #define X264_PCM_COST (FRAME_SIZE(256*BIT_DEPTH)+16)
  #define X264_LOOKAHEAD_MAX 250
  #define QP_BD_OFFSET (6*(BIT_DEPTH-8))
 -#define QP_MAX_SPEC (51+QP_BD_OFFSET)
 -#define QP_MAX (QP_MAX_SPEC+18)
 +#define QP_MAX_SPEC_H264 (51+QP_BD_OFFSET)
 +#define QP_MAX_SPEC_MPEG2 31
 +#define QP_MAX_SPEC (MPEG2 ? QP_MAX_SPEC_MPEG2 : QP_MAX_SPEC_H264)
 +#define QP_MAX (QP_MAX_SPEC_H264+18)
  #define QP_MAX_MAX (51+2*6+18)
 +#define LAMBDA_MAX (91 << (BIT_DEPTH-8))
  #define PIXEL_MAX ((1 << BIT_DEPTH)-1)
  // arbitrary, but low because SATD scores are 1/4 normal
  #define X264_LOOKAHEAD_QP (12+QP_BD_OFFSET)
  #   define PARAM_INTERLACED 0
  #endif
  
- #define CHROMA444 (h->sps->i_chroma_format_idc == 3)
 +/* MPEG-2 Support */
 +#if HAVE_MPEG2
 +#   define MPEG2 h->param.b_mpeg2
 +#else
 +#   define MPEG2 0
 +#endif
 +
+ #define CHROMA444 (CHROMA_FORMAT == CHROMA_444)
  
  /* Unions for type-punning.
   * Mn: load or store n bits, aligned, native-endian
@@@ -949,13 -900,13 +958,15 @@@ struct x264_
  
      /* CPU functions dependents */
      x264_predict_t      predict_16x16[4+3];
-     x264_predict_t      predict_8x8c[4+3];
      x264_predict8x8_t   predict_8x8[9+3];
      x264_predict_t      predict_4x4[9+3];
+     x264_predict_t      predict_chroma[4+3];
+     x264_predict_t      predict_8x8c[4+3];
+     x264_predict_t      predict_8x16c[4+3];
      x264_predict_8x8_filter_t predict_8x8_filter;
  
 +    x262_predict_t      predict_mpeg2_8x8;
 +
      x264_pixel_function_t pixf;
      x264_mc_functions_t   mc;
      x264_dct_function_t   dctf;
diff --cc common/dct.c
index 0369bcc,cf8a235..b450f4e
mode 100755,100644..100755
diff --cc common/dct.h
Simple merge
diff --cc common/frame.c
Simple merge
diff --cc common/frame.h
Simple merge
diff --cc common/mc.c
Simple merge
diff --cc common/mc.h
Simple merge
@@@ -149,8 -150,9 +150,8 @@@ void x264_predict_16x16_p_c( pixel *sr
      }
  }
  
 -
  /****************************************************************************
-  * 8x8 prediction for intra chroma block
+  * 8x8 prediction for intra chroma block (4:2:0)
   ****************************************************************************/
  
  static void x264_predict_8x8c_dc_128_c( pixel *src )
Simple merge
diff --cc common/quant.c
@@@ -372,9 -385,9 +440,10 @@@ static int x264_coeff_level_run##num( d
  }
  
  level_run(4)
+ level_run(8)
  level_run(15)
  level_run(16)
 +level_run(64)
  
  void x264_quant_init( x264_t *h, int cpu, x264_quant_function_t *pf )
  {
diff --cc common/quant.h
@@@ -46,11 -50,11 +50,15 @@@ typedef struc
      int (*decimate_score16)( dctcoef *dct );
      int (*decimate_score64)( dctcoef *dct );
      int (*coeff_last[14])( dctcoef *dct );
+     int (*coeff_last4)( dctcoef *dct );
+     int (*coeff_last8)( dctcoef *dct );
      int (*coeff_level_run[13])( dctcoef *dct, x264_run_level_t *runlevel );
+     int (*coeff_level_run4)( dctcoef *dct, x264_run_level_t *runlevel );
+     int (*coeff_level_run8)( dctcoef *dct, x264_run_level_t *runlevel );
 +
 +    int (*quant_8x8_mpeg2)( dctcoef dct[64], uint16_t mf[64], uint16_t bias[64] );
 +    void (*dequant_mpeg2_intra)( dctcoef dct[64], int dequant_mf[64] );
 +    void (*dequant_mpeg2_inter)( dctcoef dct[64], int dequant_mf[64] );
  } x264_quant_function_t;
  
  void x264_quant_init( x264_t *h, int cpu, x264_quant_function_t *pf );
diff --cc common/set.h
index 6a956e1,038dbd4..0becb0b
mode 100755,100644..100755
@@@ -774,18 -690,9 +778,18 @@@ static inline void x264_mb_init_fenc_ca
  
  static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *a )
  {
-     if( a->i_satd_i8x8chroma < COST_MAX )
+     if( a->i_satd_chroma < COST_MAX )
          return;
  
-         a->i_satd_i8x8chroma = h->pixf.mbcmp[PIXEL_8x8]( h->mb.pic.p_fdec[1], FDEC_STRIDE, h->mb.pic.p_fenc[1], FENC_STRIDE ) +
-                                h->pixf.mbcmp[PIXEL_8x8]( h->mb.pic.p_fdec[2], FDEC_STRIDE, h->mb.pic.p_fenc[2], FENC_STRIDE );
 +    if( MPEG2 )
 +    {
 +        h->predict_mpeg2_8x8( h->mb.pic.p_fdec[1], 0 );
 +        h->predict_mpeg2_8x8( h->mb.pic.p_fdec[2], 0 );
++        a->i_satd_chroma = h->pixf.mbcmp[PIXEL_8x8]( h->mb.pic.p_fdec[1], FDEC_STRIDE, h->mb.pic.p_fenc[1], FENC_STRIDE ) +
++                           h->pixf.mbcmp[PIXEL_8x8]( h->mb.pic.p_fdec[2], FDEC_STRIDE, h->mb.pic.p_fenc[2], FENC_STRIDE );
 +        return;
 +    }
 +
      if( CHROMA444 )
      {
          if( !h->mb.b_chroma_me )
@@@ -429,50 -431,20 +439,54 @@@ static int x264_validate_parameters( x2
          return -1;
      }
  
- #if HAVE_INTERLACED
-     h->param.b_interlaced = !!PARAM_INTERLACED;
- #else
-     if( h->param.b_interlaced )
+     if( i_csp < X264_CSP_I422 && PARAM_INTERLACED && h->param.i_height % 4 )
      {
-         x264_log( h, X264_LOG_ERROR, "not compiled with interlaced support\n" );
+         x264_log( h, X264_LOG_ERROR, "height not divisible by 4 (%dx%d)\n",
+                   h->param.i_width, h->param.i_height );
+         return -1;
+     }
+     if( (i_csp < X264_CSP_I422 || PARAM_INTERLACED) && h->param.i_height % 2 )
+     {
+         x264_log( h, X264_LOG_ERROR, "height not divisible by 2 (%dx%d)\n",
+                   h->param.i_width, h->param.i_height );
          return -1;
      }
- #endif
  
 +   if( MPEG2 )
 +    {
 +        if( h->param.b_interlaced )
 +        {
 +            x264_log( h, X264_LOG_WARNING, "MPEG-2 + interlaced is not yet implemented\n" );
 +            h->param.b_interlaced = 0;
 +        }
 +        if( h->param.rc.i_qp_constant == 0 )
 +        {
 +            x264_log( h, X264_LOG_ERROR, "MPEG-2 + lossless is not allowed\n" );
 +            return -1;
 +        }
 +        if( h->param.vui.i_colorprim > 7 )
 +        {
 +            x264_log( h, X264_LOG_ERROR, "Chosen color primary not allowed in MPEG-2\n" );
 +            return -1;
 +        }
 +        if( h->param.vui.i_transfer > 8 )
 +        {
 +            x264_log( h, X264_LOG_ERROR, "Chosen transfer characteristic not allowed in MPEG-2\n" );
 +            return -1;
 +        }
 +        if( h->param.vui.i_colmatrix > 7 )
 +        {
 +            x264_log( h, X264_LOG_ERROR, "Chosen colormatrix not allowed in MPEG-2\n" );
 +            return -1;
 +        }
 +        if( h->param.i_intra_dc_precision < 0 || h->param.i_intra_dc_precision > 3 )
 +        {
 +            x264_log( h, X264_LOG_ERROR, "invalid intra DC precision specified\n" );
 +            return -1;
 +        }
 +    }
 +
      if( (h->param.crop_rect.i_left + h->param.crop_rect.i_right ) >= h->param.i_width ||
          (h->param.crop_rect.i_top  + h->param.crop_rect.i_bottom) >= h->param.i_height )
      {
@@@ -1211,9 -1144,9 +1265,10 @@@ x264_t *x264_encoder_open( x264_param_
      /* init CPU functions */
      x264_predict_16x16_init( h->param.cpu, h->predict_16x16 );
      x264_predict_8x8c_init( h->param.cpu, h->predict_8x8c );
+     x264_predict_8x16c_init( h->param.cpu, h->predict_8x16c );
      x264_predict_8x8_init( h->param.cpu, h->predict_8x8, &h->predict_8x8_filter );
      x264_predict_4x4_init( h->param.cpu, h->predict_4x4 );
 +    x262_predict_8x8_init( h->param.cpu, &h->predict_mpeg2_8x8 );
      if( h->param.b_cabac )
          x264_cabac_init( h );
      else
                            h->sps->i_profile_idc == PROFILE_MAIN ? "Main" :
                            h->sps->i_profile_idc == PROFILE_HIGH ? "High" :
                            h->sps->i_profile_idc == PROFILE_HIGH10 ? (h->sps->b_constraint_set3 == 1 ? "High 10 Intra" : "High 10") :
+                           h->sps->i_profile_idc == PROFILE_HIGH422 ? (h->sps->b_constraint_set3 == 1 ? "High 4:2:2 Intra" : "High 4:2:2") :
                            h->sps->b_constraint_set3 == 1 ? "High 4:4:4 Intra" : "High 4:4:4 Predictive";
 -    char level[4];
 -    snprintf( level, sizeof(level), "%d.%d", h->sps->i_level_idc/10, h->sps->i_level_idc%10 );
 -    if( h->sps->i_level_idc == 9 || ( h->sps->i_level_idc == 11 && h->sps->b_constraint_set3 &&
 -        (h->sps->i_profile_idc >= PROFILE_BASELINE && h->sps->i_profile_idc <= PROFILE_EXTENDED) ) )
 -        strcpy( level, "1b" );
 +    char level[10];
 +    if( MPEG2 )
 +        snprintf( level, sizeof(level), "%s", h->sps->i_level_idc == MPEG2_LEVEL_LOW ? "Low" :
 +                                              h->sps->i_level_idc == MPEG2_LEVEL_MAIN ? "Main" :
 +                                              h->sps->i_level_idc == MPEG2_LEVEL_HIGH_1440 ? "High-1440" :
 +                                              h->sps->i_level_idc == MPEG2_LEVEL_HIGH ? "High" :
 +                                              "HighP" );
 +    else
 +    {
 +        snprintf( level, sizeof(level), "%d.%d", h->sps->i_level_idc/10, h->sps->i_level_idc%10 );
 +        if( h->sps->i_level_idc == 9 || ( h->sps->i_level_idc == 11 && h->sps->b_constraint_set3 &&
 +            (h->sps->i_profile_idc >= PROFILE_BASELINE && h->sps->i_profile_idc <= PROFILE_EXTENDED) ) )
 +            strcpy( level, "1b" );
 +    }
  
      if( h->sps->i_profile_idc < PROFILE_HIGH10 )
      {
@@@ -1007,19 -989,20 +1135,19 @@@ static ALWAYS_INLINE void x264_macroblo
      {
          if( IS_INTRA( h->mb.i_type ) )
          {
-             const int i_mode = h->mb.i_chroma_pred_mode;
+             int i_mode = h->mb.i_chroma_pred_mode;
              if( h->mb.b_lossless )
-                 x264_predict_lossless_8x8_chroma( h, i_mode );
+                 x264_predict_lossless_chroma( h, i_mode );
              else
              {
-                 h->predict_8x8c[i_mode]( h->mb.pic.p_fdec[1] );
-                 h->predict_8x8c[i_mode]( h->mb.pic.p_fdec[2] );
+                 h->predict_chroma[i_mode]( h->mb.pic.p_fdec[1] );
+                 h->predict_chroma[i_mode]( h->mb.pic.p_fdec[2] );
              }
          }
 -
          /* encode the 8x8 blocks */
-         x264_mb_encode_8x8_chroma( h, !IS_INTRA( h->mb.i_type ), h->mb.i_chroma_qp );
+         x264_mb_encode_chroma( h, !IS_INTRA( h->mb.i_type ), h->mb.i_chroma_qp );
      }
 -    else
 +    else if( !MPEG2 )
          h->mb.i_cbp_chroma = 0;
  
      /* store cbp */
@@@ -1238,69 -1181,14 +1376,72 @@@ static ALWAYS_INLINE int x264_macrobloc
      return 1;
  }
  
-         h->mc.load_deinterleave_8x8x2_fdec( h->mb.pic.p_fdec[1], h->mb.pic.p_fref[0][0][4], h->mb.pic.i_stride[1] );
 +int x264_macroblock_probe_skip_mpeg2( x264_t *h, int b_bidir )
 +{
 +    ALIGNED_ARRAY_16( dctcoef, dct8x8,[6],[64] );
 +    ALIGNED_ARRAY_16( dctcoef, dctscan8,[64] );
 +
 +    int i_qp = h->mb.i_qp;
 +
 +    if( !b_bidir )
 +    {
 +        /* Motion compensation */
 +        h->mc.mc_luma( h->mb.pic.p_fdec[0],    FDEC_STRIDE,
 +                       h->mb.pic.p_fref[0][0], h->mb.pic.i_stride[0],
 +                       0, 0, 16, 16, &h->sh.weight[0][0] );
 +    }
 +
 +    for( int idx = 0, i_decimate_mb = 0; idx < 4; idx++ )
 +    {
 +        int x = idx&1;
 +        int y = idx>>1;
 +        pixel *p_src = &h->mb.pic.p_fenc[0][8*x + 8*y*FENC_STRIDE];
 +        pixel *p_dst = &h->mb.pic.p_fdec[0][8*x + 8*y*FDEC_STRIDE];;
 +
 +        h->dctf.sub8x8_dct8( dct8x8[idx], p_src, p_dst );
 +        if( !h->quantf.quant_8x8_mpeg2( dct8x8[idx], h->quant8_mf[CQM_8PY][i_qp], h->quant8_bias[CQM_8PY][i_qp] ) )
 +            continue;
 +        h->zigzagf.scan_8x8( dctscan8, dct8x8[idx] );
 +        i_decimate_mb += h->quantf.decimate_score64( dctscan8 );
 +        if( i_decimate_mb >= 6 )
 +            return 0;
 +    }
 +
 +    /* encode chroma */
 +    if( !b_bidir )
 +    {
++        h->mc.load_deinterleave_chroma_fdec( h->mb.pic.p_fdec[1], h->mb.pic.p_fref[0][0][4],
++                                             h->mb.pic.i_stride[1], 16 >> h->mb.chroma_v_shift );
 +    }
 +
 +    for( int idx = 4, i_decimate_mb = 0; idx < 6; idx++ )
 +    {
 +        pixel *p_src = h->mb.pic.p_fenc[idx-3];
 +        pixel *p_dst = h->mb.pic.p_fdec[idx-3];
 +
 +        h->dctf.sub8x8_dct8( dct8x8[idx], p_src, p_dst );
 +        if( !h->quantf.quant_8x8_mpeg2( dct8x8[idx], h->quant8_mf[CQM_8PY][i_qp], h->quant8_bias[CQM_8PY][i_qp] ) )
 +            continue;
 +        h->zigzagf.scan_8x8( dctscan8, dct8x8[idx] );
 +        i_decimate_mb += h->quantf.decimate_score64( dctscan8 );
 +        if( i_decimate_mb >= 7 )
 +            return 0;
 +    }
 +
 +    h->mb.b_skip_mc = 1;
 +    return 1;
 +}
 +
  int x264_macroblock_probe_skip( x264_t *h, int b_bidir )
  {
-     if( CHROMA444 )
-         return x264_macroblock_probe_skip_internal( h, b_bidir, 3, 0 );
-     else if( MPEG2 )
 -    if( CHROMA_FORMAT == CHROMA_444 )
++    if( MPEG2 )
 +        return x264_macroblock_probe_skip_mpeg2( h, b_bidir );
++    else if( CHROMA_FORMAT == CHROMA_444 )
+         return x264_macroblock_probe_skip_internal( h, b_bidir, 3, CHROMA_444 );
+     else if( CHROMA_FORMAT == CHROMA_422 )
+         return x264_macroblock_probe_skip_internal( h, b_bidir, 1, CHROMA_422 );
      else
-         return x264_macroblock_probe_skip_internal( h, b_bidir, 1, 1 );
+         return x264_macroblock_probe_skip_internal( h, b_bidir, 1, CHROMA_420 );
  }
  
  /****************************************************************************
index e1498ba,d8ca95d..4a7183c
mode 100755,100644..100755
@@@ -41,14 -35,12 +41,13 @@@ extern const uint16_t x262_lambda_tab_l
  void x264_rdo_init( void );
  
  int x264_macroblock_probe_skip( x264_t *h, int b_bidir );
 +int x264_macroblock_probe_skip_mpeg2( x264_t *h, int b_bidir );
  
  #define x264_macroblock_probe_pskip( h )\
 -    x264_macroblock_probe_skip( h, 0 )
 +    ( MPEG2 ? x264_macroblock_probe_skip_mpeg2( h, 0 ) : x264_macroblock_probe_skip( h, 0 ) )
  #define x264_macroblock_probe_bskip( h )\
 -    x264_macroblock_probe_skip( h, 1 )
 +    ( MPEG2 ? x264_macroblock_probe_skip_mpeg2( h, 1 ) : x264_macroblock_probe_skip( h, 1 ) )
  
- void x264_predict_lossless_8x8_chroma( x264_t *h, int i_mode );
  void x264_predict_lossless_4x4( x264_t *h, pixel *p_dst, int p, int idx, int i_mode );
  void x264_predict_lossless_8x8( x264_t *h, pixel *p_dst, int p, int idx, int i_mode, pixel edge[36] );
  void x264_predict_lossless_16x16( x264_t *h, int p, int i_mode );
diff --cc encoder/me.c
Simple merge
@@@ -1293,8 -1281,8 +1295,8 @@@ void x264_ratecontrol_start( x264_t *h
          if( h->param.b_bluray_compat )
              mincr = 4;
  
-         /* High 10 / High 4:4:4 Predictive doesn't require minCR, so just set the maximum to a large value. */
-         if( MPEG2 || h->sps->i_profile_idc >= PROFILE_HIGH10 )
 -        /* Profiles above High don't require minCR, so just set the maximum to a large value. */
 -        if( h->sps->i_profile_idc > PROFILE_HIGH )
++        /* MPEG-2 and H.254 profiles above High don't require minCR, so just set the maximum to a large value. */
++        if( MPEG2 || h->sps->i_profile_idc > PROFILE_HIGH )
              rc->frame_size_maximum = 1e9;
          else
          {
diff --cc encoder/rdo.c
index 5c0e607,80b6cf0..6655b18
mode 100755,100644..100755
diff --cc encoder/set.c
@@@ -104,21 -104,14 +104,24 @@@ void x264_sps_init( x264_sps_t *sps, in
      sps->i_id = i_id;
      sps->i_mb_width = ( param->i_width + 15 ) / 16;
      sps->i_mb_height= ( param->i_height + 15 ) / 16;
-     sps->i_chroma_format_idc = csp >= X264_CSP_I444 ? 3 : 1;
+     sps->i_chroma_format_idc = csp >= X264_CSP_I444 ? CHROMA_444 :
+                                csp >= X264_CSP_I422 ? CHROMA_422 : CHROMA_420;
  
      sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0;
 -    if( sps->b_qpprime_y_zero_transform_bypass || sps->i_chroma_format_idc == CHROMA_444 )
 +
 +    if( param->b_mpeg2 )
 +    {
-         if( param->i_intra_dc_precision > 2 )
++        if( param->i_intra_dc_precision > X264_INTRA_DC_10_BIT )
 +            sps->i_profile_idc = MPEG2_PROFILE_HIGH;
 +        else if( param->i_bframe > 0 || param->b_interlaced )
 +            sps->i_profile_idc = MPEG2_PROFILE_MAIN;
 +        else
 +            sps->i_profile_idc = MPEG2_PROFILE_SIMPLE;
 +    }
-     else if( sps->b_qpprime_y_zero_transform_bypass || sps->i_chroma_format_idc == 3 )
++    else if( sps->b_qpprime_y_zero_transform_bypass || sps->i_chroma_format_idc == CHROMA_444 )
          sps->i_profile_idc  = PROFILE_HIGH444_PREDICTIVE;
+     else if( sps->i_chroma_format_idc == CHROMA_422 )
+         sps->i_profile_idc  = PROFILE_HIGH422;
      else if( BIT_DEPTH > 8 )
          sps->i_profile_idc  = PROFILE_HIGH10;
      else if( param->analyse.b_transform_8x8 || param->i_cqm_preset != X264_CQM_FLAT )
Simple merge
diff --cc x264.c
index e65b296,55b0f4f..720fe13
mode 100755,100644..100755
--- 1/x264.c
--- 2/x264.c
+++ b/x264.c
diff --cc x264.h
--- 1/x264.h
--- 2/x264.h
+++ b/x264.h
@@@ -280,12 -245,11 +284,12 @@@ typedef struct x264_param_
      /* Video Properties */
      int         i_width;
      int         i_height;
-     int         i_csp;  /* CSP of encoded bitstream, only i420 supported */
+     int         i_csp;         /* CSP of encoded bitstream */
      int         i_level_idc;
      int         i_frame_total; /* number of frames to encode if known, else 0 */
 +    int         b_mpeg2; /* Encode output as MPEG-2 instead of H.264 */
  
 -    /* NAL HRD
 +    /* NAL HRD (H.264 ONLY)
       * Uses Buffering and Picture Timing SEIs to signal HRD
       * The HRD in H.264 was not designed with VFR in mind.
       * It is therefore not recommendeded to use NAL HRD with VFR.