#define NAL_REF_IDC_MEDIUM 2
#define NAL_REF_IDC_HIGH 3
+#define GST_VAAPI_H264_MAX_REFERENCE_NUM 2
typedef enum {
NAL_UNKNOWN = 0,
return priv->avc_flag;
}
+static void
+_ensure_level(GstVaapiEncoderH264* encoder)
+{
+ guint pic_mb_size;
+ guint MaxDpbMbs, MaxMBPS;
+ guint dbp_level, mbps_level;
+
+ if (encoder->level) {
+ if (encoder->level < H264_LEVEL_10)
+ encoder->level = H264_LEVEL_10;
+ else if (encoder->level > H264_LEVEL_51)
+ encoder->level = H264_LEVEL_51;
+ return;
+ }
+
+ /* calculate level */
+ pic_mb_size = ((ENCODER_WIDTH(encoder)+15)/16) *
+ ((ENCODER_HEIGHT(encoder)+15)/16);
+ MaxDpbMbs = pic_mb_size * GST_VAAPI_H264_MAX_REFERENCE_NUM;
+ MaxMBPS = pic_mb_size * ENCODER_FPS(encoder);
+
+ /* calculate from MaxDbpMbs */
+ if (MaxDpbMbs > 110400)
+ dbp_level = H264_LEVEL_51;
+ else if (MaxDpbMbs > 34816)
+ dbp_level = H264_LEVEL_50;
+ else if (MaxDpbMbs > 32768)
+ dbp_level = H264_LEVEL_42;
+ else if (MaxDpbMbs > 20480) /* 41 or 40 */
+ dbp_level = H264_LEVEL_41;
+ else if (MaxDpbMbs > 18000)
+ dbp_level = H264_LEVEL_32;
+ else if (MaxDpbMbs > 8100)
+ dbp_level = H264_LEVEL_31;
+ else if (MaxDpbMbs > 4752) /* 30 or 22 */
+ dbp_level = H264_LEVEL_30;
+ else if (MaxDpbMbs > 2376)
+ dbp_level = H264_LEVEL_21;
+ else if (MaxDpbMbs > 900) /* 20, 13, 12 */
+ dbp_level = H264_LEVEL_20;
+ else if (MaxDpbMbs > 396)
+ dbp_level = H264_LEVEL_11;
+ else
+ dbp_level = H264_LEVEL_10;
+
+ /* calculate from Max Mb processing rate */
+ if (MaxMBPS > 589824)
+ mbps_level = H264_LEVEL_51;
+ else if (MaxMBPS > 522240)
+ mbps_level = H264_LEVEL_50;
+ else if (MaxMBPS > 245760)
+ mbps_level = H264_LEVEL_42;
+ else if (MaxMBPS > 216000) /* 40 or 41 */
+ mbps_level = H264_LEVEL_41;
+ else if (MaxMBPS > 108000)
+ mbps_level = H264_LEVEL_32;
+ else if (MaxMBPS > 40500)
+ mbps_level = H264_LEVEL_31;
+ else if (MaxMBPS > 20250)
+ mbps_level = H264_LEVEL_30;
+ else if (MaxMBPS > 19800)
+ mbps_level = H264_LEVEL_22;
+ else if (MaxMBPS > 11800)
+ mbps_level = H264_LEVEL_21;
+ else if (MaxMBPS > 6000) /*13 or 20 */
+ mbps_level = H264_LEVEL_20;
+ else if (MaxMBPS > 3000)
+ mbps_level = H264_LEVEL_12;
+ else if (MaxMBPS > 1485)
+ mbps_level = H264_LEVEL_11;
+ else
+ mbps_level = H264_LEVEL_10;
+
+ encoder->level = (dbp_level > mbps_level ? dbp_level : mbps_level);
+}
+
gboolean
gst_vaapi_encoder_h264_validate_attributes(GstVaapiBaseEncoder *base)
{
encoder->profile = H264_DEFAULT_PROFILE;
}
gst_vaapi_base_encoder_set_va_profile(base, h264_get_va_profile(encoder->profile));
- if (!encoder->level) {
- if (encoder->profile <= H264_PROFILE_BASELINE)
- encoder->level = H264_LEVEL_31;
- else
- encoder->level = H264_LEVEL_41;
- }
+
+ _ensure_level(encoder);
+
if (!encoder->intra_period) {
encoder->intra_period = H264_DEFAULT_INTRA_PERIOD;
}
#else /* extended libva, new parameter structures*/
+static guint
+_get_log2_max_frame_num_minus4(guint num)
+{
+ guint ret = 0;
+
+ while (num) {
+ ++ret;
+ num >>= 1;
+ }
+ if (ret <= 4)
+ ret = 4;
+ else if (ret > 9)
+ ret = 9;
+ return (ret -4);
+}
+
static gboolean
set_sequence_parameters(
GstVaapiEncoderH264 *encoder,
else
seq_param->bits_per_second = 0;
- seq_param->max_num_ref_frames =
- (encoder->b_frame_num < 2 ? 3 : encoder->b_frame_num+1); // ?, why 4
+ seq_param->max_num_ref_frames = GST_VAAPI_H264_MAX_REFERENCE_NUM;
seq_param->picture_width_in_mbs = width_in_mbs;
seq_param->picture_height_in_mbs = height_in_mbs;
seq_param->seq_fields.bits.seq_scaling_matrix_present_flag = FALSE;
/* direct_8x8_inference_flag default false */
seq_param->seq_fields.bits.direct_8x8_inference_flag = FALSE;
- seq_param->seq_fields.bits.log2_max_frame_num_minus4 = 4; // log2(seq.intra_period)-3 : 0
+ seq_param->seq_fields.bits.log2_max_frame_num_minus4
+ = _get_log2_max_frame_num_minus4(encoder->intra_period);
/* picture order count */
seq_param->seq_fields.bits.pic_order_cnt_type = 0;
seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
- seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 2;
+ seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 1;
seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
priv->max_frame_num =