diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 3b0af8a030..04f21e452b 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -417,34 +417,23 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) static guint get_max_dec_frame_buffering(GstH264SPS *sps) { - guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs; + guint max_dec_frame_buffering, PicSizeMbs; + GstVaapiLevelH264 level; + const GstVaapiH264LevelLimits *level_limits; /* Table A-1 - Level limits */ - switch (sps->level_idc) { - case 10: MaxDpbMbs = 396; break; - case 11: MaxDpbMbs = 900; break; - case 12: MaxDpbMbs = 2376; break; - case 13: MaxDpbMbs = 2376; break; - case 20: MaxDpbMbs = 2376; break; - case 21: MaxDpbMbs = 4752; break; - case 22: MaxDpbMbs = 8100; break; - case 30: MaxDpbMbs = 8100; break; - case 31: MaxDpbMbs = 18000; break; - case 32: MaxDpbMbs = 20480; break; - case 40: MaxDpbMbs = 32768; break; - case 41: MaxDpbMbs = 32768; break; - case 42: MaxDpbMbs = 34816; break; - case 50: MaxDpbMbs = 110400; break; - case 51: MaxDpbMbs = 184320; break; - default: - g_assert(0 && "unhandled level"); - break; - } + if (G_UNLIKELY(sps->level_idc == 11 && sps->constraint_set3_flag)) + level = GST_VAAPI_LEVEL_H264_L1b; + else + level = gst_vaapi_utils_h264_get_level(sps->level_idc); + level_limits = gst_vaapi_utils_h264_get_level_limits(level); + if (!level_limits) + return 16; PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) * (sps->pic_height_in_map_units_minus1 + 1) * (sps->frame_mbs_only_flag ? 1 : 2)); - max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs; + max_dec_frame_buffering = level_limits->MaxDpbMbs / PicSizeMbs; /* VUI parameters */ if (sps->vui_parameters_present_flag) { diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.c b/gst-libs/gst/vaapi/gstvaapiutils_h264.c index b6d908594e..b7d2f43196 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.c +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.c @@ -24,6 +24,31 @@ #include #include "gstvaapiutils_h264.h" +/* Table A-1 - Level limits */ +/* *INDENT-OFF* */ +static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = { + /* level idc MaxMBPS MaxFS MaxDpbMbs MaxBR */ + { GST_VAAPI_LEVEL_H264_L1, 10, 1485, 99, 396, 64 }, + { GST_VAAPI_LEVEL_H264_L1b, 11, 1485, 99, 396, 128 }, + { GST_VAAPI_LEVEL_H264_L1_1, 11, 3000, 396, 900, 192 }, + { GST_VAAPI_LEVEL_H264_L1_2, 12, 6000, 396, 2376, 384 }, + { GST_VAAPI_LEVEL_H264_L1_3, 13, 11880, 396, 2376, 768 }, + { GST_VAAPI_LEVEL_H264_L2, 20, 11880, 396, 2376, 2000 }, + { GST_VAAPI_LEVEL_H264_L2_1, 21, 19800, 792, 4752, 4000 }, + { GST_VAAPI_LEVEL_H264_L2_2, 22, 20250, 1620, 8100, 4000 }, + { GST_VAAPI_LEVEL_H264_L3, 30, 40500, 1620, 8100, 10000 }, + { GST_VAAPI_LEVEL_H264_L3_1, 31, 108000, 3600, 18000, 14000 }, + { GST_VAAPI_LEVEL_H264_L3_2, 32, 216000, 5120, 20480, 20000 }, + { GST_VAAPI_LEVEL_H264_L4, 40, 245760, 8192, 32768, 20000 }, + { GST_VAAPI_LEVEL_H264_L4_1, 41, 245760, 8192, 32768, 50000 }, + { GST_VAAPI_LEVEL_H264_L4_2, 42, 522240, 8704, 34816, 50000 }, + { GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000 }, + { GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000 }, + { GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000 }, + { 0, } +}; +/* *INDENT-ON* */ + /** Returns GstVaapiProfile from H.264 profile_idc value */ GstVaapiProfile gst_vaapi_utils_h264_get_profile (guint8 profile_idc) @@ -79,6 +104,52 @@ gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile) return profile_idc; } +/** Returns GstVaapiLevelH264 from H.264 level_idc value */ +GstVaapiLevelH264 +gst_vaapi_utils_h264_get_level (guint8 level_idc) +{ + const GstVaapiH264LevelLimits *llp; + + // Prefer Level 1.1 over level 1b + if (G_UNLIKELY (level_idc == 11)) + return GST_VAAPI_LEVEL_H264_L1_1; + + for (llp = gst_vaapi_h264_level_limits; llp->level != 0; llp++) { + if (llp->level_idc == level_idc) + return llp->level; + } + g_assert (0 && "unsupported level_idc value"); + return (GstVaapiLevelH264) 0; +} + +/** Returns H.264 level_idc value from GstVaapiLevelH264 */ +guint8 +gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level) +{ + const GstVaapiH264LevelLimits *const llp = + gst_vaapi_utils_h264_get_level_limits (level); + + return llp ? llp->level_idc : 0; +} + +/** Returns level limits as specified in Table A-1 of the H.264 standard */ +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level) +{ + if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2) + return NULL; + return &gst_vaapi_h264_level_limits[level - GST_VAAPI_LEVEL_H264_L1]; +} + +/** Returns the Table A-1 specification */ +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits_table (guint * out_length_ptr) +{ + if (out_length_ptr) + *out_length_ptr = G_N_ELEMENTS (gst_vaapi_h264_level_limits) - 1; + return gst_vaapi_h264_level_limits; +} + /** Returns GstVaapiChromaType from H.264 chroma_format_idc value */ GstVaapiChromaType gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc) diff --git a/gst-libs/gst/vaapi/gstvaapiutils_h264.h b/gst-libs/gst/vaapi/gstvaapiutils_h264.h index f1abf22452..cbd7217982 100644 --- a/gst-libs/gst/vaapi/gstvaapiutils_h264.h +++ b/gst-libs/gst/vaapi/gstvaapiutils_h264.h @@ -29,6 +29,69 @@ G_BEGIN_DECLS +/** + * GstVaapiLevelH264: + * @GST_VAAPI_LEVEL_H264_L1: H.264 level 1. + * @GST_VAAPI_LEVEL_H264_L1_1: H.264 level 1.1. + * @GST_VAAPI_LEVEL_H264_L1_2: H.264 level 1.2. + * @GST_VAAPI_LEVEL_H264_L1_3: H.264 level 1.3. + * @GST_VAAPI_LEVEL_H264_L2: H.264 level 2. + * @GST_VAAPI_LEVEL_H264_L2_1: H.264 level 2.1. + * @GST_VAAPI_LEVEL_H264_L2_2: H.264 level 2.2. + * @GST_VAAPI_LEVEL_H264_L3: H.264 level 3. + * @GST_VAAPI_LEVEL_H264_L3_1: H.264 level 3.1. + * @GST_VAAPI_LEVEL_H264_L3_2: H.264 level 3.2. + * @GST_VAAPI_LEVEL_H264_L4: H.264 level 4. + * @GST_VAAPI_LEVEL_H264_L4_1: H.264 level 4.1. + * @GST_VAAPI_LEVEL_H264_L4_2: H.264 level 4.2. + * @GST_VAAPI_LEVEL_H264_L5: H.264 level 5. + * @GST_VAAPI_LEVEL_H264_L5_1: H.264 level 5.1. + * @GST_VAAPI_LEVEL_H264_L5_2: H.264 level 5.2. + * + * The set of all levels for #GstVaapiLevelH264. + */ +typedef enum +{ + GST_VAAPI_LEVEL_H264_L1 = 1, + GST_VAAPI_LEVEL_H264_L1b, + GST_VAAPI_LEVEL_H264_L1_1, + GST_VAAPI_LEVEL_H264_L1_2, + GST_VAAPI_LEVEL_H264_L1_3, + GST_VAAPI_LEVEL_H264_L2, + GST_VAAPI_LEVEL_H264_L2_1, + GST_VAAPI_LEVEL_H264_L2_2, + GST_VAAPI_LEVEL_H264_L3, + GST_VAAPI_LEVEL_H264_L3_1, + GST_VAAPI_LEVEL_H264_L3_2, + GST_VAAPI_LEVEL_H264_L4, + GST_VAAPI_LEVEL_H264_L4_1, + GST_VAAPI_LEVEL_H264_L4_2, + GST_VAAPI_LEVEL_H264_L5, + GST_VAAPI_LEVEL_H264_L5_1, + GST_VAAPI_LEVEL_H264_L5_2, +} GstVaapiLevelH264; + +/** + * GstVaapiH264LevelLimits: + * @level: the #GstVaapiLevelH264 + * @level_idc: the H.264 level_idc value + * @MaxMBPS: the maximum macroblock processing rate (MB/sec) + * @MaxFS: the maximum frame size (MBs) + * @MaxDpbMbs: the maxium decoded picture buffer size (MBs) + * @MaxBR: the maximum video bit rate (kbps) + * + * The data structure that describes the limits of an H.264 level. + */ +typedef struct +{ + GstVaapiLevelH264 level; + guint8 level_idc; + guint32 MaxMBPS; + guint32 MaxFS; + guint32 MaxDpbMbs; + guint32 MaxBR; +} GstVaapiH264LevelLimits; + /* Returns GstVaapiProfile from H.264 profile_idc value */ G_GNUC_INTERNAL GstVaapiProfile @@ -39,6 +102,26 @@ G_GNUC_INTERNAL guint8 gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile); +/* Returns GstVaapiLevelH264 from H.264 level_idc value */ +G_GNUC_INTERNAL +GstVaapiLevelH264 +gst_vaapi_utils_h264_get_level (guint8 level_idc); + +/* Returns H.264 level_idc value from GstVaapiLevelH264 */ +G_GNUC_INTERNAL +guint8 +gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level); + +/* Returns level limits as specified in Table A-1 of the H.264 standard */ +G_GNUC_INTERNAL +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level); + +/* Returns the Table A-1 specification */ +G_GNUC_INTERNAL +const GstVaapiH264LevelLimits * +gst_vaapi_utils_h264_get_level_limits_table (guint *out_length_ptr); + /* Returns GstVaapiChromaType from H.264 chroma_format_idc value */ G_GNUC_INTERNAL GstVaapiChromaType