- handle mono audio too

Original commit message from CVS:
- handle mono audio too
- better caps negotiation
- goom_close() in dispose
This commit is contained in:
Wim Taymans 2003-04-13 18:40:34 +00:00
parent a1c77f33ab
commit 533d9c6860
2 changed files with 104 additions and 46 deletions

2
common

@ -1 +1 @@
Subproject commit 50879a63c4fa8f2544d4d89a9dbfa0f5720c3266
Subproject commit 0ce4bbf0bc51c08694a8a1e0bec7624094b043d6

View file

@ -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->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;
if (goom->channels == 2) {
for (i=0; i < 512; i++) {
goom->datain[0][i] = *data++;
goom->datain[1][i] = *data++;
}
}
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;