GstVaapiContextInfo cip = { 0, };
GstVaapiContext *ctxt;
- if (encoder->context)
- return gst_vaapi_context_ref (encoder->context);
-
- /* if there is no profile, let's figure out one */
- if (profile == GST_VAAPI_PROFILE_UNKNOWN)
- profile = get_profile (encoder);
+ g_assert (profile != GST_VAAPI_PROFILE_UNKNOWN);
cip.profile = profile;
cip.entrypoint = gst_vaapi_encoder_get_entrypoint (encoder, profile);
return ctxt;
}
-static GArray *
-get_profile_surface_formats (GstVaapiEncoder * encoder, GstVaapiProfile profile)
+static gboolean
+get_profile_surface_attributes (GstVaapiEncoder * encoder,
+ GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs)
{
- GstVaapiContext *ctxt;
- GArray *formats;
+ GstVaapiContext *ctxt = NULL;
+ gboolean ret;
+
+ g_return_val_if_fail (attribs != NULL, FALSE);
+ g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
ctxt = create_test_context_config (encoder, profile);
if (!ctxt)
- return NULL;
- formats = gst_vaapi_context_get_surface_formats (ctxt);
+ return FALSE;
+
+ ret = gst_vaapi_context_get_surface_attributes (ctxt, attribs);
+ if (ret)
+ attribs->formats = gst_vaapi_context_get_surface_formats (ctxt);
+
gst_vaapi_context_unref (ctxt);
- return formats;
+ return ret;
}
static gboolean
-merge_profile_surface_formats (GstVaapiEncoder * encoder,
- GstVaapiProfile profile, GArray * formats)
+merge_profile_surface_attributes (GstVaapiEncoder * encoder,
+ GstVaapiProfile profile, GstVaapiConfigSurfaceAttributes * attribs)
{
- GArray *surface_fmts;
+ GstVaapiConfigSurfaceAttributes attr = { 0, };
guint i, j;
GstVideoFormat fmt, sfmt;
if (profile == GST_VAAPI_PROFILE_UNKNOWN)
return FALSE;
- surface_fmts = get_profile_surface_formats (encoder, profile);
- if (!surface_fmts)
+ if (!get_profile_surface_attributes (encoder, profile, &attr))
return FALSE;
- for (i = 0; i < surface_fmts->len; i++) {
- sfmt = g_array_index (surface_fmts, GstVideoFormat, i);
- for (j = 0; j < formats->len; j++) {
- fmt = g_array_index (formats, GstVideoFormat, j);
+ for (i = 0; i < attr.formats->len; i++) {
+ sfmt = g_array_index (attr.formats, GstVideoFormat, i);
+ for (j = 0; j < attribs->formats->len; j++) {
+ fmt = g_array_index (attribs->formats, GstVideoFormat, j);
if (fmt == sfmt)
break;
}
- if (j >= formats->len)
- g_array_append_val (formats, sfmt);
+ if (j >= attribs->formats->len)
+ g_array_append_val (attribs->formats, sfmt);
}
- g_array_unref (surface_fmts);
+ g_array_unref (attr.formats);
+
+ attribs->min_width = MIN (attribs->min_width, attr.min_width);
+ attribs->min_height = MIN (attribs->min_height, attr.min_height);
+ attribs->max_width = MAX (attribs->max_width, attr.max_width);
+ attribs->max_height = MAX (attribs->max_height, attr.max_height);
+
return TRUE;
}
/**
- * gst_vaapi_encoder_get_surface_formats:
+ * gst_vaapi_encoder_get_surface_attributres:
* @encoder: a #GstVaapiEncoder instances
+ * @profile: a #GstVaapiProfile to 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 formats for the current VAConfig
+ * 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.
*
- * Returns: a #GArray of valid formats for the current VAConfig
+ * Returns: a #GArray of valid formats we get or %NULL if failed.
**/
GArray *
-gst_vaapi_encoder_get_surface_formats (GstVaapiEncoder * encoder,
- GstVaapiProfile profile)
+gst_vaapi_encoder_get_surface_attributes (GstVaapiEncoder * encoder,
+ GstVaapiProfile profile, gint * min_width, gint * min_height,
+ gint * max_width, gint * max_height)
{
const GstVaapiEncoderClassData *const cdata =
GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data;
- GArray *profiles, *formats;
+ GstVaapiConfigSurfaceAttributes attribs = {
+ G_MAXINT, G_MAXINT, 1, 1, 0, NULL
+ };
+ GArray *profiles;
guint i;
- if (profile || encoder->context)
- return get_profile_surface_formats (encoder, profile);
+ 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 */
if (!profiles)
return NULL;
- formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
+ 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_formats (encoder, profile, formats)) {
- g_array_unref (formats);
- formats = NULL;
- break;
+ 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);
- return formats;
+ if (!attribs.formats)
+ return NULL;
+
+success:
+ if (min_width)
+ *min_width = attribs.min_width;
+ if (min_height)
+ *min_height = attribs.min_height;
+ if (max_width)
+ *max_width = attribs.max_width;
+ if (max_height)
+ *max_height = attribs.max_height;
+ return attribs.formats;
}
/**
return GST_VAAPI_PROFILE_UNKNOWN;
}
-static GstVaapiEntrypoint
-get_entrypoint (GstVaapiEncode * encode, GstVaapiProfile profile)
-{
- GstVaapiEncoderTune tune = GST_VAAPI_ENCODER_TUNE_NONE;
-
- g_object_get (encode, "tune", &tune, NULL);
- if (tune == GST_VAAPI_ENCODER_TUNE_LOW_POWER)
- return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
- if (profile == GST_VAAPI_PROFILE_JPEG_BASELINE)
- return GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE;
- return GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
-}
-
static gboolean
ensure_allowed_sinkpad_caps (GstVaapiEncode * encode)
{
GstVaapiProfile profile;
guint i, size;
GstStructure *structure;
+ gint min_width, min_height, max_width, max_height;
if (encode->allowed_sinkpad_caps)
return TRUE;
return TRUE;
profile = get_profile (encode);
- if (profile == GST_VAAPI_PROFILE_UNKNOWN)
- return TRUE;
/* First get all supported formats, all these formats should be recognized
in video-format map. */
- formats = gst_vaapi_encoder_get_surface_formats (encode->encoder, profile);
+ formats = gst_vaapi_encoder_get_surface_attributes (encode->encoder, profile,
+ &min_width, &min_height, &max_width, &max_height);
if (!formats)
- goto failed_get_formats;
+ goto failed_get_attributes;
raw_caps = gst_vaapi_video_format_new_template_caps_from_list (formats);
if (!raw_caps)
goto failed_create_raw_caps;
+ /* Set the width/height info to caps */
+ size = gst_caps_get_size (raw_caps);
+ for (i = 0; i < size; i++) {
+ structure = gst_caps_get_structure (raw_caps, i);
+ if (!structure)
+ continue;
+ gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, min_width,
+ max_width, "height", GST_TYPE_INT_RANGE, min_height, max_height, NULL);
+ }
+
va_caps = gst_caps_copy (raw_caps);
gst_caps_set_features_simple (va_caps,
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE));
gst_caps_append (out_caps, va_caps);
gst_caps_append (out_caps, dma_caps);
- /* Last, set the width/height info to caps */
- size = gst_caps_get_size (out_caps);
- for (i = 0; i < size; i++) {
- structure = gst_caps_get_structure (out_caps, i);
- if (!structure)
- continue;
- gst_vaapi_profile_caps_append_encoder (GST_VAAPI_PLUGIN_BASE_DISPLAY
- (encode), profile, get_entrypoint (encode, profile), structure);
- }
-
gst_caps_replace (&encode->allowed_sinkpad_caps, out_caps);
GST_INFO_OBJECT (encode, "Allowed sink caps %" GST_PTR_FORMAT,
encode->allowed_sinkpad_caps);
g_array_unref (formats);
return ret;
-failed_get_formats:
+failed_get_attributes:
{
- GST_WARNING_OBJECT (encode, "failed to get allowed surface formats");
+ GST_WARNING_OBJECT (encode, "failed to get surface attributes");
goto bail;
}
failed_create_raw_caps: