ccconverter: fix missing output framerate on the caps
authorMatthew Waters <matthew@centricular.com>
Wed, 1 Jul 2020 09:41:33 +0000 (19:41 +1000)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 1 Jul 2020 19:33:56 +0000 (19:33 +0000)
A pipeline like this:

closedcaption/x-cea-708,format=cdp,framerate=30000/1001 ! ccconverter ! closedcaption/x-cea-708,format=cc_data

would produce a critical/assert:

GStreamer-CRITICAL **: 14:21:11.509: gst_util_fraction_multiply: assertion 'a_d != 0' failed

because there would be no framerate field on ccconverter's output.

Fixed by always fixating a framerate if the input has a framerate.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1393>

ext/closedcaption/gstccconverter.c
tests/check/elements/ccconverter.c

index c363017..8d23130 100644 (file)
@@ -318,14 +318,25 @@ gst_cc_converter_fixate_caps (GstBaseTransform * base,
       GST_BASE_TRANSFORM_CLASS (parent_class)->fixate_caps (base, direction,
       incaps, outcaps);
 
-  /* remove any framerate that might've been added by basetransform due to
-   * intersecting with downstream */
   s = gst_caps_get_structure (incaps, 0);
   framerate = gst_structure_get_value (s, "framerate");
   outcaps = gst_caps_make_writable (outcaps);
   t = gst_caps_get_structure (outcaps, 0);
   if (!framerate) {
+    /* remove any output framerate that might've been added by basetransform
+     * due to intersecting with downstream */
     gst_structure_remove_field (t, "framerate");
+  } else {
+    /* or passthrough the input framerate if possible */
+    guint n, d;
+
+    n = gst_value_get_fraction_numerator (framerate);
+    d = gst_value_get_fraction_denominator (framerate);
+
+    if (gst_structure_has_field (t, "framerate"))
+      gst_structure_fixate_field_nearest_fraction (t, "framerate", n, d);
+    else
+      gst_structure_set (t, "framerate", GST_TYPE_FRACTION, n, d, NULL);
   }
 
   GST_DEBUG_OBJECT (self,
index 82a5ff6..e44466d 100644 (file)
@@ -142,9 +142,20 @@ GST_START_TEST (framerate_passthrough)
   gst_harness_set_sink_caps_str (h,
       "closedcaption/x-cea-708,format=(string)cc_data,framerate=(fraction)30/1");
 
-  fail_unless_equals_int (gst_harness_push (h, buffer),
+  fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
       GST_FLOW_NOT_NEGOTIATED);
 
+  /* Now try cdp -> cc_data with framerate passthrough */
+  gst_harness_set_src_caps_str (h,
+      "closedcaption/x-cea-708,format=(string)cdp,framerate=(fraction)30/1");
+
+  gst_harness_set_sink_caps_str (h,
+      "closedcaption/x-cea-708,format=(string)cc_data");
+
+  fail_unless_equals_int (gst_harness_push (h, gst_buffer_ref (buffer)),
+      GST_FLOW_OK);
+
+  gst_buffer_unref (buffer);
   gst_harness_teardown (h);
 }