glstereomix: Fix caps negotiation
authorJan Schmidt <jan@centricular.com>
Thu, 25 Aug 2016 14:29:34 +0000 (00:29 +1000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:32:22 +0000 (19:32 +0000)
The videoaggregator negotiation sequence changed some time
back and broke glstereomix. Instead of doing nego incorrectly
in the find_best_format() vfunc, do it directly in the
update_caps() method.

ext/gl/gstglstereomix.c
ext/gl/gstglstereomix.h

index 663c1b7..1c214d8 100644 (file)
@@ -106,11 +106,6 @@ static gboolean gst_gl_stereo_mix_start (GstAggregator * agg);
 static gboolean gst_gl_stereo_mix_src_query (GstAggregator * agg,
     GstQuery * query);
 
-static void
-gst_gl_stereo_mix_find_best_format (GstVideoAggregator * vagg,
-    GstCaps * downstream_caps, GstVideoInfo * best_info,
-    gboolean * at_least_one_alpha);
-
 static void gst_gl_stereo_mix_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_gl_stereo_mix_get_property (GObject * object, guint prop_id,
@@ -163,7 +158,6 @@ gst_gl_stereo_mix_class_init (GstGLStereoMixClass * klass)
   videoaggregator_class->negotiated_caps = _negotiated_caps;
   videoaggregator_class->get_output_buffer =
       gst_gl_stereo_mix_get_output_buffer;
-  videoaggregator_class->find_best_format = gst_gl_stereo_mix_find_best_format;
 
   base_mix_class->supported_gl_api =
       GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
@@ -438,13 +432,97 @@ get_converted_caps (GstGLStereoMix * mix, GstCaps * caps)
   return result;
 }
 
-/* Return the possible output caps we decided in find_best_format() */
+/* Return the possible output caps based on inputs and downstream prefs */
 static GstCaps *
 _update_caps (GstVideoAggregator * vagg, GstCaps * caps, GstCaps * filter)
 {
   GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);
+  GList *l;
+  gint best_width = -1, best_height = -1;
+  gdouble best_fps = -1, cur_fps;
+  gint best_fps_n = 0, best_fps_d = 1;
+  GstVideoInfo *mix_info;
+  GstCaps *blend_caps, *tmp_caps;
+  GstCaps *out_caps;
+
+  GST_OBJECT_LOCK (vagg);
+
+  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
+    GstVideoAggregatorPad *pad = l->data;
+    GstVideoInfo tmp = pad->info;
+    gint this_width, this_height;
+    gint fps_n, fps_d;
+
+    if (!pad->info.finfo)
+      continue;
+
+    /* This can happen if we release a pad and another pad hasn't been negotiated_caps yet */
+    if (GST_VIDEO_INFO_FORMAT (&pad->info) == GST_VIDEO_FORMAT_UNKNOWN)
+      continue;
+
+    /* Convert to per-view width/height for unpacked forms */
+    gst_video_multiview_video_info_change_mode (&tmp,
+        GST_VIDEO_MULTIVIEW_MODE_SEPARATED, GST_VIDEO_MULTIVIEW_FLAGS_NONE);
+
+    this_width = GST_VIDEO_INFO_WIDTH (&tmp);
+    this_height = GST_VIDEO_INFO_HEIGHT (&tmp);
+    fps_n = GST_VIDEO_INFO_FPS_N (&tmp);
+    fps_d = GST_VIDEO_INFO_FPS_D (&tmp);
+
+    GST_INFO_OBJECT (vagg, "Input pad %" GST_PTR_FORMAT
+        " w %u h %u", pad, this_width, this_height);
+
+    if (this_width == 0 || this_height == 0)
+      continue;
+
+    if (best_width < this_width)
+      best_width = this_width;
+    if (best_height < this_height)
+      best_height = this_height;
 
-  return gst_caps_ref (mix->out_caps);
+    if (fps_d == 0)
+      cur_fps = 0.0;
+    else
+      gst_util_fraction_to_double (fps_n, fps_d, &cur_fps);
+
+    if (best_fps < cur_fps) {
+      best_fps = cur_fps;
+      best_fps_n = fps_n;
+      best_fps_d = fps_d;
+    }
+
+    /* FIXME: Preserve PAR for at least one input when different sized inputs */
+  }
+  GST_OBJECT_UNLOCK (vagg);
+
+  mix_info = &mix->mix_info;
+  gst_video_info_set_format (mix_info, GST_VIDEO_FORMAT_RGBA, best_width,
+      best_height);
+
+  GST_VIDEO_INFO_FPS_N (mix_info) = best_fps_n;
+  GST_VIDEO_INFO_FPS_D (mix_info) = best_fps_d;
+
+  GST_VIDEO_INFO_MULTIVIEW_MODE (mix_info) = GST_VIDEO_MULTIVIEW_MODE_SEPARATED;
+  GST_VIDEO_INFO_VIEWS (mix_info) = 2;
+
+  /* FIXME: If input is marked as flipped or flopped, preserve those flags */
+  GST_VIDEO_INFO_MULTIVIEW_FLAGS (mix_info) = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
+
+  /* Choose our output format based on downstream preferences */
+  blend_caps = gst_video_info_to_caps (mix_info);
+
+  gst_caps_set_features (blend_caps, 0,
+      gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));
+
+  tmp_caps = get_converted_caps (GST_GL_STEREO_MIX (vagg), blend_caps);
+  gst_caps_unref (blend_caps);
+
+  out_caps = gst_caps_intersect (caps, tmp_caps);
+  gst_caps_unref (tmp_caps);
+
+  GST_DEBUG_OBJECT (vagg, "Possible output caps %" GST_PTR_FORMAT, out_caps);
+
+  return out_caps;
 }
 
 /* Called after videoaggregator fixates our caps */
@@ -462,8 +540,6 @@ _negotiated_caps (GstVideoAggregator * vagg, GstCaps * caps)
       return FALSE;
 
   /* Update the glview_convert output */
-  if (!gst_video_info_from_caps (&mix->out_info, caps))
-    return FALSE;
 
   /* We can configure the view_converter now */
   gst_gl_view_convert_set_context (mix->viewconvert,
@@ -585,108 +661,3 @@ gst_gl_stereo_mix_process_frames (GstGLStereoMix * mixer)
 
   return TRUE;
 }
-
-/* Iterate the input sink pads, and choose the blend format
- * we will generate before output conversion, which is RGBA
- * at some suitable size */
-static void
-gst_gl_stereo_mix_find_best_format (GstVideoAggregator * vagg,
-    GstCaps * downstream_caps, GstVideoInfo * best_info,
-    gboolean * at_least_one_alpha)
-{
-  GstGLStereoMix *mix = GST_GL_STEREO_MIX (vagg);
-  GList *l;
-  gint best_width = -1, best_height = -1;
-  gdouble best_fps = -1, cur_fps;
-  gint best_fps_n = 0, best_fps_d = 1;
-  GstVideoInfo *mix_info;
-  GstCaps *blend_caps, *tmp_caps;
-
-  /* We'll deal with alpha internally, so just tell aggregator to
-   * be quiet */
-  *at_least_one_alpha = FALSE;
-
-  GST_OBJECT_LOCK (vagg);
-
-  for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
-    GstVideoAggregatorPad *pad = l->data;
-    GstVideoInfo tmp = pad->info;
-    gint this_width, this_height;
-    gint fps_n, fps_d;
-
-    if (!pad->info.finfo)
-      continue;
-
-    /* This can happen if we release a pad and another pad hasn't been negotiated_caps yet */
-    if (GST_VIDEO_INFO_FORMAT (&pad->info) == GST_VIDEO_FORMAT_UNKNOWN)
-      continue;
-
-    /* Convert to per-view width/height for unpacked forms */
-    gst_video_multiview_video_info_change_mode (&tmp,
-        GST_VIDEO_MULTIVIEW_MODE_SEPARATED, GST_VIDEO_MULTIVIEW_FLAGS_NONE);
-
-    this_width = GST_VIDEO_INFO_WIDTH (&tmp);
-    this_height = GST_VIDEO_INFO_HEIGHT (&tmp);
-    fps_n = GST_VIDEO_INFO_FPS_N (&tmp);
-    fps_d = GST_VIDEO_INFO_FPS_D (&tmp);
-
-    GST_INFO_OBJECT (vagg, "Input pad %" GST_PTR_FORMAT
-        " w %u h %u", pad, this_width, this_height);
-
-    if (this_width == 0 || this_height == 0)
-      continue;
-
-    if (best_width < this_width)
-      best_width = this_width;
-    if (best_height < this_height)
-      best_height = this_height;
-
-    if (fps_d == 0)
-      cur_fps = 0.0;
-    else
-      gst_util_fraction_to_double (fps_n, fps_d, &cur_fps);
-
-    if (best_fps < cur_fps) {
-      best_fps = cur_fps;
-      best_fps_n = fps_n;
-      best_fps_d = fps_d;
-    }
-
-    /* FIXME: Preserve PAR for at least one input when different sized inputs */
-  }
-  GST_OBJECT_UNLOCK (vagg);
-
-  mix_info = &mix->mix_info;
-  gst_video_info_set_format (mix_info, GST_VIDEO_FORMAT_RGBA, best_width,
-      best_height);
-
-  GST_VIDEO_INFO_FPS_N (mix_info) = best_fps_n;
-  GST_VIDEO_INFO_FPS_D (mix_info) = best_fps_d;
-
-  GST_VIDEO_INFO_MULTIVIEW_MODE (mix_info) = GST_VIDEO_MULTIVIEW_MODE_SEPARATED;
-  GST_VIDEO_INFO_VIEWS (mix_info) = 2;
-
-  /* FIXME: If input is marked as flipped or flopped, preserve those flags */
-  GST_VIDEO_INFO_MULTIVIEW_FLAGS (mix_info) = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
-
-  /* Choose our output format based on downstream preferences */
-  blend_caps = gst_video_info_to_caps (mix_info);
-
-  gst_caps_set_features (blend_caps, 0,
-      gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY));
-
-  tmp_caps = get_converted_caps (GST_GL_STEREO_MIX (vagg), blend_caps);
-  gst_caps_unref (blend_caps);
-
-  if (mix->out_caps)
-    gst_caps_unref (mix->out_caps);
-
-  mix->out_caps = gst_caps_intersect (downstream_caps, tmp_caps);
-  gst_caps_unref (tmp_caps);
-
-  GST_DEBUG_OBJECT (vagg, "Possible output caps %" GST_PTR_FORMAT,
-      mix->out_caps);
-  /* Tell videoaggregator our preferred size. Actual info gets
-   * overridden during caps nego */
-  *best_info = *mix_info;
-}
index b0f1bd2..9971a89 100644 (file)
@@ -69,9 +69,6 @@ struct _GstGLStereoMix
   GstGLViewConvert *viewconvert;
   GstGLStereoDownmix downmix_mode;
 
-  GstCaps *out_caps;
-  GstVideoInfo out_info;
-
   GstVideoInfo mix_info;
 
   GPtrArray *input_frames;