/**
* gst_vaapi_encoder_get_surface_attributres:
* @encoder: a #GstVaapiEncoder instances
- * @profile: a #GstVaapiProfile to test
+ * @profiles: a #GArray of #GstVaapiProfile to be test
* @min_width (out): the minimal surface width
* @min_height (out): the minimal surface height
* @max_width (out): the maximal surface width
* @max_height (out): the maximal surface height
*
- * Fetches the valid surface's attributes for @profile if it is valid,
- * Otherwise, it collects surface's attributes for all profiles which
- * belong to the current encoder's codec.
+ * Fetches the valid surface's attributes for the specified @profiles
*
* Returns: a #GArray of valid formats we get or %NULL if failed.
**/
GArray *
gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder,
- GstVaapiProfile profile, gint * min_width, gint * min_height,
+ GArray * profiles, gint * min_width, gint * min_height,
gint * max_width, gint * max_height)
{
- const GstVaapiEncoderClassData *const cdata =
- GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data;
GstVaapiConfigSurfaceAttributes attribs = {
G_MAXINT, G_MAXINT, 1, 1, 0, NULL
};
- GArray *profiles;
+ GstVaapiProfile profile;
guint i;
- if (profile != GST_VAAPI_PROFILE_UNKNOWN) {
- if (get_profile_surface_attributes (encoder, profile, &attribs))
- goto success;
- return NULL;
- }
-
- /* no specific context neither specific profile, let's iterate among
- * the codec's profiles */
- profiles = gst_vaapi_display_get_encode_profiles (encoder->display);
- if (!profiles)
- return NULL;
-
attribs.formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
for (i = 0; i < profiles->len; i++) {
profile = g_array_index (profiles, GstVaapiProfile, i);
- if (gst_vaapi_profile_get_codec (profile) == cdata->codec) {
- if (!merge_profile_surface_attributes (encoder, profile, &attribs)) {
- GST_INFO ("Can not get surface formats for profile %s",
- gst_vaapi_profile_get_va_name (profile));
- continue;
- }
+ g_assert (profile != GST_VAAPI_PROFILE_UNKNOWN);
+ GST_LOG ("Detect input formats of profile %s",
+ gst_vaapi_profile_get_va_name (profile));
+
+ if (!merge_profile_surface_attributes (encoder, profile, &attribs)) {
+ GST_INFO ("Can not get surface formats for profile %s",
+ gst_vaapi_profile_get_va_name (profile));
+ continue;
}
}
- g_array_unref (profiles);
-
if (!attribs.formats)
return NULL;
-success:
if (min_width)
*min_width = attribs.min_width;
if (min_height)
GArray *
gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder,
- GstVaapiProfile profile, gint * min_width, gint * min_height,
+ GArray * profiles, gint * min_width, gint * min_height,
gint * max_width, gint * max_height);
GstVaapiProfile
gst_pad_pause_task (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode));
}
-static GstVaapiProfile
-get_profile (GstVaapiEncode * encode)
+static GArray *
+get_profiles (GstVaapiEncode * encode)
{
GstVaapiEncodeClass *klass = GST_VAAPIENCODE_GET_CLASS (encode);
+ GArray *profiles = NULL;
- if (klass->get_profile) {
- GstVaapiProfile profile = GST_VAAPI_PROFILE_UNKNOWN;
+ if (klass->get_allowed_profiles) {
GstCaps *allowed =
gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode));
+ GST_LOG_OBJECT (encode,
+ "Get allowed sink caps from downstream %" GST_PTR_FORMAT, allowed);
+ if (allowed && !gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed))
+ profiles = klass->get_allowed_profiles (encode, allowed);
- if (allowed) {
- if (!gst_caps_is_empty (allowed) && !gst_caps_is_any (allowed))
- profile = klass->get_profile (allowed);
+ if (allowed)
gst_caps_unref (allowed);
- }
- if (profile != GST_VAAPI_PROFILE_UNKNOWN)
- return profile;
+ if (profiles)
+ return profiles;
}
- if (encode->encoder)
- return gst_vaapi_encoder_get_profile (encode->encoder);
-
- return GST_VAAPI_PROFILE_UNKNOWN;
+ profiles = gst_vaapi_encoder_get_available_profiles (encode->encoder);
+ return profiles;
}
static gboolean
GstCaps *va_caps, *dma_caps;
GArray *formats = NULL;
gboolean ret = FALSE;
- GstVaapiProfile profile;
+ GArray *profiles = NULL;
guint i, size;
GstStructure *structure;
gint min_width, min_height, max_width, max_height;
if (!encode->encoder)
return TRUE;
- profile = get_profile (encode);
+ /* First, get all possible profiles. */
+ profiles = get_profiles (encode);
+ if (profiles == NULL)
+ goto failed_get_profiles;
- /* First get all supported formats, all these formats should be recognized
+ /* Then get all supported formats, all these formats should be recognized
in video-format map. */
- formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profile,
+ formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profiles,
&min_width, &min_height, &max_width, &max_height);
if (!formats)
goto failed_get_attributes;
if (!encode->allowed_sinkpad_caps)
encode->allowed_sinkpad_caps = gst_caps_new_empty ();
+ if (profiles)
+ g_array_unref (profiles);
if (out_caps)
gst_caps_unref (out_caps);
if (raw_caps)
GST_WARNING_OBJECT (encode, "failed to create raw sink caps");
goto bail;
}
+failed_get_profiles:
+ {
+ GST_WARNING_OBJECT (encode, "failed to get supported profiles");
+ goto bail;
+ }
}
static GstCaps *
GstFlowReturn (*alloc_buffer) (GstVaapiEncode * encode,
GstVaapiCodedBuffer * coded_buf,
GstBuffer ** outbuf_ptr);
- GstVaapiProfile (*get_profile) (GstCaps * caps);
+ /* Get all possible profiles based on allowed caps */
+ GArray * (*get_allowed_profiles) (GstVaapiEncode * encode,
+ GstCaps * allowed);
#if USE_H264_FEI_ENCODER
G_OBJECT_CLASS (gst_vaapiencode_h264_parent_class)->finalize (object);
}
-static GstVaapiProfile
-gst_vaapiencode_h264_get_profile (GstCaps * caps)
+static GArray *
+gst_vaapiencode_h264_get_allowed_profiles (GstVaapiEncode * encode,
+ GstCaps * allowed)
{
- guint i;
-
- for (i = 0; i < gst_caps_get_size (caps); i++) {
- GstStructure *const structure = gst_caps_get_structure (caps, i);
- const GValue *const value = gst_structure_get_value (structure, "profile");
-
- if (value && G_VALUE_HOLDS_STRING (value)) {
- const gchar *str = g_value_get_string (value);
- if (str)
- return gst_vaapi_utils_h264_get_profile_from_string (str);
- }
- }
-
- return GST_VAAPI_PROFILE_UNKNOWN;
+ return gst_vaapi_h26x_encoder_get_profiles_from_caps (allowed,
+ gst_vaapi_utils_h264_get_profile_from_string);
}
typedef struct
object_class->set_property = gst_vaapiencode_set_property_subclass;
object_class->get_property = gst_vaapiencode_get_property_subclass;
- encode_class->get_profile = gst_vaapiencode_h264_get_profile;
+ encode_class->get_allowed_profiles =
+ gst_vaapiencode_h264_get_allowed_profiles;
encode_class->set_config = gst_vaapiencode_h264_set_config;
encode_class->get_caps = gst_vaapiencode_h264_get_caps;
encode_class->alloc_encoder = gst_vaapiencode_h264_alloc_encoder;
G_OBJECT_CLASS (gst_vaapiencode_h265_parent_class)->finalize (object);
}
-static GstVaapiProfile
-gst_vaapiencode_h265_get_profile (GstCaps * caps)
+static GArray *
+gst_vaapiencode_h265_get_allowed_profiles (GstVaapiEncode * encode,
+ GstCaps * allowed)
{
- guint i;
-
- for (i = 0; i < gst_caps_get_size (caps); i++) {
- GstStructure *const structure = gst_caps_get_structure (caps, i);
- const GValue *const value = gst_structure_get_value (structure, "profile");
-
- if (value && G_VALUE_HOLDS_STRING (value)) {
- const gchar *str = g_value_get_string (value);
- if (str)
- return gst_vaapi_utils_h265_get_profile_from_string (str);
- }
- }
-
- return GST_VAAPI_PROFILE_UNKNOWN;
+ return gst_vaapi_h26x_encoder_get_profiles_from_caps (allowed,
+ gst_vaapi_utils_h265_get_profile_from_string);
}
typedef struct
object_class->set_property = gst_vaapiencode_set_property_subclass;
object_class->get_property = gst_vaapiencode_get_property_subclass;
- encode_class->get_profile = gst_vaapiencode_h265_get_profile;
+ encode_class->get_allowed_profiles =
+ gst_vaapiencode_h265_get_allowed_profiles;
encode_class->set_config = gst_vaapiencode_h265_set_config;
encode_class->get_caps = gst_vaapiencode_h265_get_caps;
encode_class->alloc_encoder = gst_vaapiencode_h265_alloc_encoder;