[x264-devel] [PATCH ]Support 12bit and add ultra calss
xuefeng
xuefeng at multicorewareinc.com
Tue Sep 29 11:11:17 CEST 2015
From 42f66a8e7b25865945222447fcaa924a5580669d Mon Sep 17 00:00:00 2001
From: xuefeng <xuefeng at multicorewareinc.com>
Date: Thu, 24 Sep 2015 15:54:17 +0800
Subject: [PATCH] Support 12bit and add ultra calss based on AVC-Ultra
Specification from Panasonic Corporation, T-REC-H.264-201402-I!!PDF-E.pdf and
C-AVC Intra specification v1.1 20080404.doc
---
common/common.c | 69 +++-
common/common.h | 2 +-
common/macroblock.h | 6 +
common/set.h | 109 ++++++
configure | 6 +-
encoder/analyse.c | 15 +-
encoder/encoder.c | 913 +++++++++++++++++++++++++++++++++++++++++++++++++-
encoder/ratecontrol.c | 4 +-
encoder/set.c | 16 +-
x264.c | 37 +-
x264.h | 1 +
11 files changed, 1146 insertions(+), 32 deletions(-)
diff --git a/common/common.c b/common/common.c
index 6999a00..012fbb2 100644
--- a/common/common.c
+++ b/common/common.c
@@ -453,7 +453,7 @@ static int profile_string_to_int( const char *str )
return -1;
}
-int x264_param_apply_profile( x264_param_t *param, const char *profile )
+static int x264_param_apply_default_profile( x264_param_t *param, const char *profile )
{
if( !profile )
return 0;
@@ -514,6 +514,73 @@ int x264_param_apply_profile( x264_param_t *param, const char *profile )
return 0;
}
+static int class_string_to_int( const char *str )
+{
+#if BIT_DEPTH == 10
+ if( !strcasecmp( str, "intra-480" ) )
+ return AVCULTRA_CLASS_480;
+ if( !strcasecmp( str, "intra-300" ) )
+ return AVCULTRA_CLASS_300;
+ if( !strcasecmp( str, "intra-200" ) )
+ return AVCULTRA_CLASS_200;
+ if( !strcasecmp( str, "intra-100" ) )
+ return AVCULTRA_CLASS_100;
+ if( !strcasecmp( str, "intra-50" ) )
+ return AVCULTRA_CLASS_50;
+
+ if( !strcasecmp( str, "xavc-class-x25" ) )
+ return XAVC_CLASS_X25;
+ if( !strcasecmp( str, "xavc-class-x35" ) )
+ return XAVC_CLASS_X35;
+ if( !strcasecmp( str, "xavc-class-x50" ) )
+ return XAVC_CLASS_X50;
+#elif BIT_DEPTH == 12
+ if( !strcasecmp( str, "intra-444-220" ) )
+ return AVCULTRA_CLASS_220;
+ if( !strcasecmp( str, "intra-480" ) )
+ return AVCULTRA_CLASS_480;
+ if( !strcasecmp( str, "intra-444-600" ) )
+ return AVCULTRA_CLASS_600;
+#endif
+ return 0;
+}
+
+int x264_param_apply_profile( x264_param_t *param, const char *profiles )
+{
+ if( !profiles )
+ return 0;
+ const char *profile = profiles;
+ // test whether the first param is a param for class ultra or class xavc
+ if( param->i_ex_class > 0)
+ {
+ int csp = param->i_ex_class;
+ param->i_ex_class = class_string_to_int( profile );
+#if BIT_DEPTH == 10
+ if ( AVCULTRA_CLASS_480 == param->i_ex_class && !( 422 == csp ) )
+ param->i_ex_class = 0;
+#elif BIT_DEPTH == 12
+ if ( AVCULTRA_CLASS_480 == param->i_ex_class && !( 444 == csp ) )
+ param->i_ex_class = 0;
+#endif
+ if( param->i_ex_class == 0 )
+ {
+ x264_log( NULL, X264_LOG_ERROR, "invalid constraint class: %s\n", profile );
+#if BIT_DEPTH == 10
+ x264_log( NULL, X264_LOG_ERROR, "%d bits constraint: intra-50, intra-100, intra-200, intra-300, intra-480\n", BIT_DEPTH );
+#elif BIT_DEPTH == 12
+ x264_log( NULL, X264_LOG_ERROR, "%d bits constraint support: intra-444-220, intra-480, intra-444-600 \n", BIT_DEPTH );
+#endif
+ return -1;
+ }
+ profile = profiles + (strlen( profile ) + 1);
+ if( 0 == *profile )
+ return 0;
+ }
+ x264_param_apply_default_profile( param, profile );
+
+ return 0;
+}
+
static int parse_enum( const char *arg, const char * const *names, int *dst )
{
for( int i = 0; names[i]; i++ )
diff --git a/common/common.h b/common/common.h
index 9cda187..e1ccdcc 100644
--- a/common/common.h
+++ b/common/common.h
@@ -109,7 +109,7 @@ do {\
#define NALU_OVERHEAD 5 // startcode + NAL type costs 5 bytes per frame
#define FILLER_OVERHEAD (NALU_OVERHEAD+1)
-#define SEI_OVERHEAD (NALU_OVERHEAD - (h->param.b_annexb && !h->param.i_avcintra_class && (h->out.i_nal-1)))
+#define SEI_OVERHEAD (NALU_OVERHEAD - (h->param.b_annexb && !( h->param.i_avcintra_class || h->param.i_ex_class ) && (h->out.i_nal-1)))
/****************************************************************************
* Includes
diff --git a/common/macroblock.h b/common/macroblock.h
index 7974f5a..41fac75 100644
--- a/common/macroblock.h
+++ b/common/macroblock.h
@@ -250,6 +250,12 @@ static const uint8_t i_chroma_qp_table[QP_MAX+1+12*2] =
{
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
+#if BIT_DEPTH > 11
+ QP(-24), QP(-23), QP(-22), QP(-21), QP(-20), QP(-19),
+#endif
+#if BIT_DEPTH > 10
+ QP(-18), QP(-17), QP(-16), QP(-15), QP(-14), QP(-13),
+#endif
#if BIT_DEPTH > 9
QP(-12),QP(-11),QP(-10), QP(-9), QP(-8), QP(-7),
#endif
diff --git a/common/set.h b/common/set.h
index 0d4f806..489dd80 100644
--- a/common/set.h
+++ b/common/set.h
@@ -37,6 +37,27 @@ enum profile_e
PROFILE_HIGH444_PREDICTIVE = 244,
};
+enum class_e
+{
+ // avcultra class
+#if BIT_DEPTH == 10
+ AVCULTRA_CLASS_50 = 1,
+ AVCULTRA_CLASS_100,
+ AVCULTRA_CLASS_200,
+ AVCULTRA_CLASS_300,
+ AVCULTRA_CLASS_480,
+#elif BIT_DEPTH == 12
+ AVCULTRA_CLASS_220 = 1,
+ AVCULTRA_CLASS_480,
+ AVCULTRA_CLASS_600,
+#endif
+
+ // xavc class
+ XAVC_CLASS_X25,
+ XAVC_CLASS_X35,
+ XAVC_CLASS_X50,
+};
+
enum chroma_format_e
{
CHROMA_400 = 0,
@@ -257,6 +278,42 @@ static const uint8_t x264_cqm_avci50_4ic[16] =
40,44,48,60
};
+//2160p25_avci300 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci300_2160_4ic[16] =
+{
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16
+};
+
+//2160p25_avci480 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci480_2160_4ic[16] =
+{
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16
+};
+
+//2160p25_avci600 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci600_2160_4ic[16] =
+{
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16
+};
+
+//1080p25_avci220 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci220_1080_4ic[16] =
+{
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16,
+ 16,16,16,16
+};
+
// 1080i25_avci50,
static const uint8_t x264_cqm_avci50_1080i_8iy[64] =
{
@@ -340,6 +397,58 @@ static const uint8_t x264_cqm_avci100_720p_8iy[64] =
32,32,32,34,34,36,38,42
};
+// 2160p25_avci300,2160p50_avci300 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci300_2160p_8iy[64] =
+{
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16
+};
+
+// 2160p25_avci480,2160p25_avci480 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci480_2160p_8iy[64] =
+{
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16
+};
+
+// 2160p25_avci600 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci600_2160p_8iy[64] =
+{
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16
+};
+
+// 1080p25_avci220 //TODO: The temporary quantization matrix
+static const uint8_t x264_cqm_avci220_1080p_8iy[64] =
+{
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16
+};
+
int x264_cqm_init( x264_t *h );
void x264_cqm_delete( x264_t *h );
int x264_cqm_parse_file( x264_t *h, const char *filename );
diff --git a/configure b/configure
index 57a47ac..c905df8 100755
--- a/configure
+++ b/configure
@@ -30,7 +30,7 @@ Configuration options:
--disable-thread disable multithreaded encoding
--enable-win32thread use win32threads (windows only)
--disable-interlaced disable interlaced encoding support
- --bit-depth=BIT_DEPTH set output bit depth (8-10) [8]
+ --bit-depth=BIT_DEPTH set output bit depth (8-12) [8]
--chroma-format=FORMAT output chroma format (420, 422, 444, all) [all]
Advanced options:
@@ -481,8 +481,8 @@ for opt do
;;
--bit-depth=*)
bit_depth="$optarg"
- if [ "$bit_depth" -lt "8" -o "$bit_depth" -gt "10" ]; then
- echo "Supplied bit depth must be in range [8,10]."
+ if [ "$bit_depth" -lt "8" -o "$bit_depth" -gt "12" ]; then
+ echo "Supplied bit depth must be in range [8,12]."
exit 1
fi
bit_depth=`expr $bit_depth + 0`
diff --git a/encoder/analyse.c b/encoder/analyse.c
index b82f647..5a22036 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -436,7 +436,7 @@ static void x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int qp )
/* non-RD PCM decision is inaccurate (as is psy-rd), so don't do it.
* PCM cost can overflow with high lambda2, so cap it at COST_MAX. */
uint64_t pcm_cost = ((uint64_t)X264_PCM_COST*a->i_lambda2 + 128) >> 8;
- a->i_satd_pcm = !h->param.i_avcintra_class && !h->mb.i_psy_rd && a->i_mbrd && pcm_cost < COST_MAX ? pcm_cost : COST_MAX;
+ a->i_satd_pcm = !h->param.i_avcintra_class && !h->param.i_ex_class && !h->mb.i_psy_rd && a->i_mbrd && pcm_cost < COST_MAX ? pcm_cost : COST_MAX;
a->b_fast_intra = 0;
a->b_avoid_topright = 0;
@@ -812,7 +812,7 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_satd_
/*---------------- Try all mode and calculate their score ---------------*/
/* Disabled i16x16 for AVC-Intra compat */
- if( !h->param.i_avcintra_class )
+ if( !( h->param.i_avcintra_class || h->param.i_ex_class ) )
{
const int8_t *predict_mode = predict_16x16_mode_available( h->mb.i_neighbour_intra );
@@ -3055,10 +3055,13 @@ intra_analysis:
if( analysis.i_mbrd )
x264_intra_rd( h, &analysis, COST_MAX );
- i_cost = analysis.i_satd_i16x16;
- h->mb.i_type = I_16x16;
- COPY2_IF_LT( i_cost, analysis.i_satd_i4x4, h->mb.i_type, I_4x4 );
- COPY2_IF_LT( i_cost, analysis.i_satd_i8x8, h->mb.i_type, I_8x8 );
+ if ( !( h->param.i_avcintra_class || h->param.i_ex_class ) )
+ {
+ i_cost = analysis.i_satd_i16x16;
+ h->mb.i_type = I_16x16;
+ COPY2_IF_LT( i_cost, analysis.i_satd_i4x4, h->mb.i_type, I_4x4 );
+ COPY2_IF_LT( i_cost, analysis.i_satd_i8x8, h->mb.i_type, I_8x8 );
+ }
if( analysis.i_satd_pcm < i_cost )
h->mb.i_type = I_PCM;
diff --git a/encoder/encoder.c b/encoder/encoder.c
index 79997b9..4722c98 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -410,6 +410,885 @@ static void x264_encoder_thread_init( x264_t *h )
}
#endif
+#if BIT_DEPTH == 10
+static int apply_avcultra_class_50_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ h->param.b_cabac = 1;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_nal_hrd = X264_NAL_HRD_CBR;
+ h->param.i_slice_count = 10;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+ h->param.rc.i_rc_method = X264_RC_ABR;
+
+ // sps set
+ h->param.vui.i_sar_width = 4;
+ h->param.vui.i_sar_height = 3;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.analyse.i_chroma_qp_offset = 4;
+ h->param.b_stitchable = 1;
+
+ if( h->param.i_width == 960 && h->param.i_height == 720 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 53276)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 54067)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 26638)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 27033)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 27033)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 21314)) ||
+ (h->param.i_ex_class = 0);
+
+ h->param.i_level_idc = 32;
+ }
+ else if( h->param.i_width == 1440 && h->param.i_height == 1080 )
+ {
+ if( (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 107044)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 108544)) )
+ {
+ h->param.i_level_idc = 42;
+ }
+ else if( (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 1 && (h->param.rc.i_bitrate = 107044)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 1 && (h->param.rc.i_bitrate = 108544)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 53522)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 54272)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 54272)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 42800)) )
+ {
+ h->param.i_level_idc = 40;
+ }
+ else
+ {
+ h->param.i_ex_class = 0;
+ }
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid or Interlaced %c invalid for AVC-Ultra 50 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num, h->param.b_interlaced ? 'I' : 'P' );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ memcpy( h->param.cqm_4ic, x264_cqm_avci50_4ic, sizeof( h->param.cqm_4ic ) );
+ if( PARAM_INTERLACED == 0 )
+ {
+ memcpy( h->param.cqm_8iy, x264_cqm_avci50_p_8iy, sizeof( h->param.cqm_8iy ) );
+ }
+ else
+ {
+ memcpy( h->param.cqm_8iy, x264_cqm_avci50_1080i_8iy, sizeof( h->param.cqm_8iy ) );
+ }
+
+ h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+
+ return 0;
+}
+
+static int apply_avcultra_class_100_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ h->param.b_cabac = 0;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_slice_count = 10;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+
+ // sps set
+ h->param.vui.i_sar_width = 1;
+ h->param.vui.i_sar_height = 1;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.b_stitchable = 1;
+
+ if( h->param.i_width == 1280 && h->param.i_height == 720 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 110726)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 111616)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 55363)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 55800)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 55800)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 44298)) ||
+ (h->param.i_ex_class = 0);
+
+ h->param.i_level_idc = 41;
+ h->param.i_nal_hrd = X264_NAL_HRD_CBR;
+ h->param.analyse.i_chroma_qp_offset = 4;
+ }
+ else if( h->param.i_width == 1920 && h->param.i_height == 1080 )
+ {
+ if( (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 221944)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 223641)) )
+ {
+ h->param.i_level_idc = 42;
+ }
+ else if( (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 1 && (h->param.rc.i_bitrate = 221944)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 1 && (h->param.rc.i_bitrate = 223641)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 110972)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 111820)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 111820)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 88700)) )
+ {
+ h->param.i_level_idc = 41;
+ }
+ else
+ {
+ h->param.i_ex_class = 0;
+ }
+
+ h->param.i_nal_hrd = X264_NAL_HRD_CBR;
+ h->param.analyse.i_chroma_qp_offset = 3;
+ }
+ else if( h->param.i_width == 2048 && h->param.i_height == 1080 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 213000) && (h->param.rc.i_vbv_max_bitrate = 232000)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 215000) && (h->param.rc.i_vbv_max_bitrate = 235000)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 106000) && (h->param.rc.i_vbv_max_bitrate = 116000)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 107000) && (h->param.rc.i_vbv_max_bitrate = 117000)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 107000) && (h->param.rc.i_vbv_max_bitrate = 117000)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 90000) && (h->param.rc.i_vbv_max_bitrate = 98000)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 85000) && (h->param.rc.i_vbv_max_bitrate = 93000)) ||
+ (h->param.i_ex_class = 0);
+
+ h->param.i_level_idc = 42;
+ h->param.i_nal_hrd = X264_NAL_HRD_VBR;
+ h->param.i_slice_count = 8;
+ h->param.analyse.i_chroma_qp_offset = 3;
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid or Interlaced %c invalid for AVC-Ultra 100 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num, h->param.b_interlaced ? 'I' : 'P' );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ if( h->param.i_height == 720 )
+ {
+ memcpy( h->param.cqm_4ic, x264_cqm_avci100_720p_4ic, sizeof( h->param.cqm_4ic ) );
+ memcpy( h->param.cqm_8iy, x264_cqm_avci100_720p_8iy, sizeof( h->param.cqm_8iy ) );
+ }
+ else
+ {
+ memcpy( h->param.cqm_4ic, x264_cqm_avci100_1080_4ic, sizeof( h->param.cqm_4ic ) );
+ if( PARAM_INTERLACED == 0 )
+ {
+ memcpy( h->param.cqm_8iy, x264_cqm_avci100_1080p_8iy, sizeof( h->param.cqm_8iy ) );
+ }
+ else
+ {
+ memcpy( h->param.cqm_8iy, x264_cqm_avci100_1080i_8iy, sizeof( h->param.cqm_8iy ) );
+ }
+ }
+
+ if( X264_NAL_HRD_CBR == h->param.i_nal_hrd )
+ {
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+ }
+ else
+ {
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+ }
+
+ return 0;
+}
+
+static int apply_avcultra_class_200_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ h->param.b_cabac = 0;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_slice_count = 10;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+
+ // sps set
+ h->param.vui.i_sar_width = 1;
+ h->param.vui.i_sar_height = 1;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.b_stitchable = 1;
+
+ if( h->param.i_width == 1280 && h->param.i_height == 720 )
+ {
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 90364)) ||
+ (h->param.i_fps_num == 23980 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 90364)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 112936)) ||
+ (h->param.i_fps_num == 29970 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 112936)) ||
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 225873)) ||
+ (h->param.i_fps_num == 59940 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 225873)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 113356)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 113356)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 226713)) ||
+ (h->param.i_ex_class = 0);
+
+ h->param.i_level_idc = 41;
+ h->param.i_nal_hrd = X264_NAL_HRD_CBR;
+ h->param.analyse.i_chroma_qp_offset = 4;
+ }
+ else if( h->param.i_width == 1920 && h->param.i_height == 1080 )
+ {
+ if( (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 451700)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 453200)) )
+ {
+ h->param.i_level_idc = 50;
+ }
+ else if( (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 1 && (h->param.rc.i_bitrate = 451700)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 1 && (h->param.rc.i_bitrate = 453200)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 225854)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 226600)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 226600)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 180713)) )
+ {
+ h->param.i_level_idc = 41;
+ }
+ else
+ {
+ h->param.i_ex_class = 0;
+ }
+
+ h->param.i_nal_hrd = X264_NAL_HRD_CBR;
+ h->param.analyse.i_chroma_qp_offset = 3;
+ }
+ else if( h->param.i_width == 2048 && h->param.i_height == 1080 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 220000) && (h->param.rc.i_vbv_max_bitrate = 240000)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 220000) && (h->param.rc.i_vbv_max_bitrate = 240000)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 110000) && (h->param.rc.i_vbv_max_bitrate = 120000)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 110000) && (h->param.rc.i_vbv_max_bitrate = 120000)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 110000) && (h->param.rc.i_vbv_max_bitrate = 120000)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 90000) && (h->param.rc.i_vbv_max_bitrate = 98000)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 90000) && (h->param.rc.i_vbv_max_bitrate = 98000)) ||
+ (h->param.i_ex_class = 0);
+
+ h->param.i_level_idc = 50;
+ h->param.i_nal_hrd = X264_NAL_HRD_VBR;
+ h->param.i_slice_count = 8;
+ h->param.analyse.i_chroma_qp_offset = 3;
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid for AVC-Ultra 200 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ memcpy( h->param.cqm_4ic, x264_cqm_avci100_1080_4ic, sizeof( h->param.cqm_4ic ) );
+ if( PARAM_INTERLACED == 0 )
+ {
+ memcpy( h->param.cqm_8iy, x264_cqm_avci100_1080p_8iy, sizeof( h->param.cqm_8iy ) );
+ }
+ else
+ {
+ memcpy( h->param.cqm_8iy, x264_cqm_avci100_1080i_8iy, sizeof( h->param.cqm_8iy ) );
+ }
+
+ if( X264_NAL_HRD_CBR == h->param.i_nal_hrd )
+ {
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+ }
+ else
+ {
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+ }
+
+ return 0;
+}
+
+static int apply_avcultra_class_300_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ h->param.b_cabac = 0;
+ h->param.i_nal_hrd = X264_NAL_HRD_VBR;
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.i_level_idc = 52;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_slice_count = 16;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+
+ // sps set
+ h->param.vui.i_sar_width = 1;
+ h->param.vui.i_sar_height = 1;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.b_stitchable = 1;
+ h->param.analyse.i_chroma_qp_offset = 3;
+
+ if( h->param.i_width == 3840 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 576000) && (h->param.rc.i_vbv_max_bitrate = 627000)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 480000) && (h->param.rc.i_vbv_max_bitrate = 523000)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 288000) && (h->param.rc.i_vbv_max_bitrate = 313920)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 230000) && (h->param.rc.i_vbv_max_bitrate = 251000)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else if( h->param.i_width == 4096 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 576000) && (h->param.rc.i_vbv_max_bitrate = 627000)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 480000) && (h->param.rc.i_vbv_max_bitrate = 523000)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 288000) && (h->param.rc.i_vbv_max_bitrate = 313920)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 230000) && (h->param.rc.i_vbv_max_bitrate = 251000)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 230000) && (h->param.rc.i_vbv_max_bitrate = 251000)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid for AVC-Ultra 300 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ memcpy( h->param.cqm_4ic, x264_cqm_avci300_2160_4ic, sizeof( h->param.cqm_4ic ) );
+ memcpy( h->param.cqm_8iy, x264_cqm_avci300_2160p_8iy, sizeof( h->param.cqm_8iy ) );
+
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+
+ return 0;
+}
+
+static int apply_avcultra_class_480_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ int i_csp = h->param.i_csp & X264_CSP_MASK;
+ if( i_csp != X264_CSP_I422)
+ {
+ x264_log( NULL, X264_LOG_ERROR, "10 bits intra-480 need csp i422\n" );
+ return -1;
+ }
+
+ h->param.i_nal_hrd = X264_NAL_HRD_VBR;
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.i_level_idc = 52;
+ h->param.b_cabac = 0;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_slice_count = 16;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+
+ // sps set
+ h->param.vui.i_sar_width = 1;
+ h->param.vui.i_sar_height = 1;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.b_stitchable = 1;
+ h->param.analyse.i_chroma_qp_offset = 3;
+
+ if( h->param.i_width == 3840 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 576000) && (h->param.rc.i_vbv_max_bitrate = 627000)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 480000) && (h->param.rc.i_vbv_max_bitrate = 523000)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 288000) && (h->param.rc.i_vbv_max_bitrate = 313920)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 230000) && (h->param.rc.i_vbv_max_bitrate = 251000)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else if( h->param.i_width == 4096 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 576000) && (h->param.rc.i_vbv_max_bitrate = 627000)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 480000) && (h->param.rc.i_vbv_max_bitrate = 523000)) ||
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 288000) && (h->param.rc.i_vbv_max_bitrate = 313920)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 240000) && (h->param.rc.i_vbv_max_bitrate = 261600)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 230000) && (h->param.rc.i_vbv_max_bitrate = 251000)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 230000) && (h->param.rc.i_vbv_max_bitrate = 251000)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid for AVC-Ultra 480 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ memcpy( h->param.cqm_4ic, x264_cqm_avci480_2160_4ic, sizeof( h->param.cqm_4ic ) );
+ memcpy( h->param.cqm_8iy, x264_cqm_avci480_2160p_8iy, sizeof( h->param.cqm_8iy ) );
+
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+
+ return 0;
+}
+
+#elif BIT_DEPTH == 12
+static int apply_avcultra_class_220_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ h->param.i_nal_hrd = X264_NAL_HRD_VBR;
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.b_cabac = 0;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_slice_count = 8;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+
+ // sps set
+ h->param.vui.i_sar_width = 1;
+ h->param.vui.i_sar_height = 1;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.analyse.i_chroma_qp_offset = 3;
+ h->param.b_stitchable = 1;
+
+
+ if( h->param.i_width == 1920 && h->param.i_height == 1080 )
+ {
+ if( (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 439676) && (h->param.rc.i_vbv_max_bitrate = 479980)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 367018) && (h->param.rc.i_vbv_max_bitrate = 400384)) )
+ {
+ h->param.i_level_idc = 50;
+ }
+ else if( (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 219990) && (h->param.rc.i_vbv_max_bitrate = 239990)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 219990) && (h->param.rc.i_vbv_max_bitrate = 200192)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 219990) && (h->param.rc.i_vbv_max_bitrate = 200192)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 176348) && (h->param.rc.i_vbv_max_bitrate = 192024)) )
+ {
+ h->param.i_level_idc = 41;
+ }
+ else
+ {
+ h->param.i_ex_class = 0;
+ }
+ }
+ else if( h->param.i_width == 2048 && h->param.i_height == 1080 )
+ {
+ if( (h->param.i_fps_num == 60000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 439981) && (h->param.rc.i_vbv_max_bitrate = 479980)) ||
+ (h->param.i_fps_num == 50000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 367018) && (h->param.rc.i_vbv_max_bitrate = 400384)) )
+ {
+ h->param.i_level_idc = 50;
+ }
+ else if( (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 219990) && (h->param.rc.i_vbv_max_bitrate = 239990)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 183509) && (h->param.rc.i_vbv_max_bitrate = 200192)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 183509) && (h->param.rc.i_vbv_max_bitrate = 200192)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 176495) && (h->param.rc.i_vbv_max_bitrate = 192184)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 176348) && (h->param.rc.i_vbv_max_bitrate = 192024)) )
+ {
+ h->param.i_level_idc = 42;
+ }
+ else
+ {
+ h->param.i_ex_class = 0;
+ }
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid for AVC-Ultra 220 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ memcpy( h->param.cqm_4ic, x264_cqm_avci220_1080_4ic, sizeof( h->param.cqm_4ic ) );
+ memcpy( h->param.cqm_8iy, x264_cqm_avci220_1080p_8iy, sizeof( h->param.cqm_8iy ) );
+
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+
+ return 0;
+}
+static int apply_avcultra_class_480_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ int i_csp = h->param.i_csp & X264_CSP_MASK;
+ if( i_csp != X264_CSP_I444 )
+ {
+ x264_log( NULL, X264_LOG_ERROR, "12 bits intra-480 need csp i444\n" );
+ return -1;
+ }
+
+ h->param.i_nal_hrd = X264_NAL_HRD_VBR;
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.i_level_idc = 52;
+ h->param.b_cabac = 0;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_slice_count = 16;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+
+ // sps set
+ h->param.vui.i_sar_width = 1;
+ h->param.vui.i_sar_height = 1;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.analyse.i_chroma_qp_offset = 3;
+ h->param.b_stitchable = 1;
+
+ if( h->param.i_width == 3840 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 439898) && (h->param.rc.i_vbv_max_bitrate = 479489)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 366948) && (h->param.rc.i_vbv_max_bitrate = 399974)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 366948) && (h->param.rc.i_vbv_max_bitrate = 399974)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 352112) && (h->param.rc.i_vbv_max_bitrate = 383655)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else if( h->param.i_width == 4096 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 439898) && (h->param.rc.i_vbv_max_bitrate = 479489)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 366948) && (h->param.rc.i_vbv_max_bitrate = 399974)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 366948) && (h->param.rc.i_vbv_max_bitrate = 399974)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 352405) && (h->param.rc.i_vbv_max_bitrate = 383975)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 352112) && (h->param.rc.i_vbv_max_bitrate = 383655)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid for AVC-Ultra 480 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ memcpy( h->param.cqm_4ic, x264_cqm_avci480_2160_4ic, sizeof( h->param.cqm_4ic ) );
+ memcpy( h->param.cqm_8iy, x264_cqm_avci480_2160p_8iy, sizeof( h->param.cqm_8iy ) );
+
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+
+ return 0;
+}
+static int apply_avcultra_class_600_profile( x264_t *h )
+{
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ h->param.i_ex_class = 0;
+ return -1;
+ }
+
+ h->param.i_nal_hrd = X264_NAL_HRD_VBR;
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.i_level_idc = 52;
+ h->param.b_cabac = 0;
+ h->param.i_keyint_max = 1;
+ h->param.b_deblocking_filter = 0;
+ h->param.i_slice_count = 16;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+
+ // sps set
+ h->param.vui.i_sar_width = 1;
+ h->param.vui.i_sar_height = 1;
+ h->param.vui.i_overscan = 2;
+ h->param.vui.i_vidformat = 0;
+ h->param.vui.b_fullrange = 0;
+ h->param.vui.i_colorprim = 1;
+ h->param.vui.i_transfer = 1;
+ h->param.vui.i_colmatrix = 1;
+ h->param.b_pic_struct = 0;
+
+ // pps set
+ h->param.i_frame_reference = 1;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.analyse.i_chroma_qp_offset = 3;
+ h->param.b_stitchable = 1;
+
+ if( h->param.i_width == 3840 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 599933) && (h->param.rc.i_vbv_max_bitrate = 653927)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 500444) && (h->param.rc.i_vbv_max_bitrate = 545484)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 500444) && (h->param.rc.i_vbv_max_bitrate = 545484)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 480210) && (h->param.rc.i_vbv_max_bitrate = 523229)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else if( h->param.i_width == 4096 && h->param.i_height == 2160 )
+ {
+ (h->param.i_fps_num == 30000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 599933) && (h->param.rc.i_vbv_max_bitrate = 653927)) ||
+ (h->param.i_fps_num == 25000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 500444) && (h->param.rc.i_vbv_max_bitrate = 545484)) ||
+ (h->param.i_fps_num == 25 && h->param.i_fps_den == 1 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 500444) && (h->param.rc.i_vbv_max_bitrate = 545484)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1000 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 480000) && (h->param.rc.i_vbv_max_bitrate = 523229)) ||
+ (h->param.i_fps_num == 24000 && h->param.i_fps_den == 1001 && PARAM_INTERLACED == 0 && (h->param.rc.i_bitrate = 480610) && (h->param.rc.i_vbv_max_bitrate = 523665)) ||
+ (h->param.i_ex_class = 0);
+ }
+ else
+ h->param.i_ex_class = 0;
+
+ if( !h->param.i_ex_class )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid or FPS %d invalid for AVC-Ultra 600 Class\n",
+ h->param.i_width, h->param.i_height, h->param.i_fps_num );
+ return -1;
+ }
+
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof( h->param.cqm_4iy ) );
+ memcpy( h->param.cqm_4ic, x264_cqm_avci600_2160_4ic, sizeof( h->param.cqm_4ic ) );
+ memcpy( h->param.cqm_8iy, x264_cqm_avci600_2160p_8iy, sizeof( h->param.cqm_8iy ) );
+
+ h->param.rc.i_vbv_buffer_size = h->param.rc.i_vbv_max_bitrate * h->param.i_fps_den / h->param.i_fps_num;
+
+ return 0;
+}
+#endif
+
+static int x264_param_apply_class_profile( x264_t *h )
+{
+ if( !h->param.i_ex_class )
+ {
+ return -1;
+ }
+
+ if( BIT_DEPTH < 10 )
+ {
+ x264_log( h, X264_LOG_ERROR, "%2d-bit AVC-Intra is not widely compatible\n", BIT_DEPTH );
+ x264_log( h, X264_LOG_ERROR, "HIGH_BIT_DEPTH is required to encode AVC-Intra\n" );
+ return -1;
+ }
+
+ switch( h->param.i_ex_class )
+ {
+#if BIT_DEPTH == 10
+ case AVCULTRA_CLASS_50:
+ if(apply_avcultra_class_50_profile( h ))
+ return -1;
+ break;
+ case AVCULTRA_CLASS_100:
+ if(apply_avcultra_class_100_profile( h ))
+ return -1;
+ break;
+ case AVCULTRA_CLASS_200:
+ if(apply_avcultra_class_200_profile( h ))
+ return -1;
+ break;
+ case AVCULTRA_CLASS_300:
+ if(apply_avcultra_class_300_profile( h ))
+ return -1;
+ break;
+ case AVCULTRA_CLASS_480:
+ if(apply_avcultra_class_480_profile( h ))
+ return -1;
+ break;
+
+ case XAVC_CLASS_X25:
+ // add the constriction for class p25
+ break;
+ case XAVC_CLASS_X35:
+ // add the constriction for class p35
+ break;
+ case XAVC_CLASS_X50:
+ // add the constriction for class p50
+ break;
+#elif BIT_DEPTH == 12
+ case AVCULTRA_CLASS_220:
+ if( apply_avcultra_class_220_profile( h ) )
+ return -1;
+ break;
+ case AVCULTRA_CLASS_480:
+ if( apply_avcultra_class_480_profile( h ) )
+ return -1;
+ break;
+ case AVCULTRA_CLASS_600:
+ if( apply_avcultra_class_600_profile( h ) )
+ return -1;
+ break;
+#endif
+ default:
+ x264_log( h, X264_LOG_ERROR, "Invalid AVC-Ultra class\n" );
+ return -1;
+ }
+ return 0;
+}
+
/****************************************************************************
*
****************************************************************************
@@ -825,6 +1704,12 @@ static int x264_validate_parameters( x264_t *h, int b_open )
h->param.rc.i_qp_min = X264_MAX( h->param.rc.i_qp_min, QP_BD_OFFSET + 1 );
}
+ if( h->param.i_ex_class )
+ {
+ if( x264_param_apply_class_profile( h ) )
+ return -1;
+ }
+
h->param.rc.f_rf_constant = x264_clip3f( h->param.rc.f_rf_constant, -QP_BD_OFFSET, 51 );
h->param.rc.f_rf_constant_max = x264_clip3f( h->param.rc.f_rf_constant_max, -QP_BD_OFFSET, 51 );
h->param.rc.i_qp_constant = x264_clip3( h->param.rc.i_qp_constant, 0, QP_MAX );
@@ -1124,14 +2009,14 @@ static int x264_validate_parameters( x264_t *h, int b_open )
h->mb.i_psy_trellis = h->param.analyse.i_trellis ? FIX8( h->param.analyse.f_psy_trellis / 4 ) : 0;
h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -32, 32);
/* In 4:4:4 mode, chroma gets twice as much resolution, so we can halve its quality. */
- if( b_open && i_csp >= X264_CSP_I444 && i_csp < X264_CSP_BGR && h->param.analyse.b_psy )
+ if( b_open && i_csp >= X264_CSP_I444 && i_csp < X264_CSP_BGR && h->param.analyse.b_psy && h->param.i_ex_class <= 0 )
h->param.analyse.i_chroma_qp_offset += 6;
/* Psy RDO increases overall quantizers to improve the quality of luma--this indirectly hurts chroma quality */
/* so we lower the chroma QP offset to compensate */
- if( b_open && h->mb.i_psy_rd && !h->param.i_avcintra_class )
+ if( b_open && h->mb.i_psy_rd && !( h->param.i_avcintra_class || h->param.i_ex_class) )
h->param.analyse.i_chroma_qp_offset -= h->param.analyse.f_psy_rd < 0.25 ? 1 : 2;
/* Psy trellis has a similar effect. */
- if( b_open && h->mb.i_psy_trellis && !h->param.i_avcintra_class )
+ if( b_open && h->mb.i_psy_trellis && !( h->param.i_avcintra_class || h->param.i_ex_class) )
h->param.analyse.i_chroma_qp_offset -= h->param.analyse.f_psy_trellis < 0.25 ? 1 : 2;
h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);
/* MB-tree requires AQ to be on, even if the strength is zero. */
@@ -1448,7 +2333,7 @@ x264_t *x264_encoder_open( x264_param_t *param )
h->i_frame = -1;
h->i_frame_num = 0;
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
h->i_idr_pic_id = 5;
else
h->i_idr_pic_id = 0;
@@ -1960,10 +2845,10 @@ static int x264_encoder_encapsulate_nals( x264_t *h, int start )
{
int old_payload_len = h->out.nal[i].i_payload;
h->out.nal[i].b_long_startcode = !i || h->out.nal[i].i_type == NAL_SPS || h->out.nal[i].i_type == NAL_PPS ||
- h->param.i_avcintra_class;
+ h->param.i_avcintra_class || h->param.i_ex_class;
x264_nal_encode( h, nal_buffer, &h->out.nal[i] );
nal_buffer += h->out.nal[i].i_payload;
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
{
h->out.nal[i].i_padding -= h->out.nal[i].i_payload - (old_payload_len + NALU_OVERHEAD);
if( h->out.nal[i].i_padding > 0 )
@@ -2504,7 +3389,7 @@ static inline void x264_slice_init( x264_t *h, int i_nal_type, int i_global_qp )
x264_slice_header_init( h, &h->sh, h->sps, h->pps, h->i_idr_pic_id, h->i_frame_num, i_global_qp );
/* alternate id */
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
{
switch( h->i_idr_pic_id )
{
@@ -3555,7 +4440,7 @@ int x264_encoder_encode( x264_t *h,
if( x264_nal_end( h ) )
return -1;
/* Pad AUD/SPS to 256 bytes like Panasonic */
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
h->out.nal[h->out.i_nal-1].i_padding = 256 - bs_pos( &h->out.bs ) / 8 - 2*NALU_OVERHEAD;
overhead += h->out.nal[h->out.i_nal-1].i_payload + h->out.nal[h->out.i_nal-1].i_padding + NALU_OVERHEAD;
@@ -3564,7 +4449,7 @@ int x264_encoder_encode( x264_t *h,
x264_pps_write( &h->out.bs, h->sps, h->pps );
if( x264_nal_end( h ) )
return -1;
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
h->out.nal[h->out.i_nal-1].i_padding = 256 - h->out.nal[h->out.i_nal-1].i_payload - NALU_OVERHEAD;
overhead += h->out.nal[h->out.i_nal-1].i_payload + h->out.nal[h->out.i_nal-1].i_padding + NALU_OVERHEAD;
}
@@ -3607,7 +4492,7 @@ int x264_encoder_encode( x264_t *h,
if( h->fenc->b_keyframe )
{
/* Avid's decoder strictly wants two SEIs for AVC-Intra so we can't insert the x264 SEI */
- if( h->param.b_repeat_headers && h->fenc->i_frame == 0 && !h->param.i_avcintra_class )
+ if( h->param.b_repeat_headers && h->fenc->i_frame == 0 && !( h->param.i_avcintra_class || h->param.i_ex_class ) )
{
/* identify ourself */
x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
@@ -3639,7 +4524,7 @@ int x264_encoder_encode( x264_t *h,
}
/* generate sei pic timing */
- if( h->sps->vui.b_pic_struct_present || h->sps->vui.b_nal_hrd_parameters_present )
+ if( (h->sps->vui.b_pic_struct_present || h->sps->vui.b_nal_hrd_parameters_present) && (h->param.i_ex_class < 1) )
{
x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
x264_sei_pic_timing_write( h, &h->out.bs );
@@ -3663,7 +4548,7 @@ int x264_encoder_encode( x264_t *h,
h->i_cpb_delay_pir_offset_next = h->fenc->i_cpb_delay;
/* Filler space: 10 or 18 SEIs' worth of space, depending on resolution */
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
{
/* Write an empty filler NAL to mimic the AUD in the P2 format*/
x264_nal_start( h, NAL_FILLER, NAL_PRIORITY_DISPOSABLE );
@@ -3774,7 +4659,7 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
x264_emms();
/* generate buffering period sei and insert it into place */
- if( h->i_thread_frames > 1 && h->fenc->b_keyframe && h->sps->vui.b_nal_hrd_parameters_present )
+ if( h->i_thread_frames > 1 && h->fenc->b_keyframe && h->sps->vui.b_nal_hrd_parameters_present && (h->param.i_ex_class < 1) )
{
x264_hrd_fullness( h );
x264_nal_start( h, NAL_SEI, NAL_PRIORITY_DISPOSABLE );
@@ -3835,7 +4720,7 @@ static int x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
/* Filler in AVC-Intra mode is written as zero bytes to the last slice
* We don't know the size of the last slice until encapsulation so we add filler to the encapsulated NAL */
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
{
x264_t *h0 = h->thread[0];
int ret = x264_check_encapsulated_buffer( h, h0, h->out.i_nal, frame_size, frame_size + filler );
diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c
index d49e2a2..43c486f 100644
--- a/encoder/ratecontrol.c
+++ b/encoder/ratecontrol.c
@@ -2134,7 +2134,7 @@ static int update_vbv( x264_t *h, int bits )
rct->buffer_fill_final_min = 0;
}
- if( h->param.i_avcintra_class )
+ if( h->param.i_avcintra_class || h->param.i_ex_class )
buffer_diff = buffer_size;
else
buffer_diff = (uint64_t)bitrate * h->sps->vui.i_num_units_in_tick * h->fenc->i_cpb_duration;
@@ -2147,7 +2147,7 @@ static int update_vbv( x264_t *h, int bits )
{
int64_t scale = (int64_t)h->sps->vui.i_time_scale * 8;
filler = (rct->buffer_fill_final - buffer_size + scale - 1) / scale;
- bits = h->param.i_avcintra_class ? filler * 8 : X264_MAX( (FILLER_OVERHEAD - h->param.b_annexb), filler ) * 8;
+ bits = (h->param.i_avcintra_class || h->param.i_ex_class) ? filler * 8 : X264_MAX( (FILLER_OVERHEAD - h->param.b_annexb), filler ) * 8;
buffer_diff = (uint64_t)bits * h->sps->vui.i_time_scale;
rct->buffer_fill_final -= buffer_diff;
rct->buffer_fill_final_min -= buffer_diff;
diff --git a/encoder/set.c b/encoder/set.c
index 9e65e62..c57baa5 100644
--- a/encoder/set.c
+++ b/encoder/set.c
@@ -166,7 +166,7 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
while( (1 << sps->i_log2_max_frame_num) <= max_frame_num )
sps->i_log2_max_frame_num++;
- sps->i_poc_type = param->i_bframe || param->b_interlaced || param->i_avcintra_class ? 0 : 2;
+ sps->i_poc_type = param->i_bframe || param->b_interlaced || param->i_avcintra_class || param->i_ex_class ? 0 : 2;
if( sps->i_poc_type == 0 )
{
int max_delta_poc = (param->i_bframe + 2) * (!!param->i_bframe_pyramid + 1) * 2;
@@ -241,12 +241,20 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
if( sps->vui.b_timing_info_present )
{
sps->vui.i_num_units_in_tick = param->i_timebase_num;
- sps->vui.i_time_scale = param->i_timebase_den * 2;
+ if( param->b_interlaced == 1 && param->i_ex_class > 0 )
+ {
+ sps->vui.i_time_scale = param->i_timebase_den;
+ }
+ else
+ sps->vui.i_time_scale = param->i_timebase_den * 2;
sps->vui.b_fixed_frame_rate = !param->b_vfr_input;
}
sps->vui.b_vcl_hrd_parameters_present = 0; // we don't support VCL HRD
- sps->vui.b_nal_hrd_parameters_present = !!param->i_nal_hrd;
+ if( param->i_ex_class <= 0 )
+ {
+ sps->vui.b_nal_hrd_parameters_present = !!param->i_nal_hrd;
+ }
sps->vui.b_pic_struct_present = param->b_pic_struct;
// NOTE: HRD related parts of the SPS are initialised in x264_ratecontrol_init_reconfigurable
@@ -423,7 +431,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
pps->i_sps_id = sps->i_id;
pps->b_cabac = param->b_cabac;
- pps->b_pic_order = !param->i_avcintra_class && param->b_interlaced;
+ pps->b_pic_order = !(param->i_avcintra_class || param->i_ex_class) && param->b_interlaced;
pps->i_num_slice_groups = 1;
pps->i_num_ref_idx_l0_default_active = param->i_frame_reference;
diff --git a/x264.c b/x264.c
index 4dd2a26..404d33c 100644
--- a/x264.c
+++ b/x264.c
@@ -895,6 +895,15 @@ static void help( x264_param_t *defaults, int longhelp )
H1( " --bluray-compat Enable compatibility hacks for Blu-ray support\n" );
H1( " --avcintra-class <integer> Use compatibility hacks for AVC-Intra class\n"
" - 50, 100, 200\n" );
+ H1( " --constraint <string> Specify output constraint of AVC-Ultra or XAVC [\"class type\"]\n"
+#if BIT_DEPTH == 10
+ " intra-50, intra-100, intra-200, intra-300, intra-480 \n"
+ " xavc-class-x25, xavc-class-x35, xavc-class-x50 \n"
+#elif BIT_DEPTH == 12
+ " intra-444-220, intra-480, intra-444-600,\n"
+#endif
+ );
+ H1( " Note: Requires set FPS and resolution.\n" );
H1( " --stitchable Don't optimize headers based on video content\n"
" Ensures ability to recombine a segmented encode\n" );
H1( "\n" );
@@ -952,6 +961,7 @@ typedef enum
OPT_NOPROGRESS,
OPT_LONGHELP,
OPT_PROFILE,
+ OPT_CONSTRAINT,
OPT_PRESET,
OPT_TUNE,
OPT_SLOWFIRSTPASS,
@@ -997,6 +1007,7 @@ static struct option long_options[] =
{ "open-gop", no_argument, NULL, 0 },
{ "bluray-compat", no_argument, NULL, 0 },
{ "avcintra-class", required_argument, NULL, 0 },
+ { "constraint", required_argument, NULL, OPT_CONSTRAINT },
{ "min-keyint", required_argument, NULL, 'i' },
{ "keyint", required_argument, NULL, 'I' },
{ "intra-refresh", no_argument, NULL, 0 },
@@ -1353,6 +1364,7 @@ static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )
char *tcfile_name = NULL;
x264_param_t defaults;
char *profile = NULL;
+ char *constraint = NULL;
char *vid_filters = NULL;
int b_thread_input = 0;
int b_turbo = 1;
@@ -1474,6 +1486,10 @@ static int parse( int argc, char **argv, x264_param_t *param, cli_opt_t *opt )
case OPT_PROFILE:
profile = optarg;
break;
+ case OPT_CONSTRAINT:
+ constraint = optarg;
+ param->i_ex_class = 1;
+ break;
case OPT_SLOWFIRSTPASS:
b_turbo = 0;
break;
@@ -1571,7 +1587,26 @@ generic_option:
x264_param_apply_fastfirstpass( param );
/* Apply profile restrictions. */
- if( x264_param_apply_profile( param, profile ) < 0 )
+ char profiles[32];
+ memset( profiles, 0, 32 );
+ int profile_len = 0;
+ if( param->i_ex_class )
+ {
+ if( input_opt.colorspace == NULL )
+ param->i_ex_class = 420;
+ else
+ {
+ param->i_ex_class = !strcasecmp( "i420", input_opt.colorspace ) ? 420 :
+ !strcasecmp( "i422", input_opt.colorspace ) ? 422 : !strcasecmp( "i444", input_opt.colorspace ) ? 444 : 0;
+ FAIL_IF_ERROR( !param->i_ex_class, "input colorspace is not supported for avcultra or xavc.\n" )
+ }
+ memcpy( profiles, constraint, strlen( constraint ) );
+ profiles[strlen( constraint )] = '\0';
+ profile_len = strlen( constraint ) + 1;
+ }
+ profile && memcpy( profiles + profile_len, profile, strlen( profile ) );
+
+ if( x264_param_apply_profile( param, profiles ) < 0 )
return -1;
/* Get the file name */
diff --git a/x264.h b/x264.h
index 9b6d8f4..2597ce9 100644
--- a/x264.h
+++ b/x264.h
@@ -333,6 +333,7 @@ typedef struct x264_param_t
int b_open_gop;
int b_bluray_compat;
int i_avcintra_class;
+ int i_ex_class; // used for avcultra class and xavc class
int b_deblocking_filter;
int i_deblocking_filter_alphac0; /* [-6, 6] -6 light filter, 6 strong */
--
1.9.4.msysgit.2
Regards,
Xuefeng Jiang
xuefeng at multicorewareinc.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x264-devel/attachments/20150929/b8db5ef5/attachment-0001.html>
More information about the x264-devel
mailing list