summaryrefslogtreecommitdiff
path: root/gst/vaapi/gstvaapipostprocutil.c
diff options
context:
space:
mode:
authorScott D Phillips <scott.d.phillips@intel.com>2016-05-06 10:50:10 +0200
committerVíctor Manuel Jáquez Leal <victorx.jaquez@intel.com>2016-05-09 16:57:02 +0200
commit4d1b11ed03759ef702c675cbacdb5ea543daa305 (patch)
tree0315b400542812632c7aa018824cc6a9dcb9d303 /gst/vaapi/gstvaapipostprocutil.c
parent1901e2231be53c23936d9a236c34c0812a0cfbdb (diff)
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
Diffstat (limited to 'gst/vaapi/gstvaapipostprocutil.c')
-rw-r--r--gst/vaapi/gstvaapipostprocutil.c182
1 files changed, 128 insertions, 54 deletions
diff --git a/gst/vaapi/gstvaapipostprocutil.c b/gst/vaapi/gstvaapipostprocutil.c
index 93588003..ff114a15 100644
--- a/gst/vaapi/gstvaapipostprocutil.c
+++ b/gst/vaapi/gstvaapipostprocutil.c
@@ -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);
}