Bring the plugins in sync with the new core capsnego system.

Original commit message from CVS:
Bring the plugins in sync with the new core capsnego system.
Added some features, enhancements...
This commit is contained in:
Wim Taymans 2002-01-13 22:27:25 +00:00
parent e92b7beff5
commit 93e9ac34a1
21 changed files with 665 additions and 403 deletions

View file

@ -151,7 +151,8 @@ RTP_DIR=
endif endif
if USE_SDL if USE_SDL
SDL_DIR=sdl #SDL_DIR=sdl
SDL_DIR=
else else
SDL_DIR= SDL_DIR=
endif endif

View file

@ -350,21 +350,20 @@ gst_afsrc_open_file (GstAFSrc *src)
/* set caps on src */ /* set caps on src */
//FIXME: add all the possible formats, especially float ! */ //FIXME: add all the possible formats, especially float ! */
gst_pad_set_caps (src->srcpad, gst_caps_new ( gst_pad_try_set_caps (src->srcpad,
"af_src", GST_CAPS_NEW (
"audio/raw", "af_src",
gst_props_new ( "audio/raw",
"format", GST_PROPS_STRING ("int"), "format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0), //FIXME "law", GST_PROPS_INT (0), //FIXME
"endianness", GST_PROPS_INT (G_BYTE_ORDER), //FIXME "endianness", GST_PROPS_INT (G_BYTE_ORDER), //FIXME
"signed", GST_PROPS_BOOLEAN (src->is_signed), "signed", GST_PROPS_BOOLEAN (src->is_signed),
"width", GST_PROPS_INT (src->width), "width", GST_PROPS_INT (src->width),
"depth", GST_PROPS_INT (src->width), "depth", GST_PROPS_INT (src->width),
"rate", GST_PROPS_INT (src->rate), "rate", GST_PROPS_INT (src->rate),
"channels", GST_PROPS_INT (src->channels), "channels", GST_PROPS_INT (src->channels)
NULL )
) );
));
GST_FLAG_SET (src, GST_AFSRC_OPEN); GST_FLAG_SET (src, GST_AFSRC_OPEN);

View file

@ -45,11 +45,11 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
static void gst_gsmdec_class_init (GstGSMDec *klass); static void gst_gsmdec_class_init (GstGSMDec *klass);
static void gst_gsmdec_init (GstGSMDec *gsmdec); static void gst_gsmdec_init (GstGSMDec *gsmdec);
static void gst_gsmdec_chain (GstPad *pad, GstBuffer *buf); static void gst_gsmdec_chain (GstPad *pad, GstBuffer *buf);
static void gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps); static GstPadConnectReturn gst_gsmdec_sinkconnect (GstPad *pad, GstCaps *caps);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
//static guint gst_gsmdec_signals[LAST_SIGNAL] = { 0 }; //static guint gst_gsmdec_signals[LAST_SIGNAL] = { 0 };
@ -93,7 +93,7 @@ gst_gsmdec_init (GstGSMDec *gsmdec)
gsmdec->sinkpad = gst_pad_new_from_template (gsmdec_sink_template, "sink"); gsmdec->sinkpad = gst_pad_new_from_template (gsmdec_sink_template, "sink");
gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad); gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad);
gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain); gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain);
gst_pad_set_newcaps_function (gsmdec->sinkpad, gst_gsmdec_newcaps); gst_pad_set_connect_function (gsmdec->sinkpad, gst_gsmdec_sinkconnect);
gsmdec->srcpad = gst_pad_new_from_template (gsmdec_src_template, "src"); gsmdec->srcpad = gst_pad_new_from_template (gsmdec_src_template, "src");
gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad); gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad);
@ -102,13 +102,18 @@ gst_gsmdec_init (GstGSMDec *gsmdec)
gsmdec->bufsize = 0; gsmdec->bufsize = 0;
} }
static void static GstPadConnectReturn
gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps) gst_gsmdec_sinkconnect (GstPad *pad, GstCaps *caps)
{ {
GstGSMDec *gsmdec; GstGSMDec *gsmdec;
gsmdec = GST_GSMDEC (gst_pad_get_parent (pad)); gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
gst_pad_set_caps (gsmdec->srcpad, GST_CAPS_NEW (
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
if (gst_pad_try_set_caps (gsmdec->srcpad,
GST_CAPS_NEW (
"gsm_raw", "gsm_raw",
"audio/raw", "audio/raw",
"format", GST_PROPS_STRING ("int"), "format", GST_PROPS_STRING ("int"),
@ -119,7 +124,11 @@ gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps)
"depth", GST_PROPS_INT (16), "depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT (gst_caps_get_int (caps, "rate")), "rate", GST_PROPS_INT (gst_caps_get_int (caps, "rate")),
"channels", GST_PROPS_INT (1) "channels", GST_PROPS_INT (1)
)); )))
{
return GST_PAD_CONNECT_OK;
}
return GST_PAD_CONNECT_REFUSED;
} }
static void static void

View file

@ -46,22 +46,11 @@ enum {
/* FILL ME */ /* FILL ME */
}; };
GST_PADTEMPLATE_FACTORY (src_factory, static void gst_gsmenc_class_init (GstGSMEnc *klass);
"src", static void gst_gsmenc_init (GstGSMEnc *gsmenc);
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_CAPS_NEW (
"gsm_enc",
"audio/x-gsm",
"rate", GST_PROPS_INT_RANGE (1000, 48000)
)
);
static void gst_gsmenc_class_init (GstGSMEnc *klass); static void gst_gsmenc_chain (GstPad *pad,GstBuffer *buf);
static void gst_gsmenc_init (GstGSMEnc *gsmenc); static GstPadConnectReturn gst_gsmenc_sinkconnect (GstPad *pad, GstCaps *caps);
static void gst_gsmenc_chain (GstPad *pad,GstBuffer *buf);
static void gst_gsmenc_newcaps (GstPad *pad, GstCaps *caps);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 }; static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 };
@ -113,7 +102,7 @@ gst_gsmenc_init (GstGSMEnc *gsmenc)
gsmenc->sinkpad = gst_pad_new_from_template (gsmenc_sink_template, "sink"); gsmenc->sinkpad = gst_pad_new_from_template (gsmenc_sink_template, "sink");
gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad); gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad);
gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain); gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain);
gst_pad_set_newcaps_function (gsmenc->sinkpad, gst_gsmenc_newcaps); gst_pad_set_connect_function (gsmenc->sinkpad, gst_gsmenc_sinkconnect);
gsmenc->srcpad = gst_pad_new_from_template (gsmenc_src_template, "src"); gsmenc->srcpad = gst_pad_new_from_template (gsmenc_src_template, "src");
gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->srcpad); gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->srcpad);
@ -124,19 +113,27 @@ gst_gsmenc_init (GstGSMEnc *gsmenc)
gsmenc->rate = 8000; gsmenc->rate = 8000;
} }
static void static GstPadConnectReturn
gst_gsmenc_newcaps (GstPad *pad, GstCaps *caps) gst_gsmenc_sinkconnect (GstPad *pad, GstCaps *caps)
{ {
GstGSMEnc *gsmenc; GstGSMEnc *gsmenc;
gsmenc = GST_GSMENC (gst_pad_get_parent (pad)); gsmenc = GST_GSMENC (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
gsmenc->rate = gst_caps_get_int (caps, "rate"); gsmenc->rate = gst_caps_get_int (caps, "rate");
gst_pad_set_caps (gsmenc->srcpad, GST_CAPS_NEW ( if (gst_pad_try_set_caps (gsmenc->srcpad, GST_CAPS_NEW (
"gsm_gsm", "gsm_gsm",
"audio/x-gsm", "audio/x-gsm",
"rate", GST_PROPS_INT (gsmenc->rate) "rate", GST_PROPS_INT (gsmenc->rate)
)); )))
{
return GST_PAD_CONNECT_OK;
}
return GST_PAD_CONNECT_REFUSED;
} }
static void static void
@ -153,7 +150,7 @@ gst_gsmenc_chain (GstPad *pad, GstBuffer *buf)
gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad)); gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad));
if (!GST_PAD_CAPS (gsmenc->srcpad)) { if (!GST_PAD_CAPS (gsmenc->srcpad)) {
gst_pad_set_caps (gsmenc->srcpad, gst_pad_try_set_caps (gsmenc->srcpad,
GST_CAPS_NEW ( GST_CAPS_NEW (
"gsm_enc", "gsm_enc",
"audio/x-gsm", "audio/x-gsm",

View file

@ -14,7 +14,7 @@ else
PLUGIN_EXTRA_LIBS = PLUGIN_EXTRA_LIBS =
endif endif
libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2yuv.c yuv2rgb.c $(ARCHSRCS) libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2yuv.c yuv2rgb.c rgb2yuv.c $(ARCHSRCS)
libgstcolorspace_la_CFLAGS = $(GST_CFLAGS) libgstcolorspace_la_CFLAGS = $(GST_CFLAGS)
libgstcolorspace_la_LIBADD = $(GST_LIBS) $(PLUGIN_EXTRA_LIBS) libgstcolorspace_la_LIBADD = $(GST_LIBS) $(PLUGIN_EXTRA_LIBS)

View file

@ -52,7 +52,13 @@ GST_PADTEMPLATE_FACTORY (colorspace_src_template_factory,
GST_CAPS_NEW ( GST_CAPS_NEW (
"colorspace_src", "colorspace_src",
"video/raw", "video/raw",
NULL "format", GST_PROPS_LIST (
GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")),
GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
),
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT)
) )
) )
@ -63,20 +69,41 @@ GST_PADTEMPLATE_FACTORY (colorspace_sink_template_factory,
GST_CAPS_NEW ( GST_CAPS_NEW (
"colorspace_sink", "colorspace_sink",
"video/raw", "video/raw",
NULL "format", GST_PROPS_LIST (
GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")),
GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB "))
),
"width", GST_PROPS_INT_RANGE (0, G_MAXINT),
"height", GST_PROPS_INT_RANGE (0, G_MAXINT)
) )
) )
static void gst_colorspace_class_init (GstColorspaceClass *klass); static void gst_colorspace_class_init (GstColorspaceClass *klass);
static void gst_colorspace_init (GstColorspace *space); static void gst_colorspace_init (GstColorspace *space);
static void gst_colorspace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_colorspace_set_property (GObject *object, guint prop_id,
static void gst_colorspace_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); const GValue *value, GParamSpec *pspec);
static void gst_colorspace_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static GstPadConnectReturn
gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps);
static GstPadConnectReturn
gst_colorspace_srcconnect (GstPad *pad, GstCaps *caps);
static GstPadConnectReturn
gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps);
static void gst_colorspace_chain (GstPad *pad, GstBuffer *buf); static void gst_colorspace_chain (GstPad *pad, GstBuffer *buf);
static GstElementStateReturn
gst_colorspace_change_state (GstElement *element);
// FIXME // FIXME
extern void gst_colorspace_yuy2_to_i420(unsigned char *src, unsigned char *dest, guint width, guint height); extern void gst_colorspace_yuy2_to_i420 (unsigned char *src, unsigned char *dest,
guint width, guint height);
extern void gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest,
guint width, guint height);
extern void gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest,
guint width, guint height);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
//static guint gst_colorspace_signals[LAST_SIGNAL] = { 0 }; //static guint gst_colorspace_signals[LAST_SIGNAL] = { 0 };
@ -88,20 +115,16 @@ colorspace_get_bufferpool (GstPad *pad)
space = GST_COLORSPACE (gst_pad_get_parent (pad)); space = GST_COLORSPACE (gst_pad_get_parent (pad));
if (space->type == GST_COLORSPACE_NONE) if (space->type == GST_COLORSPACE_NONE && !space->disabled)
return gst_pad_get_bufferpool (space->srcpad); return gst_pad_get_bufferpool (space->srcpad);
else else
return NULL; return NULL;
} }
static gboolean static gboolean
colorspace_setup_converter (GstColorspace *space) colorspace_setup_converter (GstColorspace *space, GstCaps *from_caps, GstCaps *to_caps)
{ {
gulong from_space, to_space; gulong from_space, to_space;
GstCaps *from_caps, *to_caps;
from_caps = space->sinkcaps;
to_caps = space->srccaps;
g_return_val_if_fail (to_caps != NULL, FALSE); g_return_val_if_fail (to_caps != NULL, FALSE);
g_return_val_if_fail (from_caps != NULL, FALSE); g_return_val_if_fail (from_caps != NULL, FALSE);
@ -109,26 +132,29 @@ colorspace_setup_converter (GstColorspace *space)
from_space = gst_caps_get_fourcc_int (from_caps, "format"); from_space = gst_caps_get_fourcc_int (from_caps, "format");
to_space = gst_caps_get_fourcc_int (to_caps, "format"); to_space = gst_caps_get_fourcc_int (to_caps, "format");
g_warning ("set up converter for %08lx to %08lx\n", from_space, to_space); GST_INFO (GST_CAT_NEGOTIATION, "set up converter for %08lx to %08lx", from_space, to_space);
switch (from_space) { switch (from_space) {
case GST_MAKE_FOURCC ('R','G','B',' '): case GST_MAKE_FOURCC ('R','G','B',' '):
{
gint from_bpp = gst_caps_get_int (from_caps, "bpp");
switch (to_space) { switch (to_space) {
#ifdef HAVE_LIBHERMES
case GST_MAKE_FOURCC ('R','G','B',' '): case GST_MAKE_FOURCC ('R','G','B',' '):
#ifdef HAVE_HERMES
{ {
space->source.r = gst_caps_get_int (from_caps, "red_mask"); space->source.r = gst_caps_get_int (from_caps, "red_mask");
space->source.g = gst_caps_get_int (from_caps, "green_mask"); space->source.g = gst_caps_get_int (from_caps, "green_mask");
space->source.b = gst_caps_get_int (from_caps, "blue_mask"); space->source.b = gst_caps_get_int (from_caps, "blue_mask");
space->source.a = 0; space->source.a = 0;
space->srcbpp = space->source.bits = gst_caps_get_int (from_caps, "bpp"); space->srcbpp = space->source.bits = from_bpp;
space->source.indexed = 0; space->source.indexed = 0;
space->source.has_colorkey = 0; space->source.has_colorkey = 0;
GST_INFO (0,"source red mask %08x\n", space->source.r); GST_INFO (GST_CAT_PLUGIN_INFO, "source red mask %08x", space->source.r);
GST_INFO (0, "source green mask %08x\n", space->source.g); GST_INFO (GST_CAT_PLUGIN_INFO, "source green mask %08x", space->source.g);
GST_INFO (0, "source blue mask %08x\n", space->source.b); GST_INFO (GST_CAT_PLUGIN_INFO, "source blue mask %08x", space->source.b);
GST_INFO (0, "source bpp %08x\n", space->srcbpp); GST_INFO (GST_CAT_PLUGIN_INFO, "source bpp %08x", space->srcbpp);
space->dest.r = gst_caps_get_int (to_caps, "red_mask"); space->dest.r = gst_caps_get_int (to_caps, "red_mask");
space->dest.g = gst_caps_get_int (to_caps, "green_mask"); space->dest.g = gst_caps_get_int (to_caps, "green_mask");
@ -138,173 +164,189 @@ colorspace_setup_converter (GstColorspace *space)
space->dest.indexed = 0; space->dest.indexed = 0;
space->dest.has_colorkey = 0; space->dest.has_colorkey = 0;
GST_INFO (0, "dest red mask %08x\n", space->dest.r); GST_INFO (GST_CAT_PLUGIN_INFO, "dest red mask %08x", space->dest.r);
GST_INFO (0, "dest green mask %08x\n", space->dest.g); GST_INFO (GST_CAT_PLUGIN_INFO, "dest green mask %08x", space->dest.g);
GST_INFO (0, "dest blue mask %08x\n", space->dest.b); GST_INFO (GST_CAT_PLUGIN_INFO, "dest blue mask %08x", space->dest.b);
GST_INFO (0, "dest bpp %08x\n", space->destbpp); GST_INFO (GST_CAT_PLUGIN_INFO, "dest bpp %08x", space->destbpp);
if (!Hermes_ConverterRequest (space->h_handle, &space->source, &space->dest)) { if (!Hermes_ConverterRequest (space->h_handle, &space->source, &space->dest)) {
g_warning ("could not get converter\n"); g_warning ("Hermes: could not get converter\n");
return FALSE; return FALSE;
} }
GST_INFO (0, "converter set up\n"); GST_INFO (GST_CAT_PLUGIN_INFO, "converter set up");
space->type = GST_COLORSPACE_HERMES; space->type = GST_COLORSPACE_HERMES;
break; return TRUE;
} }
#else
g_warning ("colorspace: compiled without hermes!");
return FALSE;
#endif #endif
case GST_MAKE_FOURCC ('Y','U','Y','2'): case GST_MAKE_FOURCC ('Y','V','1','2'):
if (from_bpp == 32) {
space->type = GST_COLORSPACE_RGB32_YV12;
space->destbpp = 12;
return TRUE;
}
case GST_MAKE_FOURCC ('I','4','2','0'): case GST_MAKE_FOURCC ('I','4','2','0'):
g_error ("colorspace: RGB to YUV implement me"); if (from_bpp == 32) {
break; space->type = GST_COLORSPACE_RGB32_I420;
space->destbpp = 12;
return TRUE;
}
case GST_MAKE_FOURCC ('Y','U','Y','2'):
GST_INFO (GST_CAT_NEGOTIATION, "colorspace: RGB to YUV with bpp %d not implemented!!", from_bpp);
return FALSE;
} }
break; break;
case GST_MAKE_FOURCC ('Y','U','Y','2'): }
case GST_MAKE_FOURCC ('I','4','2','0'): case GST_MAKE_FOURCC ('I','4','2','0'):
switch (to_space) { switch (to_space) {
case GST_MAKE_FOURCC ('R','G','B',' '): case GST_MAKE_FOURCC ('R','G','B',' '):
g_warning ("colorspace: YUV to RGB"); GST_INFO (GST_CAT_NEGOTIATION, "colorspace: YUV to RGB");
space->destbpp = gst_caps_get_int (to_caps, "bpp"); space->destbpp = gst_caps_get_int (to_caps, "bpp");
space->converter = gst_colorspace_yuv2rgb_get_converter (from_caps, to_caps); space->converter = gst_colorspace_yuv2rgb_get_converter (from_caps, to_caps);
space->type = GST_COLORSPACE_YUV_RGB; space->type = GST_COLORSPACE_YUV_RGB;
break; return TRUE;
case GST_MAKE_FOURCC ('I','4','2','0'): case GST_MAKE_FOURCC ('I','4','2','0'):
space->type = GST_COLORSPACE_YUY2_I420; space->type = GST_COLORSPACE_NONE;
space->destbpp = 12; space->destbpp = 12;
break; return TRUE;
}
break;
}
return TRUE;
}
static GstPadNegotiateReturn
colorspace_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstColorspace* space = GST_COLORSPACE (gst_object_get_parent (GST_OBJECT (pad)));
GstCaps *original;
gint src_width, src_height;
GST_DEBUG (GST_CAT_NEGOTIATION, "colorspace: src negotiate\n");
g_return_val_if_fail (space->sinkcaps != NULL, GST_PAD_NEGOTIATE_FAIL);
src_width = gst_caps_get_int (space->sinkcaps, "width");
src_height = gst_caps_get_int (space->sinkcaps, "height");
space->width = src_width;
space->height = src_height;
if (*caps==NULL) {
*caps = gst_caps_new ("colorspace_caps",
"video/raw",
gst_props_new (
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
"width", GST_PROPS_INT (src_width),
"height", GST_PROPS_INT (src_height),
NULL));
space->srccaps = gst_caps_ref (*caps);
return GST_PAD_NEGOTIATE_TRY;
//return gst_pad_negotiate_proxy (pad, space->sinkpad, caps);
}
original = gst_caps_copy (*caps);
//g_print ("%d %d\n", src_width, src_height);
// peers couldn't agree, we need to help
switch (gst_caps_get_fourcc_int (original, "format")) {
case GST_MAKE_FOURCC ('R','G','B',' '):
gst_caps_ref (*caps);
if (gst_caps_get_int (*caps, "width") == src_width &&
gst_caps_get_int (*caps, "height") == src_height)
{
space->srccaps = *caps;
if (colorspace_setup_converter (space)) {
return GST_PAD_NEGOTIATE_AGREE;
}
}
else {
gst_caps_set (*caps, "width", GST_PROPS_INT (src_width));
gst_caps_set (*caps, "height", GST_PROPS_INT (src_height));
space->srccaps = *caps;
// FIXME
GST_PAD_CAPS (space->srcpad) = gst_caps_ref (*caps);
return GST_PAD_NEGOTIATE_TRY;
} }
break; break;
case GST_MAKE_FOURCC ('Y','U','Y','2'): case GST_MAKE_FOURCC ('Y','U','Y','2'):
case GST_MAKE_FOURCC ('I','4','2','0'): switch (to_space) {
//space->srccaps = original; case GST_MAKE_FOURCC ('I','4','2','0'):
//fprintf (stderr, "found something suitable\n"); space->type = GST_COLORSPACE_YUY2_I420;
return GST_PAD_NEGOTIATE_AGREE; space->destbpp = 12;
default: return TRUE;
*caps = NULL; case GST_MAKE_FOURCC ('Y','U','Y','2'):
return GST_PAD_NEGOTIATE_TRY; space->type = GST_COLORSPACE_NONE;
space->destbpp = 16;
return TRUE;
}
break; break;
} }
return GST_PAD_NEGOTIATE_FAIL; return FALSE;
} }
static GstPadNegotiateReturn static GstCaps*
colorspace_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) gst_colorspace_getcaps (GstPad *pad, GstCaps *caps)
{ {
GstColorspace* space = GST_COLORSPACE (gst_object_get_parent (GST_OBJECT (pad))); GstColorspace *space;
GstCaps *original; GstCaps *result;
GstCaps *peercaps;
GST_DEBUG (GST_CAT_NEGOTIATION, "colorspace: sink negotiate\n"); GstCaps *ourcaps;
if (*caps==NULL) space = GST_COLORSPACE (gst_pad_get_parent (pad));
return gst_pad_negotiate_proxy (pad, space->srcpad, caps);
//return GST_PAD_NEGOTIATE_FAIL;
/* we can do everything our peer can... */
peercaps = gst_caps_copy (gst_pad_get_allowed_caps (space->srcpad));
/* and our own template of course */
ourcaps = gst_caps_copy (gst_pad_get_padtemplate_caps (pad));
space->type = GST_COLORSPACE_NONE; /* merge them together, we prefer the peercaps first */
result = gst_caps_prepend (ourcaps, peercaps);
original = gst_caps_copy (*caps); return result;
}
// see if a common format exists between both peers... static GstPadConnectReturn
switch (gst_pad_negotiate_proxy (pad, space->srcpad, caps)) { gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps)
case GST_PAD_NEGOTIATE_AGREE: {
//g_print ("colorspace: common format found\n"); GstColorspace *space;
return GST_PAD_NEGOTIATE_AGREE; GstPad *peer;
default:
break; space = GST_COLORSPACE (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps)) {
return GST_PAD_CONNECT_DELAYED;
} }
g_warning ("colorspace: no common format found\n");
g_warning ("colorspace: src: %08lx\n", gst_caps_get_fourcc_int (original, "format"));
// peers couldn't agree, we need to help space->width = gst_caps_get_int (caps, "width");
space->sinkcaps = original; space->height = gst_caps_get_int (caps, "height");
/* GST_INFO (GST_CAT_PROPERTIES, "size: %dx%d", space->width, space->height);
space->width = gst_caps_get_int (original, "width");
space->height = gst_caps_get_int (original, "height");
space->srccaps = gst_caps_new ( space->sinkcaps = caps;
"testcaps",
"video/raw",
gst_props_new (
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
"width", GST_PROPS_INT (gst_caps_get_int (original, "width")),
"height", GST_PROPS_INT (gst_caps_get_int (original, "height")),
NULL
));
GST_PAD_CAPS (space->srcpad) = space->srccaps; peer = gst_pad_get_peer (pad);
*/ if (peer) {
if (!gst_colorspace_srcconnect_func (pad, gst_pad_get_allowed_caps (space->srcpad), FALSE)) {
if (gst_pad_renegotiate (space->srcpad)) { space->sinkcaps = NULL;
g_warning ("found something suitable\n"); return GST_PAD_CONNECT_REFUSED;
if (colorspace_setup_converter (space)) {
return GST_PAD_NEGOTIATE_AGREE;
} }
} }
return GST_PAD_NEGOTIATE_FAIL; return GST_PAD_CONNECT_OK;
} }
static GstPadConnectReturn
gst_colorspace_srcconnect (GstPad *pad, GstCaps *caps)
{
return gst_colorspace_srcconnect_func (pad, caps, TRUE);
}
static GstPadConnectReturn
gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps)
{
GstColorspace *space;
GstCaps *peercaps;
GstCaps *ourcaps;
space = GST_COLORSPACE (gst_pad_get_parent (pad));
/* we cannot operate if we didn't get src caps */
ourcaps = space->sinkcaps;
if (!ourcaps) {
if (newcaps)
gst_pad_recalc_allowed_caps (space->sinkpad);
return GST_PAD_CONNECT_DELAYED;
}
/* first see if we can do the format natively by filtering the peer caps
* with our incomming caps */
peercaps = gst_caps_intersect (caps, ourcaps);
if (peercaps) {
/* see if the peer likes it too, it should as the caps say so.. */
if (gst_pad_try_set_caps (space->srcpad, peercaps)) {
space->type = GST_COLORSPACE_NONE;
space->disabled = FALSE;
return GST_PAD_CONNECT_OK;
}
}
/* then see what the peer has that matches the size */
peercaps = gst_caps_intersect (caps,
GST_CAPS_NEW (
"colorspace_filter",
"video/raw",
"width", GST_PROPS_INT (space->width),
"height", GST_PROPS_INT (space->height)
));
/* we are looping over the caps, so we have to get rid of the lists */
peercaps = gst_caps_normalize (peercaps);
/* loop over all possibilities and select the first one we can convert and
* is accepted by the peer */
while (peercaps) {
if (colorspace_setup_converter (space, ourcaps, peercaps)) {
if (gst_pad_try_set_caps (space->srcpad, peercaps)) {
space->disabled = FALSE;
return GST_PAD_CONNECT_OK;
}
}
peercaps = peercaps->next;
}
gst_element_error (GST_ELEMENT (space), "could not agree on caps with peer pads");
/* we disable ourself here */
space->disabled = TRUE;
return GST_PAD_CONNECT_REFUSED;
}
GType GType
gst_colorspace_get_type (void) gst_colorspace_get_type (void)
@ -340,6 +382,8 @@ gst_colorspace_class_init (GstColorspaceClass *klass)
gobject_class->set_property = gst_colorspace_set_property; gobject_class->set_property = gst_colorspace_set_property;
gobject_class->get_property = gst_colorspace_get_property; gobject_class->get_property = gst_colorspace_get_property;
gstelement_class->change_state = gst_colorspace_change_state;
} }
static void static void
@ -347,21 +391,23 @@ gst_colorspace_init (GstColorspace *space)
{ {
space->sinkpad = gst_pad_new_from_template ( space->sinkpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (colorspace_sink_template_factory), "sink"); GST_PADTEMPLATE_GET (colorspace_sink_template_factory), "sink");
gst_pad_set_negotiate_function (space->sinkpad, colorspace_negotiate_sink); gst_pad_set_connect_function (space->sinkpad, gst_colorspace_sinkconnect);
gst_pad_set_getcaps_function (space->sinkpad, gst_colorspace_getcaps);
gst_pad_set_bufferpool_function (space->sinkpad, colorspace_get_bufferpool); gst_pad_set_bufferpool_function (space->sinkpad, colorspace_get_bufferpool);
gst_pad_set_chain_function(space->sinkpad,gst_colorspace_chain); gst_pad_set_chain_function(space->sinkpad,gst_colorspace_chain);
gst_element_add_pad(GST_ELEMENT(space),space->sinkpad); gst_element_add_pad(GST_ELEMENT(space),space->sinkpad);
space->srcpad = gst_pad_new_from_template ( space->srcpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (colorspace_src_template_factory), "src"); GST_PADTEMPLATE_GET (colorspace_src_template_factory), "src");
gst_pad_set_negotiate_function (space->srcpad, colorspace_negotiate_src);
gst_element_add_pad(GST_ELEMENT(space),space->srcpad); gst_element_add_pad(GST_ELEMENT(space),space->srcpad);
gst_pad_set_connect_function (space->srcpad, gst_colorspace_srcconnect);
#ifdef HAVE_LIBHERMES #ifdef HAVE_HERMES
space->h_handle = Hermes_ConverterInstance (0); space->h_handle = Hermes_ConverterInstance (0);
#endif #endif
space->pool = NULL; space->pool = NULL;
space->converter = NULL; space->converter = NULL;
space->disabled = TRUE;
} }
static void static void
@ -380,16 +426,17 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
g_return_if_fail (space != NULL); g_return_if_fail (space != NULL);
g_return_if_fail (GST_IS_COLORSPACE (space)); g_return_if_fail (GST_IS_COLORSPACE (space));
if (space->disabled) {
gst_buffer_unref (buf);
return;
}
if (space->type == GST_COLORSPACE_NONE) { if (space->type == GST_COLORSPACE_NONE) {
outbuf = buf; outbuf = buf;
} }
else { else {
gint dest_bytes, src_bytes; gint dest_bytes, src_bytes;
if (!space->pool) {
space->pool = gst_pad_get_bufferpool (space->srcpad);
}
size = space->width * space->height; size = space->width * space->height;
dest_bytes = ((space->destbpp+7)/8); dest_bytes = ((space->destbpp+7)/8);
src_bytes = ((space->srcbpp+7)/8); src_bytes = ((space->srcbpp+7)/8);
@ -408,7 +455,7 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
if (space->type == GST_COLORSPACE_YUV_RGB) { if (space->type == GST_COLORSPACE_YUV_RGB) {
gst_colorspace_convert (space->converter, GST_BUFFER_DATA (buf), GST_BUFFER_DATA (outbuf)); gst_colorspace_convert (space->converter, GST_BUFFER_DATA (buf), GST_BUFFER_DATA (outbuf));
} }
#ifdef HAVE_LIBHERMES #ifdef HAVE_HERMES
else if (space->type == GST_COLORSPACE_HERMES) { else if (space->type == GST_COLORSPACE_HERMES) {
Hermes_ConverterCopy (space->h_handle, Hermes_ConverterCopy (space->h_handle,
GST_BUFFER_DATA (buf), 0, 0, space->width, space->height, space->width * src_bytes, GST_BUFFER_DATA (buf), 0, 0, space->width, space->height, space->width * src_bytes,
@ -421,6 +468,18 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
space->width, space->width,
space->height); space->height);
} }
else if (space->type == GST_COLORSPACE_RGB32_I420) {
gst_colorspace_rgb32_to_i420 (GST_BUFFER_DATA (buf),
GST_BUFFER_DATA (outbuf),
space->width,
space->height);
}
else if (space->type == GST_COLORSPACE_RGB32_YV12) {
gst_colorspace_rgb32_to_yv12 (GST_BUFFER_DATA (buf),
GST_BUFFER_DATA (outbuf),
space->width,
space->height);
}
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
@ -429,6 +488,27 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf)
gst_pad_push (space->srcpad, outbuf); gst_pad_push (space->srcpad, outbuf);
} }
static GstElementStateReturn
gst_colorspace_change_state (GstElement *element)
{
GstColorspace *space;
space = GST_COLORSPACE (element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PAUSED_TO_PLAYING:
space->pool = gst_pad_get_bufferpool (space->srcpad);
break;
case GST_STATE_PLAYING_TO_PAUSED:
space->pool = NULL;
break;
}
parent_class->change_state (element);
return GST_STATE_SUCCESS;
}
static void static void
gst_colorspace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) gst_colorspace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{ {
@ -464,7 +544,7 @@ static gboolean
plugin_init (GModule *module, GstPlugin *plugin) plugin_init (GModule *module, GstPlugin *plugin)
{ {
GstElementFactory *factory; GstElementFactory *factory;
#ifdef HAVE_LIBHERMES #ifdef HAVE_HERMES
gint hermes_res; gint hermes_res;
hermes_res = Hermes_Init(); hermes_res = Hermes_Init();

View file

@ -26,7 +26,7 @@
#include <gst/gst.h> #include <gst/gst.h>
#include "yuv2rgb.h" #include "yuv2rgb.h"
#ifdef HAVE_LIBHERMES #ifdef HAVE_HERMES
# include <Hermes/Hermes.h> # include <Hermes/Hermes.h>
#endif #endif
@ -57,6 +57,8 @@ typedef enum {
GST_COLORSPACE_HERMES, GST_COLORSPACE_HERMES,
GST_COLORSPACE_YUV_RGB, GST_COLORSPACE_YUV_RGB,
GST_COLORSPACE_YUY2_I420, GST_COLORSPACE_YUY2_I420,
GST_COLORSPACE_RGB32_I420,
GST_COLORSPACE_RGB32_YV12,
} GstColorSpaceConverterType; } GstColorSpaceConverterType;
struct _GstColorspace { struct _GstColorspace {
@ -64,7 +66,7 @@ struct _GstColorspace {
GstPad *sinkpad,*srcpad; GstPad *sinkpad,*srcpad;
#ifdef HAVE_LIBHERMES #ifdef HAVE_HERMES
HermesHandle h_handle; HermesHandle h_handle;
HermesFormat source, dest; HermesFormat source, dest;
#endif #endif
@ -74,8 +76,8 @@ struct _GstColorspace {
GstColorSpaceConverterType type; GstColorSpaceConverterType type;
gint width, height; gint width, height;
gint srcbpp, destbpp; gint srcbpp, destbpp;
gboolean disabled;
GstCaps *srccaps;
GstCaps *sinkcaps; GstCaps *sinkcaps;
GstBufferPool *pool; GstBufferPool *pool;

150
ext/hermes/rgb2yuv.c Normal file
View file

@ -0,0 +1,150 @@
/*
*
* rgb2rgb.c, Software RGB to YUV convertor
* Written by Nick Kurshev.
* palette & yuv & runtime cpu stuff by Michael (michaelni@gmx.at) (under GPL)
*/
#include "config.h"
#include <math.h>
#include <stdlib.h>
#include <gst/gst.h>
#define RGB2YUV_SHIFT 8
#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
#define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5))
#define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
#define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5))
#define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5))
#define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5))
#define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5))
#define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5))
#define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5))
/**
*
* height should be a multiple of 2 and width should be a multiple of 2 (if this is a
* problem for anyone then tell me, and ill fix it)
* chrominance data is only taken from every secound line others are ignored FIXME write HQ version
*/
void
gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height)
{
int y;
const int chrom_width = width >> 1;
const int chrom_size = (width * height) >> 2;
unsigned char *ydst = dest;
unsigned char *udst = ydst + (width * height);
unsigned char *vdst = udst + chrom_size;
for (y = 0; y < height; y += 2) {
int i;
for (i = 0; i < chrom_width; i++) {
unsigned int b = src[8 * i + 0];
unsigned int g = src[8 * i + 1];
unsigned int r = src[8 * i + 2];
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128;
unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128;
udst[i] = U;
vdst[i] = V;
ydst[2 * i] = Y;
b = src[8 * i + 4];
g = src[8 * i + 5];
r = src[8 * i + 6];
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
ydst[2 * i + 1] = Y;
}
ydst += width;
src += (width * 4);
for (i = 0; i < chrom_width; i++) {
unsigned int b = src[8 * i + 0];
unsigned int g = src[8 * i + 1];
unsigned int r = src[8 * i + 2];
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
ydst[2 * i] = Y;
b = src[8 * i + 4];
g = src[8 * i + 5];
r = src[8 * i + 6];
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
ydst[2 * i + 1] = Y;
}
udst += chrom_width;
vdst += chrom_width;
ydst += width;
src += (width * 4);
}
}
void
gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height)
{
int y;
const int chrom_width = width >> 1;
const int chrom_size = (width * height) >> 2;
unsigned char *ydst = dest;
unsigned char *vdst = ydst + (width * height);
unsigned char *udst = vdst + chrom_size;
for (y = 0; y < height; y += 2) {
int i;
for (i = 0; i < chrom_width; i++) {
unsigned int b = src[8 * i + 0];
unsigned int g = src[8 * i + 1];
unsigned int r = src[8 * i + 2];
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128;
unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128;
udst[i] = U;
vdst[i] = V;
ydst[2 * i] = Y;
b = src[8 * i + 4];
g = src[8 * i + 5];
r = src[8 * i + 6];
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
ydst[2 * i + 1] = Y;
}
ydst += width;
src += (width * 4);
for (i = 0; i < chrom_width; i++) {
unsigned int b = src[8 * i + 0];
unsigned int g = src[8 * i + 1];
unsigned int r = src[8 * i + 2];
unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
ydst[2 * i] = Y;
b = src[8 * i + 4];
g = src[8 * i + 5];
r = src[8 * i + 6];
Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16;
ydst[2 * i + 1] = Y;
}
udst += chrom_width;
vdst += chrom_width;
ydst += width;
src += (width * 4);
}
}

View file

@ -85,9 +85,9 @@ static GstPadTemplate *srctempl, *sinktempl;
static void gst_ladspa_class_init (GstLADSPAClass *klass); static void gst_ladspa_class_init (GstLADSPAClass *klass);
static void gst_ladspa_init (GstLADSPA *ladspa); static void gst_ladspa_init (GstLADSPA *ladspa);
static GstPadNegotiateReturn gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data); //static GstPadNegotiateReturn gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data);
static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data); //static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data);
static GstPadNegotiateReturn gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data); //static GstPadNegotiateReturn gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data);
static void gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad); static void gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad);
static void gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
@ -347,9 +347,9 @@ gst_ladspa_init (GstLADSPA *ladspa)
// mono chain // mono chain
if (sinkcount==1 && srccount==1){ if (sinkcount==1 && srccount==1){
//g_print("inplace mono chain mode\n"); //g_print("inplace mono chain mode\n");
gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono); //gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono);
gst_pad_set_chain_function(ladspa->sinkpads[0],gst_ladspa_chain_inplace_mono); gst_pad_set_chain_function(ladspa->sinkpads[0],gst_ladspa_chain_inplace_mono);
gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono); //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono);
} }
// mono get (no sink pads) // mono get (no sink pads)
@ -359,7 +359,7 @@ gst_ladspa_init (GstLADSPA *ladspa)
ladspa->samplerate = 44100; ladspa->samplerate = 44100;
ladspa->buffersize = 64; ladspa->buffersize = 64;
gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get_mono); gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get_mono);
gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono); //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
gst_ladspa_instantiate(ladspa); gst_ladspa_instantiate(ladspa);
} }
@ -370,12 +370,13 @@ gst_ladspa_init (GstLADSPA *ladspa)
ladspa->samplerate = 44100; ladspa->samplerate = 44100;
ladspa->buffersize = 64; ladspa->buffersize = 64;
gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get); gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get);
gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono); //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
gst_ladspa_instantiate(ladspa); gst_ladspa_instantiate(ladspa);
ladspa->buffers = g_new0(GstBuffer*,oclass->numsrcpads); ladspa->buffers = g_new0(GstBuffer*,oclass->numsrcpads);
} }
} }
#if 0
static GstPadNegotiateReturn static GstPadNegotiateReturn
gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data) gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data)
{ {
@ -416,12 +417,13 @@ gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data)
} }
return GST_PAD_NEGOTIATE_FAIL; return GST_PAD_NEGOTIATE_FAIL;
} }
#endif
static void static void
gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad) { gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad) {
// g_print("forcing caps\n"); // g_print("forcing caps\n");
gst_pad_set_caps (pad, gst_caps_new ( gst_pad_try_set_caps (pad, gst_caps_new (
"ladspa_src_caps", "ladspa_src_caps",
"audio/raw", "audio/raw",
gst_props_new ( gst_props_new (

View file

@ -44,6 +44,7 @@ struct _GstChart {
gint depth; gint depth;
gint width; gint width;
gint height; gint height;
gboolean first_buffer;
gint samplerate; gint samplerate;
gint framerate; // desired frame rate gint framerate; // desired frame rate
@ -162,10 +163,10 @@ static void gst_chart_get_property (GObject *object, guint prop_id, GValue *valu
static void gst_chart_chain (GstPad *pad, GstBuffer *buf); static void gst_chart_chain (GstPad *pad, GstBuffer *buf);
static GstElementClass *parent_class = NULL; static GstPadConnectReturn
gst_chart_sinkconnect (GstPad *pad, GstCaps *caps);
static void gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps); static GstElementClass *parent_class = NULL;
static void gst_chart_newsrccaps (GstPad *pad, GstCaps *caps);
GType GType
gst_chart_get_type (void) gst_chart_get_type (void)
@ -211,9 +212,7 @@ gst_chart_init (GstChart *chart)
gst_element_add_pad (GST_ELEMENT (chart), chart->srcpad); gst_element_add_pad (GST_ELEMENT (chart), chart->srcpad);
gst_pad_set_chain_function (chart->sinkpad, gst_chart_chain); gst_pad_set_chain_function (chart->sinkpad, gst_chart_chain);
gst_pad_set_newcaps_function (chart->sinkpad, gst_chart_newsinkcaps); gst_pad_set_connect_function (chart->sinkpad, gst_chart_sinkconnect);
gst_pad_set_newcaps_function (chart->srcpad, gst_chart_newsrccaps);
chart->next_time = 0; chart->next_time = 0;
chart->peerpool = NULL; chart->peerpool = NULL;
@ -221,8 +220,9 @@ gst_chart_init (GstChart *chart)
// reset the initial video state // reset the initial video state
chart->bpp = 16; chart->bpp = 16;
chart->depth = 16; chart->depth = 16;
chart->width = -1; chart->first_buffer = TRUE;
chart->height = -1; chart->width = 256;
chart->height = 128;
chart->samplerate = -1; chart->samplerate = -1;
chart->framerate = 25; // desired frame rate chart->framerate = 25; // desired frame rate
@ -230,8 +230,8 @@ gst_chart_init (GstChart *chart)
chart->samples_since_last_frame = 0; chart->samples_since_last_frame = 0;
} }
static void static GstPadConnectReturn
gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps) gst_chart_sinkconnect (GstPad *pad, GstCaps *caps)
{ {
GstChart *chart; GstChart *chart;
chart = GST_CHART (gst_pad_get_parent (pad)); chart = GST_CHART (gst_pad_get_parent (pad));
@ -242,22 +242,8 @@ gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps)
GST_DEBUG (0, "CHART: new sink caps: rate %d\n", GST_DEBUG (0, "CHART: new sink caps: rate %d\n",
chart->samplerate); chart->samplerate);
//gst_chart_sync_parms (chart); //gst_chart_sync_parms (chart);
} //
return GST_PAD_CONNECT_OK;
static void
gst_chart_newsrccaps (GstPad *pad, GstCaps *caps)
{
GstChart *chart;
chart = GST_CHART (gst_pad_get_parent (pad));
chart->bpp = gst_caps_get_int (caps, "bpp");
chart->depth = gst_caps_get_int (caps, "depth");
chart->width = gst_caps_get_int (caps, "width");
chart->height = gst_caps_get_int (caps, "height");
GST_DEBUG (0, "CHART: new src caps: bpp %d, depth %d, width %d, height %d\n",
chart->bpp, chart->depth, chart->width, chart->height);
//gst_chart_sync_parms (chart);
} }
static void static void
@ -347,28 +333,6 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin)
if (chart->samples_between_frames <= chart->samples_since_last_frame) { if (chart->samples_between_frames <= chart->samples_since_last_frame) {
chart->samples_since_last_frame = 0; chart->samples_since_last_frame = 0;
// Check if we need to renegotiate size.
if (chart->width == -1 || chart->height == -1) {
chart->width = 256;
chart->height = 128;
GST_DEBUG (0, "making new pad\n");
gst_pad_set_caps (chart->srcpad,
gst_caps_new (
"chartsrc",
"video/raw",
gst_props_new (
"format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')),
"bpp", GST_PROPS_INT (chart->bpp),
"depth", GST_PROPS_INT (chart->depth),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"red_mask", GST_PROPS_INT (0xf800),
"green_mask", GST_PROPS_INT (0x07e0),
"blue_mask", GST_PROPS_INT (0x001f),
"width", GST_PROPS_INT (chart->width),
"height", GST_PROPS_INT (chart->height),
NULL)));
}
// get data to draw into buffer // get data to draw into buffer
if (samples_in >= chart->width) { if (samples_in >= chart->width) {
// make a new buffer for the output // make a new buffer for the output
@ -384,9 +348,35 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin)
// FIXME: call different routines for different properties // FIXME: call different routines for different properties
draw_chart_16bpp(dataout, chart->width, chart->height, (gint16 *)datain, samples_in); draw_chart_16bpp(dataout, chart->width, chart->height, (gint16 *)datain, samples_in);
gst_buffer_unref(bufin);
// set timestamp // set timestamp
GST_BUFFER_TIMESTAMP (bufout) = chart->next_time; GST_BUFFER_TIMESTAMP (bufout) = chart->next_time;
// Check if we need to renegotiate size.
if (chart->first_buffer) {
GST_DEBUG (0, "making new pad\n");
if (!gst_pad_try_set_caps (chart->srcpad,
GST_CAPS_NEW (
"chartsrc",
"video/raw",
"format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')),
"bpp", GST_PROPS_INT (chart->bpp),
"depth", GST_PROPS_INT (chart->depth),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"red_mask", GST_PROPS_INT (0xf800),
"green_mask", GST_PROPS_INT (0x07e0),
"blue_mask", GST_PROPS_INT (0x001f),
"width", GST_PROPS_INT (chart->width),
"height", GST_PROPS_INT (chart->height)
)))
{
gst_element_error (GST_ELEMENT (chart), "could not set caps");
return;
}
chart->first_buffer = FALSE;
}
GST_DEBUG (0, "CHART: outputting buffer\n"); GST_DEBUG (0, "CHART: outputting buffer\n");
// output buffer // output buffer
GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_READONLY); GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_READONLY);
@ -394,9 +384,9 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin)
} }
} else { } else {
GST_DEBUG (0, "CHART: skipping buffer\n"); GST_DEBUG (0, "CHART: skipping buffer\n");
gst_buffer_unref(bufin);
} }
gst_buffer_unref(bufin);
GST_DEBUG (0, "CHART: exiting chainfunc\n"); GST_DEBUG (0, "CHART: exiting chainfunc\n");
} }

View file

@ -54,7 +54,9 @@ GST_PADTEMPLATE_FACTORY (deinterlace_src_factory,
GST_CAPS_NEW ( GST_CAPS_NEW (
"deinterlace_src", "deinterlace_src",
"video/raw", "video/raw",
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
"width", GST_PROPS_INT_POSITIVE,
"height", GST_PROPS_INT_POSITIVE
) )
) )
@ -65,7 +67,9 @@ GST_PADTEMPLATE_FACTORY (deinterlace_sink_factory,
GST_CAPS_NEW ( GST_CAPS_NEW (
"deinterlace_src", "deinterlace_src",
"video/raw", "video/raw",
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),
"width", GST_PROPS_INT_POSITIVE,
"height", GST_PROPS_INT_POSITIVE
) )
) )
@ -74,36 +78,16 @@ static GType gst_deinterlace_get_type (void);
static void gst_deinterlace_class_init (GstDeInterlaceClass *klass); static void gst_deinterlace_class_init (GstDeInterlaceClass *klass);
static void gst_deinterlace_init (GstDeInterlace *filter); static void gst_deinterlace_init (GstDeInterlace *filter);
static void gst_deinterlace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_deinterlace_set_property (GObject *object, guint prop_id,
static void gst_deinterlace_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); const GValue *value, GParamSpec *pspec);
static void gst_deinterlace_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void gst_deinterlace_chain (GstPad *pad, GstBuffer *buf); static void gst_deinterlace_chain (GstPad *pad, GstBuffer *buf);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
//static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; //static guint gst_filter_signals[LAST_SIGNAL] = { 0 };
static GstPadNegotiateReturn
deinterlace_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstDeInterlace* filter = GST_DEINTERLACE (gst_pad_get_parent (pad));
if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL;
return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps);
}
static GstPadNegotiateReturn
deinterlace_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstDeInterlace* filter = GST_DEINTERLACE (gst_pad_get_parent (pad));
if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL;
return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
}
static GType static GType
gst_deinterlace_get_type(void) { gst_deinterlace_get_type(void) {
static GType deinterlace_type = 0; static GType deinterlace_type = 0;
@ -152,12 +136,15 @@ gst_deinterlace_class_init (GstDeInterlaceClass *klass)
gobject_class->get_property = gst_deinterlace_get_property; gobject_class->get_property = gst_deinterlace_get_property;
} }
static void static GstPadConnectReturn
gst_deinterlace_newcaps (GstPad *pad, GstCaps *caps) gst_deinterlace_sinkconnect (GstPad *pad, GstCaps *caps)
{ {
GstDeInterlace *filter; GstDeInterlace *filter;
filter = GST_DEINTERLACE(gst_pad_get_parent (pad)); filter = GST_DEINTERLACE(gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
filter->width = gst_caps_get_int (caps, "width"); filter->width = gst_caps_get_int (caps, "width");
filter->height = gst_caps_get_int (caps, "height"); filter->height = gst_caps_get_int (caps, "height");
@ -168,19 +155,21 @@ gst_deinterlace_newcaps (GstPad *pad, GstCaps *caps)
filter->picsize = filter->width*filter->height; filter->picsize = filter->width*filter->height;
filter->src = g_malloc(filter->picsize); filter->src = g_malloc(filter->picsize);
} }
if (gst_pad_try_set_caps (filter->srcpad, caps)) {
return GST_PAD_CONNECT_OK;
}
return GST_PAD_CONNECT_REFUSED;
} }
static void static void
gst_deinterlace_init (GstDeInterlace *filter) gst_deinterlace_init (GstDeInterlace *filter)
{ {
filter->sinkpad = gst_pad_new_from_template(deinterlace_sink_factory (),"sink"); filter->sinkpad = gst_pad_new_from_template(deinterlace_sink_factory (),"sink");
gst_pad_set_negotiate_function(filter->sinkpad,deinterlace_negotiate_sink);
gst_pad_set_chain_function(filter->sinkpad,gst_deinterlace_chain); gst_pad_set_chain_function(filter->sinkpad,gst_deinterlace_chain);
gst_pad_set_newcaps_function(filter->sinkpad,gst_deinterlace_newcaps); gst_pad_set_connect_function(filter->sinkpad,gst_deinterlace_sinkconnect);
gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
filter->srcpad = gst_pad_new_from_template(deinterlace_src_factory (),"src"); filter->srcpad = gst_pad_new_from_template(deinterlace_src_factory (),"src");
gst_pad_set_negotiate_function(filter->srcpad,deinterlace_negotiate_src);
gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);
filter->show_deinterlaced_area_only = FALSE; filter->show_deinterlaced_area_only = FALSE;

View file

@ -22,6 +22,8 @@
#include "flx_fmt.h" #include "flx_fmt.h"
#include "gstflxdec.h" #include "gstflxdec.h"
#define JIFFIE (1000000/70)
static GstCaps* flxdec_typefind(GstBuffer *buf, gpointer private); static GstCaps* flxdec_typefind(GstBuffer *buf, gpointer private);
/* flx element information */ /* flx element information */
@ -89,6 +91,9 @@ static void gst_flxdec_init (GstFlxDec *flxdec);
static void gst_flxdec_loop (GstElement *element); static void gst_flxdec_loop (GstElement *element);
static GstElementStateReturn
gst_flxdec_change_state (GstElement *element);
static void gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
@ -108,10 +113,10 @@ flxdec_typefind (GstBuffer *buf, gpointer private)
guchar *data = GST_BUFFER_DATA(buf); guchar *data = GST_BUFFER_DATA(buf);
GstCaps *new; GstCaps *new;
// check magic /* check magic */
if ((data[4] == 0x11 || data[4] == 0x12 if ((data[4] == 0x11 || data[4] == 0x12
|| data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) { || data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) {
// check the frame type of the first frame /* check the frame type of the first frame */
if ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1) { if ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1) {
g_print("GstFlxDec: found supported flx format\n"); g_print("GstFlxDec: found supported flx format\n");
new = gst_caps_new("flxdec_typefind","video/fli", NULL); new = gst_caps_new("flxdec_typefind","video/fli", NULL);
@ -158,6 +163,7 @@ gst_flxdec_class_init (GstFlxDecClass *klass)
gobject_class->set_property = NULL; gobject_class->set_property = NULL;
gobject_class->get_property = NULL; gobject_class->get_property = NULL;
gstelement_class->change_state = gst_flxdec_change_state;
} }
@ -175,9 +181,9 @@ gst_flxdec_init(GstFlxDec *flxdec)
gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->srcpad); gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->srcpad);
flxdec->buf = NULL; flxdec->buf = NULL;
flxdec->offset = 0; flxdec->bs = NULL;
flxdec->new_buf = TRUE; flxdec->frame = NULL;
flxdec->delta = NULL;
} }
static void static void
@ -428,15 +434,13 @@ flx_get_data(GstFlxDec *flxdec, gulong size)
g_return_val_if_fail (flxdec != NULL, NULL); g_return_val_if_fail (flxdec != NULL, NULL);
if (flxdec->new_buf) { retbuf = gst_bytestream_read (flxdec->bs, size);
retbuf = gst_pad_pullregion(flxdec->sinkpad, if (!retbuf) {
GST_REGION_OFFSET_LEN, 0, size); GstEvent *event;
flxdec->new_buf = FALSE; guint32 remaining;
flxdec->offset = size;
} else { gst_bytestream_get_status (flxdec->bs, &remaining, &event);
retbuf = gst_pad_pullregion(flxdec->sinkpad, GST_REGION_OFFSET_LEN, gst_pad_event_default (flxdec->sinkpad, event);
flxdec->offset, size);
flxdec->offset += size;
} }
return retbuf; return retbuf;
@ -461,33 +465,41 @@ gst_flxdec_loop (GstElement *element)
flxdec = GST_FLXDEC(element); flxdec = GST_FLXDEC(element);
databuf = flx_get_data(flxdec, FlxHeaderSize); if (flxdec->state == GST_FLXDEC_READ_HEADER) {
databuf = flx_get_data(flxdec, FlxHeaderSize);
g_return_if_fail (databuf != NULL); data = GST_BUFFER_DATA(databuf);
data = GST_BUFFER_DATA(databuf); memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader));
memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader)); gst_buffer_unref (databuf);
gst_buffer_unref (databuf); flxh = &flxdec->hdr;
flxh = &flxdec->hdr; /* check header */
if (flxh->type != FLX_MAGICHDR_FLI &&
// check header
if (flxh->type != FLX_MAGICHDR_FLI &&
flxh->type != FLX_MAGICHDR_FLC && flxh->type != FLX_MAGICHDR_FLC &&
flxh->type != FLX_MAGICHDR_FLX) flxh->type != FLX_MAGICHDR_FLX)
return; return;
g_print("GstFlxDec: size : %d\n", flxh->size); g_print("GstFlxDec: size : %d\n", flxh->size);
g_print("GstFlxDec: frames : %d\n", flxh->frames); g_print("GstFlxDec: frames : %d\n", flxh->frames);
g_print("GstFlxDec: width : %d\n", flxh->width); g_print("GstFlxDec: width : %d\n", flxh->width);
g_print("GstFlxDec: height : %d\n", flxh->height); g_print("GstFlxDec: height : %d\n", flxh->height);
g_print("GstFlxDec: depth : %d\n", flxh->depth); g_print("GstFlxDec: depth : %d\n", flxh->depth);
g_print("GstFlxDec: speed : %d\n", flxh->speed); g_print("GstFlxDec: speed : %d\n", flxh->speed);
gst_pad_set_caps (flxdec->srcpad, flxdec->next_time = 0;
if (flxh->type == FLX_MAGICHDR_FLI) {
flxdec->frame_time = JIFFIE * flxh->speed;
}
else {
flxdec->frame_time = flxh->speed * 1000;
}
gst_pad_try_set_caps (flxdec->srcpad,
gst_caps_new ( gst_caps_new (
"src_video", "src_video",
"video/raw", "video/raw",
@ -503,41 +515,37 @@ gst_flxdec_loop (GstElement *element)
"height", GST_PROPS_INT (flxh->height), "height", GST_PROPS_INT (flxh->height),
NULL))); NULL)));
if (flxh->depth <= 8) if (flxh->depth <= 8)
flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height); flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height);
if (flxh->type == FLX_MAGICHDR_FLC || if (flxh->type == FLX_MAGICHDR_FLC ||
flxh->type == FLX_MAGICHDR_FLX) { flxh->type == FLX_MAGICHDR_FLX) {
g_print("GstFlxDec: (FLC) aspect_dx : %d\n", g_print("GstFlxDec: (FLC) aspect_dx : %d\n", flxh->aspect_dx);
flxh->aspect_dx); g_print("GstFlxDec: (FLC) aspect_dy : %d\n", flxh->aspect_dy);
g_print("GstFlxDec: (FLC) aspect_dy : %d\n", g_print("GstFlxDec: (FLC) oframe1 : 0x%08x\n", flxh->oframe1);
flxh->aspect_dy); g_print("GstFlxDec: (FLC) oframe2 : 0x%08x\n", flxh->oframe2);
g_print("GstFlxDec: (FLC) oframe1 : 0x%08x\n", }
flxh->oframe1);
g_print("GstFlxDec: (FLC) oframe2 : 0x%08x\n",
flxh->oframe2); flxdec->size = (flxh->width * flxh->height);
/* create delta and output frame */
flxdec->frame = gst_buffer_new();
flxdec->delta = gst_buffer_new();
GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size);
GST_BUFFER_SIZE(flxdec->frame) = flxdec->size;
GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size);
GST_BUFFER_SIZE(flxdec->delta) = flxdec->size;
flxdec->state = GST_FLXDEC_PLAYING;
} }
else if (flxdec->state == GST_FLXDEC_PLAYING) {
flxdec->size = (flxh->width * flxh->height);
// create delta and output frame
flxdec->frame = gst_buffer_new();
flxdec->delta = gst_buffer_new();
GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size);
GST_BUFFER_SIZE(flxdec->frame) = flxdec->size;
GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size);
GST_BUFFER_SIZE(flxdec->delta) = flxdec->size;
do
{
databuf = flx_get_data(flxdec, FlxFrameChunkSize); databuf = flx_get_data(flxdec, FlxFrameChunkSize);
flxfh = (FlxFrameChunk *) GST_BUFFER_DATA(databuf); flxfh = (FlxFrameChunk *) GST_BUFFER_DATA(databuf);
switch(flxfh->id) switch(flxfh->id) {
{
case FLX_FRAME_TYPE: case FLX_FRAME_TYPE:
buf = flx_get_data(flxdec, flxfh->size-FlxFrameChunkSize); buf = flx_get_data(flxdec, flxfh->size-FlxFrameChunkSize);
@ -546,43 +554,74 @@ gst_flxdec_loop (GstElement *element)
if (((FlxFrameType *)chunk)->chunks == 0) if (((FlxFrameType *)chunk)->chunks == 0)
break; break;
// create 32 bits output frame /* create 32 bits output frame */
flxdec->out = gst_buffer_new(); flxdec->out = gst_buffer_new();
GST_BUFFER_DATA(flxdec->out) = g_malloc(flxdec->size * 4); GST_BUFFER_DATA(flxdec->out) = g_malloc(flxdec->size * 4);
GST_BUFFER_SIZE(flxdec->out) = flxdec->size * 4; GST_BUFFER_SIZE(flxdec->out) = flxdec->size * 4;
// decode chunks /* decode chunks */
flx_decode_chunks(flxdec, flx_decode_chunks(flxdec,
((FlxFrameType *)chunk)->chunks, ((FlxFrameType *)chunk)->chunks,
GST_BUFFER_DATA(buf) + FlxFrameTypeSize, GST_BUFFER_DATA(buf) + FlxFrameTypeSize,
GST_BUFFER_DATA(flxdec->frame)); GST_BUFFER_DATA(flxdec->frame));
// destroy input buffer /* destroy input buffer*/
gst_buffer_unref(buf); gst_buffer_unref(buf);
// save copy of the current frame for possible delta. /* save copy of the current frame for possible delta. */
memcpy(GST_BUFFER_DATA(flxdec->delta), memcpy(GST_BUFFER_DATA(flxdec->delta),
GST_BUFFER_DATA(flxdec->frame), GST_BUFFER_DATA(flxdec->frame),
GST_BUFFER_SIZE(flxdec->delta)); GST_BUFFER_SIZE(flxdec->delta));
// convert current frame. /* convert current frame. */
flx_colorspace_convert(flxdec->converter, flx_colorspace_convert(flxdec->converter,
GST_BUFFER_DATA(flxdec->frame), GST_BUFFER_DATA(flxdec->frame),
GST_BUFFER_DATA(flxdec->out)); GST_BUFFER_DATA(flxdec->out));
GST_BUFFER_TIMESTAMP (flxdec->out) = flxdec->next_time;
flxdec->next_time += flxdec->frame_time;
gst_pad_push(flxdec->srcpad, flxdec->out); gst_pad_push(flxdec->srcpad, flxdec->out);
break; break;
} }
// destroy header buffer /* destroy header buffer */
gst_buffer_unref(databuf); gst_buffer_unref(databuf);
gst_element_yield (element);
} }
while (TRUE); }
static GstElementStateReturn
gst_flxdec_change_state (GstElement *element)
{
GstFlxDec *flxdec;
flxdec = GST_FLXDEC(element);
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
flxdec->bs = gst_bytestream_new (flxdec->sinkpad);
break;
case GST_STATE_READY_TO_PAUSED:
flxdec->state = GST_FLXDEC_READ_HEADER;
break;
case GST_STATE_PAUSED_TO_PLAYING:
break;
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
gst_buffer_unref (flxdec->frame);
gst_buffer_unref (flxdec->delta);
break;
case GST_STATE_READY_TO_NULL:
gst_bytestream_destroy (flxdec->bs);
break;
}
parent_class->change_state (element);
return GST_STATE_SUCCESS;
} }
static void static void
@ -622,6 +661,12 @@ plugin_init (GModule *module, GstPlugin *plugin)
GstElementFactory *factory; GstElementFactory *factory;
GstTypeFactory *type; GstTypeFactory *type;
/* this filter needs the bytestream package */
if (!gst_library_load("gstbytestream")) {
gst_info("flxdec:: could not load support library: 'gstbytestream'\n");
return FALSE;
}
factory = gst_elementfactory_new("flxdec", GST_TYPE_FLXDEC, &flxdec_details); factory = gst_elementfactory_new("flxdec", GST_TYPE_FLXDEC, &flxdec_details);
g_return_val_if_fail(factory != NULL, FALSE); g_return_val_if_fail(factory != NULL, FALSE);

View file

@ -23,23 +23,35 @@
#include <gst/gst.h> #include <gst/gst.h>
#include "flx_color.h" #include "flx_color.h"
#include <gst/bytestream/bytestream.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
typedef enum {
GST_FLXDEC_READ_HEADER,
GST_FLXDEC_PLAYING,
} GstFlxDecState;
/* Definition of structure storing data for this element. */ /* Definition of structure storing data for this element. */
typedef struct _GstFlxDec GstFlxDec; typedef struct _GstFlxDec GstFlxDec;
struct _GstFlxDec { struct _GstFlxDec {
GstElement element; GstElement element;
GstPad *sinkpad,*srcpad; GstPad *sinkpad,*srcpad;
gboolean active, new_meta, new_buf; gboolean active, new_meta;
GstBuffer *buf, *out, *delta, *frame; GstBuffer *buf, *out, *delta, *frame;
gulong offset, size; GstByteStream *bs;
gulong size;
GstFlxDecState state;
glong frame_time;
gint64 next_time;
FlxColorSpaceConverter *converter; FlxColorSpaceConverter *converter;
@ -64,9 +76,6 @@ struct _GstFlxDecClass {
#define GST_IS_FLXDEC_CLASS(obj) \ #define GST_IS_FLXDEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLXDEC)) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLXDEC))
#define FLXDEC_BUFSIZE(buf, offset) \
((GST_BUFFER_OFFSET(buf) + GST_BUFFER_SIZE(buf)) - offset)
/* Standard function returning type information. */ /* Standard function returning type information. */
GType gst_flxdec_get_type(void); GType gst_flxdec_get_type(void);

View file

@ -138,12 +138,10 @@ static void
gst_mp1videoparse_init (Mp1VideoParse *mp1videoparse) gst_mp1videoparse_init (Mp1VideoParse *mp1videoparse)
{ {
mp1videoparse->sinkpad = gst_pad_new_from_template (sink_template, "sink"); mp1videoparse->sinkpad = gst_pad_new_from_template (sink_template, "sink");
gst_pad_set_caps (mp1videoparse->sinkpad, gst_pad_get_padtemplate_caps (mp1videoparse->sinkpad));
gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->sinkpad); gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->sinkpad);
gst_pad_set_chain_function(mp1videoparse->sinkpad,gst_mp1videoparse_chain); gst_pad_set_chain_function(mp1videoparse->sinkpad,gst_mp1videoparse_chain);
mp1videoparse->srcpad = gst_pad_new_from_template (src_template, "src"); mp1videoparse->srcpad = gst_pad_new_from_template (src_template, "src");
gst_pad_set_caps (mp1videoparse->srcpad, gst_pad_get_padtemplate_caps (mp1videoparse->srcpad));
gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->srcpad); gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->srcpad);
mp1videoparse->partialbuf = NULL; mp1videoparse->partialbuf = NULL;

View file

@ -142,7 +142,6 @@ static void
gst_mp3parse_init (GstMPEGAudioParse *mp3parse) gst_mp3parse_init (GstMPEGAudioParse *mp3parse)
{ {
mp3parse->sinkpad = gst_pad_new_from_template(sink_temp, "sink"); mp3parse->sinkpad = gst_pad_new_from_template(sink_temp, "sink");
//gst_pad_set_caps(mp3parse->sinkpad, gst_pad_get_padtemplate_caps (mp3parse->sinkpad));
gst_element_add_pad(GST_ELEMENT(mp3parse),mp3parse->sinkpad); gst_element_add_pad(GST_ELEMENT(mp3parse),mp3parse->sinkpad);
#if 1 // set this to one to use the old chaining code #if 1 // set this to one to use the old chaining code

View file

@ -107,6 +107,7 @@ passthrough_get_bufferpool (GstPad *pad)
return gst_pad_get_bufferpool (filter->srcpad); return gst_pad_get_bufferpool (filter->srcpad);
} }
/*
static GstPadNegotiateReturn static GstPadNegotiateReturn
passthrough_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) passthrough_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{ {
@ -134,6 +135,7 @@ passthrough_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
} }
*/
static gint static gint
passthrough_parse_caps (GstPassthrough *filter, GstCaps *caps) passthrough_parse_caps (GstPassthrough *filter, GstCaps *caps)
@ -222,10 +224,10 @@ static void
passthrough_init (GstPassthrough *filter) passthrough_init (GstPassthrough *filter)
{ {
filter->sinkpad = gst_pad_new_from_template(passthrough_sink_factory (),"sink"); filter->sinkpad = gst_pad_new_from_template(passthrough_sink_factory (),"sink");
gst_pad_set_negotiate_function(filter->sinkpad,passthrough_negotiate_sink); //gst_pad_set_negotiate_function(filter->sinkpad,passthrough_negotiate_sink);
gst_pad_set_bufferpool_function(filter->sinkpad,passthrough_get_bufferpool); gst_pad_set_bufferpool_function(filter->sinkpad,passthrough_get_bufferpool);
filter->srcpad = gst_pad_new_from_template(passthrough_src_factory (),"src"); filter->srcpad = gst_pad_new_from_template(passthrough_src_factory (),"src");
gst_pad_set_negotiate_function(filter->srcpad,passthrough_negotiate_src); //gst_pad_set_negotiate_function(filter->srcpad,passthrough_negotiate_src);
gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);

View file

@ -117,6 +117,7 @@ play_on_demand_get_bufferpool (GstPad *pad)
return gst_pad_get_bufferpool(filter->srcpad); return gst_pad_get_bufferpool(filter->srcpad);
} }
/*
static GstPadNegotiateReturn static GstPadNegotiateReturn
play_on_demand_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) play_on_demand_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{ {
@ -144,6 +145,7 @@ play_on_demand_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
return gst_pad_negotiate_proxy(pad, filter->srcpad, caps); return gst_pad_negotiate_proxy(pad, filter->srcpad, caps);
} }
*/
static gint static gint
play_on_demand_parse_caps (GstPlayOnDemand *filter, GstCaps *caps) play_on_demand_parse_caps (GstPlayOnDemand *filter, GstCaps *caps)
@ -264,11 +266,11 @@ play_on_demand_init (GstPlayOnDemand *filter)
guint i; guint i;
filter->sinkpad = gst_pad_new_from_template(play_on_demand_sink_factory(), "sink"); filter->sinkpad = gst_pad_new_from_template(play_on_demand_sink_factory(), "sink");
gst_pad_set_negotiate_function(filter->sinkpad, play_on_demand_negotiate_sink); //gst_pad_set_negotiate_function(filter->sinkpad, play_on_demand_negotiate_sink);
gst_pad_set_bufferpool_function(filter->sinkpad, play_on_demand_get_bufferpool); gst_pad_set_bufferpool_function(filter->sinkpad, play_on_demand_get_bufferpool);
filter->srcpad = gst_pad_new_from_template(play_on_demand_src_factory(), "src"); filter->srcpad = gst_pad_new_from_template(play_on_demand_src_factory(), "src");
gst_pad_set_negotiate_function(filter->srcpad, play_on_demand_negotiate_src); //gst_pad_set_negotiate_function(filter->srcpad, play_on_demand_negotiate_src);
gst_element_add_pad(GST_ELEMENT(filter), filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter), filter->sinkpad);
gst_element_add_pad(GST_ELEMENT(filter), filter->srcpad); gst_element_add_pad(GST_ELEMENT(filter), filter->srcpad);

View file

@ -80,28 +80,6 @@ static void gst_smooth_get_property (GObject *object, guint prop_id, GValue *val
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
//static guint gst_smooth_signals[LAST_SIGNAL] = { 0 }; //static guint gst_smooth_signals[LAST_SIGNAL] = { 0 };
static GstPadNegotiateReturn
smooth_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstSmooth* filter = GST_SMOOTH (gst_pad_get_parent (pad));
if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL;
return gst_pad_negotiate_proxy (pad, filter->sinkpad, caps);
}
static GstPadNegotiateReturn
smooth_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstSmooth* filter = GST_SMOOTH (gst_pad_get_parent (pad));
if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL;
return gst_pad_negotiate_proxy (pad, filter->srcpad, caps);
}
GType GType
gst_smooth_get_type (void) gst_smooth_get_type (void)
{ {
@ -149,15 +127,20 @@ gst_smooth_class_init (GstSmoothClass *klass)
} }
static void static GstPadConnectReturn
gst_smooth_newcaps (GstPad *pad, GstCaps *caps) gst_smooth_sinkconnect (GstPad *pad, GstCaps *caps)
{ {
GstSmooth *filter; GstSmooth *filter;
filter = GST_SMOOTH (gst_pad_get_parent (pad)); filter = GST_SMOOTH (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
filter->width = gst_caps_get_int (caps, "width"); filter->width = gst_caps_get_int (caps, "width");
filter->height = gst_caps_get_int (caps, "height"); filter->height = gst_caps_get_int (caps, "height");
return GST_PAD_CONNECT_OK;
} }
static void static void
@ -165,14 +148,12 @@ gst_smooth_init (GstSmooth *smooth)
{ {
smooth->sinkpad = gst_pad_new_from_template ( smooth->sinkpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (smooth_sink_factory), "sink"); GST_PADTEMPLATE_GET (smooth_sink_factory), "sink");
gst_pad_set_negotiate_function (smooth->sinkpad, smooth_negotiate_sink); gst_pad_set_connect_function (smooth->sinkpad, gst_smooth_sinkconnect);
gst_pad_set_newcaps_function (smooth->sinkpad, gst_smooth_newcaps);
gst_pad_set_chain_function (smooth->sinkpad, gst_smooth_chain); gst_pad_set_chain_function (smooth->sinkpad, gst_smooth_chain);
gst_element_add_pad (GST_ELEMENT (smooth), smooth->sinkpad); gst_element_add_pad (GST_ELEMENT (smooth), smooth->sinkpad);
smooth->srcpad = gst_pad_new_from_template ( smooth->srcpad = gst_pad_new_from_template (
GST_PADTEMPLATE_GET (smooth_src_factory), "src"); GST_PADTEMPLATE_GET (smooth_src_factory), "src");
gst_pad_set_negotiate_function (smooth->srcpad, smooth_negotiate_src);
gst_element_add_pad (GST_ELEMENT (smooth), smooth->srcpad); gst_element_add_pad (GST_ELEMENT (smooth), smooth->srcpad);
smooth->active = TRUE; smooth->active = TRUE;

View file

@ -109,6 +109,7 @@ static void speed_loop (GstElement *element);
static GstElementClass *parent_class = NULL; static GstElementClass *parent_class = NULL;
//static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; //static guint gst_filter_signals[LAST_SIGNAL] = { 0 };
/*
static GstPadNegotiateReturn static GstPadNegotiateReturn
speed_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) speed_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{ {
@ -136,6 +137,7 @@ speed_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
} }
*/
static gint static gint
speed_parse_caps (GstSpeed *filter, GstCaps *caps) speed_parse_caps (GstSpeed *filter, GstCaps *caps)
@ -228,10 +230,10 @@ static void
speed_init (GstSpeed *filter) speed_init (GstSpeed *filter)
{ {
filter->sinkpad = gst_pad_new_from_template(speed_sink_factory (),"sink"); filter->sinkpad = gst_pad_new_from_template(speed_sink_factory (),"sink");
gst_pad_set_negotiate_function(filter->sinkpad,speed_negotiate_sink); //gst_pad_set_negotiate_function(filter->sinkpad,speed_negotiate_sink);
gst_pad_set_bufferpool_function (filter->sinkpad, speed_sink_get_bufferpool); gst_pad_set_bufferpool_function (filter->sinkpad, speed_sink_get_bufferpool);
filter->srcpad = gst_pad_new_from_template(speed_src_factory (),"src"); filter->srcpad = gst_pad_new_from_template(speed_src_factory (),"src");
gst_pad_set_negotiate_function(filter->srcpad,speed_negotiate_src); //gst_pad_set_negotiate_function(filter->srcpad,speed_negotiate_src);
gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);

View file

@ -115,15 +115,20 @@ gst_lavencode_class_init (GstLavEncodeClass *klass)
gobject_class->get_property = gst_lavencode_get_property; gobject_class->get_property = gst_lavencode_get_property;
} }
static void static GstPadConnectReturn
gst_lavencode_newcaps (GstPad *pad, GstCaps *caps) gst_lavencode_sinkconnect (GstPad *pad, GstCaps *caps)
{ {
GstLavEncode *filter; GstLavEncode *filter;
filter = GST_LAVENCODE (gst_pad_get_parent (pad)); filter = GST_LAVENCODE (gst_pad_get_parent (pad));
if (!GST_CAPS_IS_FIXED (caps))
return GST_PAD_CONNECT_DELAYED;
filter->width = gst_caps_get_int (caps, "width"); filter->width = gst_caps_get_int (caps, "width");
filter->height = gst_caps_get_int (caps, "height"); filter->height = gst_caps_get_int (caps, "height");
return GST_PAD_CONNECT_OK;
} }
static void static void
@ -133,7 +138,7 @@ gst_lavencode_init (GstLavEncode *filter)
GST_PADTEMPLATE_GET (lavencode_sink_factory), "sink"); GST_PADTEMPLATE_GET (lavencode_sink_factory), "sink");
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_pad_set_chain_function (filter->sinkpad, gst_lavencode_chain); gst_pad_set_chain_function (filter->sinkpad, gst_lavencode_chain);
gst_pad_set_newcaps_function (filter->sinkpad, gst_lavencode_newcaps); gst_pad_set_connect_function (filter->sinkpad, gst_lavencode_sinkconnect);
filter->srcpad = gst_pad_new_from_template( filter->srcpad = gst_pad_new_from_template(
GST_PADTEMPLATE_GET (lavencode_src_factory), "src"); GST_PADTEMPLATE_GET (lavencode_src_factory), "src");

View file

@ -245,7 +245,7 @@ gst_qcamsrc_get (GstPad *pad)
qc_set (qcamsrc->qcam); qc_set (qcamsrc->qcam);
if (!GST_PAD_CAPS (pad)) { if (!GST_PAD_CAPS (pad)) {
gst_pad_set_caps (pad, GST_CAPS_NEW ( gst_pad_try_set_caps (pad, GST_CAPS_NEW (
"qcam_caps", "qcam_caps",
"video/raw", "video/raw",
"format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),