From 533d9c6860257715838b1438d71acf22d2826cca Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 13 Apr 2003 18:40:34 +0000 Subject: [PATCH] - handle mono audio too Original commit message from CVS: - handle mono audio too - better caps negotiation - goom_close() in dispose --- common | 2 +- gst/goom/gstgoom.c | 146 +++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 103 insertions(+), 45 deletions(-) diff --git a/common b/common index 50879a6..0ce4bbf 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 50879a63c4fa8f2544d4d89a9dbfa0f5720c3266 +Subproject commit 0ce4bbf0bc51c08694a8a1e0bec7624094b043d6 diff --git a/gst/goom/gstgoom.c b/gst/goom/gstgoom.c index 9a75af8..36929f0 100644 --- a/gst/goom/gstgoom.c +++ b/gst/goom/gstgoom.c @@ -36,7 +36,6 @@ struct _GstGOOM { /* pads */ GstPad *sinkpad,*srcpad; - GstBufferPool *peerpool; /* the timestamp of the next frame */ guint64 next_time; @@ -46,7 +45,8 @@ struct _GstGOOM { gint fps; gint width; gint height; - gboolean first_buffer; + gint channels; + gboolean srcnegotiated; }; struct _GstGOOMClass { @@ -115,13 +115,14 @@ GST_PAD_TEMPLATE_FACTORY (sink_template, "width", GST_PROPS_INT (16), "depth", GST_PROPS_INT (16), "rate", GST_PROPS_INT_RANGE (8000, 96000), - "channels", GST_PROPS_INT (2) + "channels", GST_PROPS_INT_RANGE (1, 2) ) ) static void gst_goom_class_init (GstGOOMClass *klass); static void gst_goom_init (GstGOOM *goom); +static void gst_goom_dispose (GObject *object); static GstElementStateReturn gst_goom_change_state (GstElement *element); @@ -133,8 +134,8 @@ static void gst_goom_get_property (GObject *object, guint prop_id, static void gst_goom_chain (GstPad *pad, GstBuffer *buf); -static GstPadLinkReturn - gst_goom_sinkconnect (GstPad *pad, GstCaps *caps); +static GstPadLinkReturn gst_goom_sinkconnect (GstPad *pad, GstCaps *caps); +static GstPadLinkReturn gst_goom_srcconnect (GstPad *pad, GstCaps *caps); static GstElementClass *parent_class = NULL; @@ -181,8 +182,9 @@ gst_goom_class_init(GstGOOMClass *klass) g_param_spec_int ("fps","FPS","Frames per second", 1, 100, 25, G_PARAM_READWRITE)); - gobject_class->set_property = gst_goom_set_property; - gobject_class->get_property = gst_goom_get_property; + gobject_class->dispose = gst_goom_dispose; + gobject_class->set_property = gst_goom_set_property; + gobject_class->get_property = gst_goom_get_property; gstelement_class->change_state = gst_goom_change_state; } @@ -203,9 +205,22 @@ gst_goom_init (GstGOOM *goom) gst_pad_set_chain_function (goom->sinkpad, gst_goom_chain); gst_pad_set_link_function (goom->sinkpad, gst_goom_sinkconnect); + gst_pad_set_link_function (goom->srcpad, gst_goom_srcconnect); + goom->width = 320; goom->height = 200; goom->fps = 25; /* desired frame rate */ + goom->channels = 0; + /* set to something */ + goom_init (50, 50); +} + +static void +gst_goom_dispose (GObject *object) +{ + goom_close (); + + G_OBJECT_CLASS (parent_class)->dispose (object); } static GstPadLinkReturn @@ -218,9 +233,59 @@ gst_goom_sinkconnect (GstPad *pad, GstCaps *caps) return GST_PAD_LINK_DELAYED; } + gst_caps_get_int (caps, "channels", &goom->channels); + + return GST_PAD_LINK_OK; +} + +static GstPadLinkReturn +gst_goom_srcconnect (GstPad *pad, GstCaps *caps) +{ + GstGOOM *goom; + goom = GST_GOOM (gst_pad_get_parent (pad)); + + if (!GST_CAPS_IS_FIXED (caps)) { + return GST_PAD_LINK_DELAYED; + } + + gst_caps_get_int (caps, "width", &goom->width); + gst_caps_get_int (caps, "height", &goom->height); + + goom_set_resolution (goom->width, goom->height); + goom->srcnegotiated = TRUE; + return GST_PAD_LINK_OK; } +static gboolean +gst_goom_negotiate_default (GstGOOM *goom) +{ + GstCaps *caps; + + caps = GST_CAPS_NEW ( + "goomsrc", + "video/raw", + "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), + "bpp", GST_PROPS_INT (32), + "depth", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "red_mask", GST_PROPS_INT (0xff0000), + "green_mask", GST_PROPS_INT (0x00ff00), + "blue_mask", GST_PROPS_INT (0x0000ff), + "width", GST_PROPS_INT (goom->width), + "height", GST_PROPS_INT (goom->height) + ); + + if (gst_pad_try_set_caps (goom->srcpad, caps) <= 0) { + return FALSE; + } + + goom_set_resolution (goom->width, goom->height); + goom->srcnegotiated = TRUE; + + return TRUE; +} + static void gst_goom_chain (GstPad *pad, GstBuffer *bufin) { @@ -253,47 +318,41 @@ gst_goom_chain (GstPad *pad, GstBuffer *bufin) return; } - samples_in = GST_BUFFER_SIZE (bufin) / sizeof (gint16); + if (goom->channels == 0) { + gst_element_error (GST_ELEMENT (goom), "sink format not negotiated"); + goto done; + } + + if (!GST_PAD_IS_USABLE (goom->srcpad)) + goto done; + + if (!goom->srcnegotiated) { + if (!gst_goom_negotiate_default (goom)) { + gst_element_error (GST_ELEMENT (goom), "could not negotiate src format"); + goto done; + } + } + + samples_in = GST_BUFFER_SIZE (bufin) / (sizeof (gint16) * goom->channels); GST_DEBUG (0, "input buffer has %d samples", samples_in); - if (GST_BUFFER_TIMESTAMP (bufin) < goom->next_time || samples_in < 1024) { - gst_buffer_unref (bufin); - return; + if (GST_BUFFER_TIMESTAMP (bufin) < goom->next_time || samples_in < 512) { + goto done; } data = (gint16 *) GST_BUFFER_DATA (bufin); - for (i=0; i < 512; i++) { - goom->datain[0][i] = *data++; - goom->datain[1][i] = *data++; + if (goom->channels == 2) { + for (i=0; i < 512; i++) { + goom->datain[0][i] = *data++; + goom->datain[1][i] = *data++; + } } - - if (goom->first_buffer) { - GstCaps *caps; - - goom_init (goom->width, goom->height); - - GST_DEBUG (0, "making new pad"); - - caps = GST_CAPS_NEW ( - "goomsrc", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), - "bpp", GST_PROPS_INT (32), - "depth", GST_PROPS_INT (32), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "red_mask", GST_PROPS_INT (0xff0000), - "green_mask", GST_PROPS_INT (0x00ff00), - "blue_mask", GST_PROPS_INT (0x0000ff), - "width", GST_PROPS_INT (goom->width), - "height", GST_PROPS_INT (goom->height) - ); - - if (gst_pad_try_set_caps (goom->srcpad, caps) <= 0) { - gst_element_error (GST_ELEMENT (goom), "could not set caps"); - return; + else { + for (i=0; i < 512; i++) { + goom->datain[0][i] = *data; + goom->datain[1][i] = *data++; } - goom->first_buffer = FALSE; } bufout = gst_buffer_new (); @@ -306,10 +365,10 @@ gst_goom_chain (GstPad *pad, GstBuffer *bufin) gst_pad_push (goom->srcpad, bufout); +done: gst_buffer_unref (bufin); GST_DEBUG (0, "GOOM: exiting chainfunc"); - } static GstElementStateReturn @@ -324,9 +383,8 @@ gst_goom_change_state (GstElement *element) break; case GST_STATE_READY_TO_PAUSED: goom->next_time = 0; - goom->peerpool = NULL; - /* reset the initial video state */ - goom->first_buffer = TRUE; + goom->srcnegotiated = FALSE; + goom->channels = 0; break; case GST_STATE_PAUSED_TO_READY: break; -- 2.7.4