diff options
author | He Junyan <junyan.he@hotmail.com> | 2019-04-09 20:42:04 +0800 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2019-04-10 15:28:46 +0000 |
commit | 58e74f9440fed4031394be2de6c64d593546716b (patch) | |
tree | eef3d8dae49a9456d46d6706ac481c1e5f17ee19 | |
parent | 5b1fe9c68afcdd956dea6c43db529eb546cc1eb3 (diff) |
libs: encoder: h265: Recognize the correct level and tier.
The current manner can not recognize the correct level and always
set the tier to main. Need to add frame rate check to recognize
levels such as 4.1, 6.2, etc. We also add a logic to check main
and high tier based on bitrate.
Fixes: #145
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiencoder_h265.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c index 4290ad37..52d74f5a 100644 --- a/gst-libs/gst/vaapi/gstvaapiencoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapiencoder_h265.c @@ -998,38 +998,46 @@ ensure_profile (GstVaapiEncoderH265 * encoder) return TRUE; } -/* Derives the minimum tier from the active coding tools */ +/* Derives the level and tier from the currently set limits */ static gboolean -ensure_tier (GstVaapiEncoderH265 * encoder) +ensure_tier_level (GstVaapiEncoderH265 * encoder) { - - encoder->tier = GST_VAAPI_TIER_H265_MAIN; - /* FIXME: Derive proper tier based on upstream caps or limits, coding - * tools etc */ - - return TRUE; -} - -/* Derives the level from the currently set limits */ -static gboolean -ensure_level (GstVaapiEncoderH265 * encoder) -{ - const GstVaapiH265LevelLimits *limits_table; + guint bitrate = GST_VAAPI_ENCODER_CAST (encoder)->bitrate; guint i, num_limits, PicSizeInSamplesY; + guint LumaSr; + const GstVaapiH265LevelLimits *limits_table; PicSizeInSamplesY = encoder->luma_width * encoder->luma_height; + LumaSr = + gst_util_uint64_scale (PicSizeInSamplesY, + GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)); limits_table = gst_vaapi_utils_h265_get_level_limits_table (&num_limits); for (i = 0; i < num_limits; i++) { const GstVaapiH265LevelLimits *const limits = &limits_table[i]; - if (PicSizeInSamplesY <= limits->MaxLumaPs) + /* Choose level by luma picture size and luma sample rate */ + if (PicSizeInSamplesY <= limits->MaxLumaPs && LumaSr <= limits->MaxLumaSr) break; - /* FIXME: Add more constraint checking:tier (extracted from caps), - * cpb size, bitrate, num_tile_columns and num_tile_rows */ } + if (i == num_limits) goto error_unsupported_level; + if (bitrate <= limits_table[i].MaxBRTierMain) { + encoder->tier = GST_VAAPI_TIER_H265_MAIN; + } else { + encoder->tier = GST_VAAPI_TIER_H265_HIGH; + if (bitrate > limits_table[i].MaxBRTierHigh) { + GST_INFO ("The bitrate of the stream is %d kbps, larger than" + " %s profile %s level %s tier's max bit rate %d kbps", + bitrate, + gst_vaapi_utils_h265_get_profile_string (encoder->profile), + gst_vaapi_utils_h265_get_level_string (limits_table[i].level), + gst_vaapi_utils_h265_get_tier_string (GST_VAAPI_TIER_H265_HIGH), + limits_table[i].MaxBRTierHigh); + } + } + encoder->level = limits_table[i].level; encoder->level_idc = limits_table[i].level_idc; return TRUE; @@ -1042,6 +1050,7 @@ error_unsupported_level: } } +/* Derives the minimum tier from the active coding tools */ /* Enable "high-compression" tuning options */ static gboolean ensure_tuning_high_compression (GstVaapiEncoderH265 * encoder) @@ -2024,14 +2033,10 @@ ensure_profile_tier_level (GstVaapiEncoderH265 * encoder) if (encoder->profile_idc > encoder->hw_max_profile_idc) return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE; - /* ensure tier */ - if (!ensure_tier (encoder)) - return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; - /* Ensure bitrate if not set already and derive the right level to use */ ensure_bitrate (encoder); - if (!ensure_level (encoder)) + if (!ensure_tier_level (encoder)) return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED; if (encoder->profile != profile || encoder->level != level |