+
+ if( PARAM_INTERLACED )
+ h->param.b_pic_struct = 1;
+
+ if( h->param.i_avcintra_class )
+ {
+ 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, "10-bit x264 is required to encode AVC-Intra\n" );
+ return -1;
+ }
+
+ int type = h->param.i_avcintra_class == 200 ? 2 :
+ h->param.i_avcintra_class == 100 ? 1 :
+ h->param.i_avcintra_class == 50 ? 0 : -1;
+ if( type < 0 )
+ {
+ x264_log( h, X264_LOG_ERROR, "Invalid AVC-Intra class\n" );
+ return -1;
+ }
+
+ /* [50/100/200][res][fps] */
+ static const struct
+ {
+ uint16_t fps_num;
+ uint16_t fps_den;
+ uint8_t interlaced;
+ uint16_t frame_size;
+ const uint8_t *cqm_4ic;
+ const uint8_t *cqm_8iy;
+ } avcintra_lut[3][2][7] =
+ {
+ {{{ 60000, 1001, 0, 912, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 50, 1, 0, 1100, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 30000, 1001, 0, 912, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 25, 1, 0, 1100, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 24000, 1001, 0, 912, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy }},
+ {{ 30000, 1001, 1, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_1080i_8iy },
+ { 25, 1, 1, 2196, x264_cqm_avci50_4ic, x264_cqm_avci50_1080i_8iy },
+ { 60000, 1001, 0, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 30000, 1001, 0, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 50, 1, 0, 2196, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 25, 1, 0, 2196, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },
+ { 24000, 1001, 0, 1820, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy }}},
+ {{{ 60000, 1001, 0, 1848, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy },
+ { 50, 1, 0, 2224, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy },
+ { 30000, 1001, 0, 1848, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy },
+ { 25, 1, 0, 2224, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy },
+ { 24000, 1001, 0, 1848, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy }},
+ {{ 30000, 1001, 1, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },
+ { 25, 1, 1, 4444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },
+ { 60000, 1001, 0, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 30000, 1001, 0, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 50, 1, 0, 4444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 25, 1, 0, 4444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 24000, 1001, 0, 3692, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}},
+ {{{ 60000, 1001, 0, 3724, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy },
+ { 50, 1, 0, 4472, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy }},
+ {{ 30000, 1001, 1, 7444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },
+ { 25, 1, 1, 8940, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },
+ { 60000, 1001, 0, 7444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 30000, 1001, 0, 7444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 50, 1, 0, 8940, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 25, 1, 0, 8940, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },
+ { 24000, 1001, 0, 7444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}}
+ };
+
+ int res = -1;
+ if( i_csp >= X264_CSP_I420 && i_csp < X264_CSP_I422 && !type )
+ {
+ if( h->param.i_width == 1440 && h->param.i_height == 1080 ) res = 1;
+ else if( h->param.i_width == 960 && h->param.i_height == 720 ) res = 0;
+ }
+ else if( i_csp >= X264_CSP_I422 && i_csp < X264_CSP_I444 && type )
+ {
+ if( h->param.i_width == 1920 && h->param.i_height == 1080 ) res = 1;
+ else if( h->param.i_width == 1280 && h->param.i_height == 720 ) res = 0;
+ }
+ else
+ {
+ x264_log( h, X264_LOG_ERROR, "Invalid colorspace for AVC-Intra %d\n", h->param.i_avcintra_class );
+ return -1;
+ }
+
+ if( res < 0 )
+ {
+ x264_log( h, X264_LOG_ERROR, "Resolution %dx%d invalid for AVC-Intra %d\n",
+ h->param.i_width, h->param.i_height, h->param.i_avcintra_class );
+ return -1;
+ }
+
+ if( h->param.nalu_process )
+ {
+ x264_log( h, X264_LOG_ERROR, "nalu_process is not supported in AVC-Intra mode\n" );
+ return -1;
+ }
+
+ if( !h->param.b_repeat_headers )
+ {
+ x264_log( h, X264_LOG_ERROR, "Separate headers not supported in AVC-Intra mode\n" );
+ return -1;
+ }
+
+ int i;
+ uint32_t fps_num = h->param.i_fps_num, fps_den = h->param.i_fps_den;
+ x264_reduce_fraction( &fps_num, &fps_den );
+ for( i = 0; i < 7; i++ )
+ {
+ if( avcintra_lut[type][res][i].fps_num == fps_num &&
+ avcintra_lut[type][res][i].fps_den == fps_den &&
+ avcintra_lut[type][res][i].interlaced == PARAM_INTERLACED )
+ {
+ break;
+ }
+ }
+ if( i == 7 )
+ {
+ x264_log( h, X264_LOG_ERROR, "FPS %d/%d%c not compatible with AVC-Intra\n",
+ h->param.i_fps_num, h->param.i_fps_den, PARAM_INTERLACED ? 'i' : 'p' );
+ return -1;
+ }
+
+ h->param.i_keyint_max = 1;
+ h->param.b_intra_refresh = 0;
+ h->param.analyse.i_weighted_pred = 0;
+ h->param.i_frame_reference = 1;
+ h->param.i_dpb_size = 1;
+
+ h->param.b_bluray_compat = 0;
+ h->param.b_vfr_input = 0;
+ h->param.b_aud = 1;
+ h->param.vui.i_chroma_loc = 0;
+ h->param.i_nal_hrd = X264_NAL_HRD_NONE;
+ h->param.b_deblocking_filter = 0;
+ h->param.b_stitchable = 1;
+ h->param.b_pic_struct = 0;
+ h->param.analyse.b_transform_8x8 = 1;
+ h->param.analyse.intra = X264_ANALYSE_I8x8;
+ h->param.analyse.i_chroma_qp_offset = res && type ? 3 : 4;
+ h->param.b_cabac = !type;
+ h->param.rc.i_vbv_buffer_size = avcintra_lut[type][res][i].frame_size;
+ h->param.rc.i_vbv_max_bitrate =
+ h->param.rc.i_bitrate = h->param.rc.i_vbv_buffer_size * fps_num / fps_den;
+ h->param.rc.i_rc_method = X264_RC_ABR;
+ h->param.rc.f_vbv_buffer_init = 1.0;
+ h->param.rc.b_filler = 1;
+ h->param.i_cqm_preset = X264_CQM_CUSTOM;
+ memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof(h->param.cqm_4iy) );
+ memcpy( h->param.cqm_4ic, avcintra_lut[type][res][i].cqm_4ic, sizeof(h->param.cqm_4ic) );
+ memcpy( h->param.cqm_8iy, avcintra_lut[type][res][i].cqm_8iy, sizeof(h->param.cqm_8iy) );
+
+ /* Need exactly 10 slices of equal MB count... why? $deity knows... */
+ h->param.i_slice_max_mbs = ((h->param.i_width + 15) / 16) * ((h->param.i_height + 15) / 16) / 10;
+ h->param.i_slice_max_size = 0;
+ /* The slice structure only allows a maximum of 2 threads for 1080i/p
+ * and 1 or 5 threads for 720p */
+ if( h->param.b_sliced_threads )
+ {
+ if( res )
+ h->param.i_threads = X264_MIN( 2, h->param.i_threads );
+ else
+ {
+ h->param.i_threads = X264_MIN( 5, h->param.i_threads );
+ if( h->param.i_threads < 5 )
+ h->param.i_threads = 1;
+ }
+ }
+
+ if( type )
+ h->param.vui.i_sar_width = h->param.vui.i_sar_height = 1;
+ else
+ {
+ h->param.vui.i_sar_width = 4;
+ h->param.vui.i_sar_height = 3;
+ }
+
+ /* Official encoder doesn't appear to go under 13
+ * and Avid cannot handle negative QPs */
+ h->param.rc.i_qp_min = X264_MAX( h->param.rc.i_qp_min, QP_BD_OFFSET + 1 );
+ }
+