diff options
author | Scott D Phillips <scott.d.phillips@intel.com> | 2016-05-06 10:50:10 +0200 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <victorx.jaquez@intel.com> | 2016-05-09 16:57:02 +0200 |
commit | 4d1b11ed03759ef702c675cbacdb5ea543daa305 (patch) | |
tree | 0315b400542812632c7aa018824cc6a9dcb9d303 /gst/vaapi/gstvaapipostprocutil.c | |
parent | 1901e2231be53c23936d9a236c34c0812a0cfbdb (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.c | 182 |
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); } |