From ddfc8357a81cf47a4bbbe318ab3a6d932e6f51c2 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Thu, 2 Jun 2011 17:29:53 +0200 Subject: [PATCH] theora: get sink caps info from downstream element pad https://bugzilla.gnome.org/show_bug.cgi?id=651564 --- ext/theora/gsttheoraenc.c | 64 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index e77f8e6..f9967d1 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -243,6 +243,8 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_CAPS ("video/x-theora") ); +static GstCaps *theora_enc_src_caps; + static void _do_init (GType object_type) { @@ -275,6 +277,8 @@ static void theora_enc_finalize (GObject * object); static gboolean theora_enc_write_multipass_cache (GstTheoraEnc * enc, gboolean begin, gboolean eos); +static char *theora_enc_get_supported_formats (void); + static void gst_theora_enc_base_init (gpointer g_class) { @@ -295,6 +299,7 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) { GObjectClass *gobject_class = (GObjectClass *) klass; GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + char *caps_string; /* query runtime encoder properties */ th_enc_ctx *th_ctx; @@ -414,6 +419,14 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) THEORA_DEF_MULTIPASS_MODE, (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + caps_string = g_strdup_printf ("video/x-raw-yuv, " + "format = (fourcc) { %s }, " + "framerate = (fraction) [1/MAX, MAX], " + "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]", + theora_enc_get_supported_formats ()); + theora_enc_src_caps = gst_caps_from_string (caps_string); + g_free (caps_string); + gstelement_class->change_state = theora_enc_change_state; } @@ -598,24 +611,49 @@ theora_enc_get_supported_formats (void) static GstCaps * theora_enc_sink_getcaps (GstPad * pad) { + GstTheoraEnc *encoder; + GstPad *peer; GstCaps *caps; - char *supported_formats, *caps_string; - supported_formats = theora_enc_get_supported_formats (); - if (!supported_formats) { - GST_WARNING ("no supported formats found. Encoder disabled?"); + /* If we already have caps return them */ + if (GST_PAD_CAPS (pad)) + return gst_caps_ref (GST_PAD_CAPS (pad)); + + encoder = GST_THEORA_ENC (gst_pad_get_parent (pad)); + if (!encoder) return gst_caps_new_empty (); + + peer = gst_pad_get_peer (encoder->srcpad); + if (peer) { + const GstCaps *templ_caps; + GstCaps *peer_caps; + GstStructure *s; + guint i, n; + + peer_caps = gst_pad_get_caps (peer); + + /* Translate peercaps to YUV */ + peer_caps = gst_caps_make_writable (peer_caps); + n = gst_caps_get_size (peer_caps); + for (i = 0; i < n; i++) { + s = gst_caps_get_structure (peer_caps, i); + + gst_structure_set_name (s, "video/x-raw-yuv"); + gst_structure_remove_field (s, "streamheader"); + } + + templ_caps = gst_pad_get_pad_template_caps (pad); + + caps = gst_caps_intersect (peer_caps, templ_caps); + caps = gst_caps_intersect (caps, theora_enc_src_caps); + gst_caps_unref (peer_caps); + gst_object_unref (peer); + peer = NULL; + } else { + caps = gst_caps_ref (theora_enc_src_caps); } - caps_string = g_strdup_printf ("video/x-raw-yuv, " - "format = (fourcc) { %s }, " - "framerate = (fraction) [1/MAX, MAX], " - "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]", - supported_formats); - caps = gst_caps_from_string (caps_string); - g_free (caps_string); - g_free (supported_formats); - GST_DEBUG ("Supported caps: %" GST_PTR_FORMAT, caps); + gst_object_unref (encoder); return caps; } -- 2.7.4