mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
vaapipostproc: don't use GstVideoInfo for src caps
Instead of using gst_video_info_to_caps () to generated the fixed src caps, this patch enables the first step for caps negotiation with a possible following caps filter. _get_preferred_caps() will traverse the possible src caps looking for the one wit the preferred feature and the preferred color format. Then the color format, the frame size and the frame rate are fixated. https://bugzilla.gnome.org/show_bug.cgi?id=758548
This commit is contained in:
parent
1901e2231b
commit
4d1b11ed03
1 changed files with 128 additions and 54 deletions
|
@ -24,6 +24,8 @@
|
|||
#include "gstvaapipostprocutil.h"
|
||||
#include "gstvaapipluginutil.h"
|
||||
|
||||
#define GST_CAT_DEFAULT (GST_VAAPI_PLUGIN_BASE (postproc)->debug_category)
|
||||
|
||||
/* if format property is set */
|
||||
static void
|
||||
_transform_format (GstVaapiPostproc * postproc, GstCapsFeatures * features,
|
||||
|
@ -173,6 +175,131 @@ find_best_size (GstVaapiPostproc * postproc, GstVideoInfo * vip,
|
|||
*height_ptr = height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_fixate_frame_size (GstVaapiPostproc * postproc, GstVideoInfo * vinfo,
|
||||
GstStructure * outs)
|
||||
{
|
||||
guint width, height, par_n, par_d;
|
||||
|
||||
par_n = GST_VIDEO_INFO_PAR_N (vinfo);
|
||||
par_d = GST_VIDEO_INFO_PAR_D (vinfo);
|
||||
find_best_size (postproc, vinfo, &width, &height);
|
||||
gst_structure_set (outs, "width", G_TYPE_INT, width, "height", G_TYPE_INT,
|
||||
height, "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_fixate_frame_rate (GstVaapiPostproc * postproc, GstVideoInfo * vinfo,
|
||||
GstStructure * outs)
|
||||
{
|
||||
gint fps_n, fps_d;
|
||||
|
||||
fps_n = GST_VIDEO_INFO_FPS_N (vinfo);
|
||||
fps_d = GST_VIDEO_INFO_FPS_D (vinfo);
|
||||
if (is_deinterlace_enabled (postproc, vinfo)) {
|
||||
if (!gst_util_fraction_multiply (fps_n, fps_d, 2, 1, &fps_n, &fps_d))
|
||||
goto overflow_error;
|
||||
}
|
||||
gst_structure_set (outs, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
overflow_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (postproc, CORE, NEGOTIATION, (NULL),
|
||||
("Error calculating the output framerate - integer overflow"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_preferred_format (GstStructure * outs, GstVideoFormat format)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
if (format == GST_VIDEO_FORMAT_UNKNOWN || format == GST_VIDEO_FORMAT_ENCODED)
|
||||
return FALSE;
|
||||
|
||||
if (gst_vaapi_value_set_format (&value, format)) {
|
||||
gst_structure_set_value (outs, "format", &value);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
_get_preferred_caps (GstVaapiPostproc * postproc, GstVideoInfo * vinfo,
|
||||
GstCaps * srccaps)
|
||||
{
|
||||
GstPad *srcpad;
|
||||
GstVideoFormat format;
|
||||
GstVaapiCapsFeature f;
|
||||
const gchar *feature;
|
||||
GstStructure *structure;
|
||||
GstCapsFeatures *features;
|
||||
GstCaps *outcaps;
|
||||
gint i, n;
|
||||
|
||||
format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc);
|
||||
f = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps, &format);
|
||||
if (f == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED)
|
||||
return NULL;
|
||||
|
||||
feature = gst_vaapi_caps_feature_to_string (f);
|
||||
if (!feature)
|
||||
feature = GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY;
|
||||
|
||||
n = gst_caps_get_size (srccaps);
|
||||
for (i = 0; i < n; i++) {
|
||||
structure = gst_caps_get_structure (srccaps, i);
|
||||
features = gst_caps_get_features (srccaps, i);
|
||||
|
||||
if (!gst_caps_features_is_any (features)
|
||||
&& gst_caps_features_contains (features, feature))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= n)
|
||||
goto invalid_caps;
|
||||
|
||||
/* make copy */
|
||||
structure = gst_structure_copy (structure);
|
||||
|
||||
if (!_set_preferred_format (structure, format))
|
||||
goto fixate_failed;
|
||||
if (!_fixate_frame_size (postproc, vinfo, structure))
|
||||
goto fixate_failed;
|
||||
if (!_fixate_frame_rate (postproc, vinfo, structure))
|
||||
goto fixate_failed;
|
||||
|
||||
outcaps = gst_caps_new_empty ();
|
||||
gst_caps_append_structure_full (outcaps, structure,
|
||||
gst_caps_features_copy (features));
|
||||
|
||||
/* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META
|
||||
* is negotiated */
|
||||
if (f != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META
|
||||
&& postproc->format != format)
|
||||
postproc->format = format;
|
||||
|
||||
return outcaps;
|
||||
|
||||
/* ERRORS */
|
||||
fixate_failed:
|
||||
{
|
||||
GST_WARNING_OBJECT (postproc, "Could not fixate src caps");
|
||||
gst_structure_free (structure);
|
||||
return NULL;
|
||||
}
|
||||
invalid_caps:
|
||||
{
|
||||
GST_WARNING_OBJECT (postproc, "No valid src caps found");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapipostproc_fixate_srccaps:
|
||||
* @postproc: a #GstVaapiPostproc instance
|
||||
|
@ -189,61 +316,8 @@ gst_vaapipostproc_fixate_srccaps (GstVaapiPostproc * postproc,
|
|||
GstCaps * sinkcaps, GstCaps * srccaps)
|
||||
{
|
||||
GstVideoInfo vi;
|
||||
GstVideoFormat out_format;
|
||||
GstCaps *out_caps;
|
||||
GstVaapiCapsFeature feature;
|
||||
const gchar *feature_str;
|
||||
guint width, height;
|
||||
GstPad *srcpad;
|
||||
|
||||
/* Generate the expected src pad caps, from the current fixated sink
|
||||
pad caps */
|
||||
if (!gst_video_info_from_caps (&vi, sinkcaps))
|
||||
return NULL;
|
||||
|
||||
// Set double framerate in interlaced mode
|
||||
if (is_deinterlace_enabled (postproc, &vi)) {
|
||||
gint fps_n = GST_VIDEO_INFO_FPS_N (&vi);
|
||||
gint fps_d = GST_VIDEO_INFO_FPS_D (&vi);
|
||||
if (!gst_util_fraction_multiply (fps_n, fps_d, 2, 1, &fps_n, &fps_d))
|
||||
return NULL;
|
||||
GST_VIDEO_INFO_FPS_N (&vi) = fps_n;
|
||||
GST_VIDEO_INFO_FPS_D (&vi) = fps_d;
|
||||
}
|
||||
// Signal the other pad that we only generate progressive frames
|
||||
GST_VIDEO_INFO_INTERLACE_MODE (&vi) = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
|
||||
|
||||
// Update size from user-specified parameters
|
||||
find_best_size (postproc, &vi, &width, &height);
|
||||
|
||||
// Update format from user-specified parameters
|
||||
srcpad = GST_BASE_TRANSFORM_SRC_PAD (postproc);
|
||||
feature = gst_vaapi_find_preferred_caps_feature (srcpad, srccaps,
|
||||
&out_format);
|
||||
|
||||
if (postproc->format != DEFAULT_FORMAT)
|
||||
out_format = postproc->format;
|
||||
|
||||
if (feature == GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED)
|
||||
return NULL;
|
||||
|
||||
gst_video_info_change_format (&vi, out_format, width, height);
|
||||
out_caps = gst_video_info_to_caps (&vi);
|
||||
if (!out_caps)
|
||||
return NULL;
|
||||
|
||||
if (feature) {
|
||||
feature_str = gst_vaapi_caps_feature_to_string (feature);
|
||||
if (feature_str)
|
||||
gst_caps_set_features (out_caps, 0,
|
||||
gst_caps_features_new (feature_str, NULL));
|
||||
}
|
||||
|
||||
/* we don't need to do format conversion if GL_TEXTURE_UPLOAD_META
|
||||
* is negotiated */
|
||||
if (feature != GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META &&
|
||||
postproc->format != out_format) {
|
||||
postproc->format = out_format;
|
||||
}
|
||||
return out_caps;
|
||||
return _get_preferred_caps (postproc, &vi, srccaps);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue