diff options
Diffstat (limited to 'gst')
29 files changed, 916 insertions, 792 deletions
diff --git a/gst/cdxaparse/gstcdxaparse.c b/gst/cdxaparse/gstcdxaparse.c index 08e6f14c..1c2141b2 100644 --- a/gst/cdxaparse/gstcdxaparse.c +++ b/gst/cdxaparse/gstcdxaparse.c @@ -54,8 +54,8 @@ static GstCaps* cdxa_type_find (GstBuffer *buf, gpointer private); /* typefactory for 'cdxa' */ static GstTypeDefinition cdxadefinition = { - "cdxaparse_video/avi", - "video/avi", + "cdxaparse_video", + "video/x-cdxa", ".dat", cdxa_type_find, }; @@ -77,8 +77,8 @@ GST_PAD_TEMPLATE_FACTORY (sink_templ, GST_PAD_ALWAYS, GST_CAPS_NEW ( "cdxaparse_sink", - "video/avi", - "format", GST_PROPS_STRING ("CDXA") + "video/x-cdxa", + NULL ) ) @@ -89,7 +89,6 @@ GST_PAD_TEMPLATE_FACTORY (src_templ, GST_CAPS_NEW ( "cdxaparse_src", "video/mpeg", - "mpegversion", GST_PROPS_INT (1), "systemstream", GST_PROPS_BOOLEAN (TRUE) ) ) @@ -174,8 +173,8 @@ cdxa_type_find (GstBuffer *buf, return NULL; new = GST_CAPS_NEW ("cdxa_type_find", - "video/avi", - "RIFF", GST_PROPS_STRING ("CDXA")); + "video/x-cdxa", + NULL); return new; } diff --git a/gst/chart/gstchart.c b/gst/chart/gstchart.c index 97cb6fc0..bc86b893 100644 --- a/gst/chart/gstchart.c +++ b/gst/chart/gstchart.c @@ -22,6 +22,7 @@ #endif #include <config.h> #include <gst/gst.h> +#include <gst/video/video.h> #define GST_TYPE_CHART (gst_chart_get_type()) #define GST_CHART(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CHART,GstChart)) @@ -47,10 +48,9 @@ struct _GstChart { gint depth; gint width; gint height; - gboolean first_buffer; gint samplerate; - gint framerate; /* desired frame rate */ + gfloat framerate; /* desired frame rate */ gint samples_between_frames; /* number of samples between start of successive frames */ gint samples_since_last_frame; /* number of samples between start of successive frames */ }; @@ -84,79 +84,30 @@ enum { /* FILL ME */ }; -static GstPadTemplate* -src_template_factory (void) -{ - static GstPadTemplate *template = NULL; - - if (!template) { - template = gst_pad_template_new ( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - gst_caps_new ( - "chartsrc", - "video/raw", - /*gst_props_new ( - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')), - "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 (0xff00), - "blue_mask", GST_PROPS_INT (0xff), - "width", GST_PROPS_INT_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096), - NULL),*/ - gst_props_new ( - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')), - "bpp", GST_PROPS_INT (16), - "depth", GST_PROPS_INT (16), - "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_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096), - NULL) - ), - NULL); - } - return template; -} - -static GstPadTemplate* -sink_template_factory (void) -{ - static GstPadTemplate *template = NULL; - - if (!template) { - template = gst_pad_template_new ( - "sink", /* the name of the pads */ - GST_PAD_SINK, /* type of the pad */ - GST_PAD_ALWAYS, /* ALWAYS/SOMETIMES */ - gst_caps_new ( - "chartsink", /* the name of the caps */ - "audio/raw", /* the mime type of the caps */ - gst_props_new ( - /* Properties follow: */ - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (TRUE), - "width", GST_PROPS_INT (16), - "depth", GST_PROPS_INT (16), - "rate", GST_PROPS_INT_RANGE (8000, 96000), - "channels", GST_PROPS_INT (1), - NULL) - ), - NULL); - } - - return template; -} - - +GST_PAD_TEMPLATE_FACTORY (src_factory, + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + gst_caps_new ("chartsrc", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_16 + ) +); + +GST_PAD_TEMPLATE_FACTORY (sink_factory, + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_CAPS_NEW ("chartsink", + "audio/x-raw-int", + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "signed", GST_PROPS_BOOLEAN (TRUE), + "width", GST_PROPS_INT (16), + "depth", GST_PROPS_INT (16), + "rate", GST_PROPS_INT_RANGE (8000, 96000), + "channels", GST_PROPS_INT (1) + ) +); static void gst_chart_class_init (GstChartClass *klass); @@ -169,6 +120,8 @@ static void gst_chart_chain (GstPad *pad, GstBuffer *buf); static GstPadLinkReturn gst_chart_sinkconnect (GstPad *pad, GstCaps *caps); +static GstPadLinkReturn + gst_chart_srcconnect (GstPad *pad, GstCaps *caps); static GstElementClass *parent_class = NULL; @@ -210,13 +163,18 @@ static void gst_chart_init (GstChart *chart) { /* create the sink and src pads */ - chart->sinkpad = gst_pad_new_from_template (sink_template_factory (), "sink"); - chart->srcpad = gst_pad_new_from_template (src_template_factory (), "src"); + chart->sinkpad = gst_pad_new_from_template ( + GST_PAD_TEMPLATE_GET (sink_factory), + "sink"); + chart->srcpad = gst_pad_new_from_template ( + GST_PAD_TEMPLATE_GET (src_factory), + "src"); gst_element_add_pad (GST_ELEMENT (chart), chart->sinkpad); gst_element_add_pad (GST_ELEMENT (chart), chart->srcpad); gst_pad_set_chain_function (chart->sinkpad, gst_chart_chain); gst_pad_set_link_function (chart->sinkpad, gst_chart_sinkconnect); + gst_pad_set_link_function (chart->sinkpad, gst_chart_srcconnect); chart->next_time = 0; chart->peerpool = NULL; @@ -224,7 +182,6 @@ gst_chart_init (GstChart *chart) /* reset the initial video state */ chart->bpp = 16; chart->depth = 16; - chart->first_buffer = TRUE; chart->width = 256; chart->height = 128; @@ -250,6 +207,54 @@ gst_chart_sinkconnect (GstPad *pad, GstCaps *caps) return GST_PAD_LINK_OK; } +static GstPadLinkReturn +gst_chart_srcconnect (GstPad *pad, GstCaps *caps) +{ + GstChart *chart; + chart = GST_CHART (gst_pad_get_parent (pad)); + + if (gst_caps_has_property_typed (caps, "framerate", + GST_PROPS_FLOAT_TYPE)) { + gst_caps_get_float (caps, "framerate", &chart->framerate); + chart->samples_between_frames = chart->samplerate / chart->framerate; + } + + if (gst_caps_has_property_typed (caps, "width", + GST_PROPS_INT_TYPE)) { + gst_caps_get_int (caps, "width", &chart->width); + } + if (gst_caps_has_property_typed (caps, "height", + GST_PROPS_INT_TYPE)) { + gst_caps_get_int (caps, "height", &chart->height); + } + + GST_DEBUG ("CHART: new src caps: framerate %f, %dx%d", + chart->framerate, chart->width, chart->height); + + if (!GST_CAPS_IS_FIXED (caps)) { + GstPadLinkReturn ret; + GstCaps *newcaps; + newcaps = GST_CAPS_NEW ("chartsrc", + "video/x-raw-rgb", + "bpp", GST_PROPS_INT (chart->bpp), + "depth", GST_PROPS_INT (chart->depth), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "red_mask", GST_PROPS_INT (R_MASK_16), + "green_mask", GST_PROPS_INT (G_MASK_16), + "blue_mask", GST_PROPS_INT (B_MASK_16), + "width", GST_PROPS_INT (chart->width), + "height", GST_PROPS_INT (chart->height), + "framerate", GST_PROPS_FLOAT (chart->framerate)); + ret = gst_pad_try_set_caps (chart->srcpad, newcaps); + if (ret > 0) { + return GST_PAD_LINK_DONE; + } + return ret; + } + + return GST_PAD_LINK_OK; +} + static void draw_chart_16bpp(guchar * output, gint width, gint height, gint16 * src_data, gint src_size) @@ -352,27 +357,25 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin) GST_BUFFER_TIMESTAMP (bufout) = chart->next_time; /* Check if we need to renegotiate size. */ - if (chart->first_buffer) { + if (!GST_PAD_CAPS (chart->srcpad)) { + GstCaps *newcaps; GST_DEBUG ("making new pad"); - 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) - )) <= 0) - { - gst_element_error (GST_ELEMENT (chart), "could not set caps"); + newcaps = GST_CAPS_NEW ("chartsrc", + "video/x-raw-rgb", + "bpp", GST_PROPS_INT (chart->bpp), + "depth", GST_PROPS_INT (chart->depth), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "red_mask", GST_PROPS_INT (R_MASK_16), + "green_mask", GST_PROPS_INT (G_MASK_16), + "blue_mask", GST_PROPS_INT (B_MASK_16), + "width", GST_PROPS_INT (chart->width), + "height", GST_PROPS_INT (chart->height), + "framerate", GST_PROPS_FLOAT (chart->framerate)); + if (gst_pad_try_set_caps (chart->srcpad, newcaps) <= 0) { + gst_element_error (GST_ELEMENT (chart), + "chart: could not negotiate format"); return; } - chart->first_buffer = FALSE; } GST_DEBUG ("CHART: outputting buffer"); @@ -428,8 +431,10 @@ plugin_init (GModule *module, GstPlugin *plugin) &gst_chart_details); g_return_val_if_fail(factory != NULL, FALSE); - gst_element_factory_add_pad_template (factory, src_template_factory ()); - gst_element_factory_add_pad_template (factory, sink_template_factory ()); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (src_factory)); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (sink_factory)); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c index 76cc34b1..3a63eb17 100644 --- a/gst/deinterlace/gstdeinterlace.c +++ b/gst/deinterlace/gstdeinterlace.c @@ -58,10 +58,11 @@ GST_PAD_TEMPLATE_FACTORY (deinterlace_src_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "deinterlace_src", - "video/raw", + "video/x-raw-yuv", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), "width", GST_PROPS_INT_POSITIVE, - "height", GST_PROPS_INT_POSITIVE + "height", GST_PROPS_INT_POSITIVE, + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) ) ) @@ -71,10 +72,11 @@ GST_PAD_TEMPLATE_FACTORY (deinterlace_sink_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "deinterlace_src", - "video/raw", + "video/x-raw-yuv", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), "width", GST_PROPS_INT_POSITIVE, - "height", GST_PROPS_INT_POSITIVE + "height", GST_PROPS_INT_POSITIVE, + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) ) ) @@ -160,7 +162,7 @@ gst_deinterlace_sinkconnect (GstPad *pad, GstCaps *caps) filter->picsize = filter->width*filter->height; filter->src = g_malloc(filter->picsize); } - return gst_pad_try_set_caps (filter->srcpad, caps); + return gst_pad_try_set_caps (filter->srcpad, gst_caps_ref (caps)); } static void diff --git a/gst/festival/gstfestival.c b/gst/festival/gstfestival.c index 728b4556..7f40e3b0 100644 --- a/gst/festival/gstfestival.c +++ b/gst/festival/gstfestival.c @@ -75,6 +75,7 @@ #include <arpa/inet.h> #include "gstfestival.h" +#include <gst/audio/audio.h> static void gst_festival_class_init (GstFestivalClass *klass); static void gst_festival_init (GstFestival *festival); @@ -115,23 +116,10 @@ GST_PAD_TEMPLATE_FACTORY (src_template_factory, "festival_src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "festival_raw", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (TRUE), - "width", GST_PROPS_LIST ( - GST_PROPS_INT (8), - GST_PROPS_INT (16) - ), - "depth", GST_PROPS_LIST ( - GST_PROPS_INT (8), - GST_PROPS_INT (16) - ), - "rate", GST_PROPS_INT_RANGE (8000, 48000), - "channels", GST_PROPS_INT_RANGE (1, 2) + "audio/x-raw-int", + GST_AUDIO_INT_PAD_TEMPLATE_PROPS ) ) @@ -287,9 +275,7 @@ gst_festival_chain (GstPad *pad, GstBuffer *buf) gst_pad_try_set_caps (festival->srcpad, GST_CAPS_NEW ( "festival_src", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), + "audio/x-raw-int", "endianness", GST_PROPS_INT (G_BYTE_ORDER), "signed", GST_PROPS_BOOLEAN (TRUE), "width", GST_PROPS_INT (16), diff --git a/gst/filter/gstbpwsinc.c b/gst/filter/gstbpwsinc.c index 0e57a747..68af7a28 100644 --- a/gst/filter/gstbpwsinc.c +++ b/gst/filter/gstbpwsinc.c @@ -194,7 +194,7 @@ gst_bpwsinc_sink_connect (GstPad * pad, GstCaps * caps) if (!GST_CAPS_IS_FIXED (caps)) return GST_PAD_LINK_DELAYED; - set_retval = gst_pad_try_set_caps (filter->srcpad, caps); + set_retval = gst_pad_try_set_caps (filter->srcpad, gst_caps_ref (caps)); if (set_retval > 0) { diff --git a/gst/filter/gstfilter.c b/gst/filter/gstfilter.c index 0aee8525..f031bb6e 100644 --- a/gst/filter/gstfilter.c +++ b/gst/filter/gstfilter.c @@ -21,6 +21,7 @@ */ #include "gstfilter.h" +#include <gst/audio/audio.h> struct _elements_entry { @@ -46,15 +47,10 @@ gst_filter_src_factory (void) "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "filter_src", - "audio/raw", - "format", GST_PROPS_STRING ("float"), - "rate", GST_PROPS_INT_RANGE (1, G_MAXINT), - "layout", GST_PROPS_STRING ("gfloat"), - "intercept", GST_PROPS_FLOAT(0.0), - "slope", GST_PROPS_FLOAT(1.0), - "channels", GST_PROPS_INT (1) + "audio/x-raw-float", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS ) ); } @@ -70,15 +66,10 @@ gst_filter_sink_factory (void) "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "filter_src", - "audio/raw", - "format", GST_PROPS_STRING ("float"), - "rate", GST_PROPS_INT_RANGE (1, G_MAXINT), - "layout", GST_PROPS_STRING ("gfloat"), - "intercept", GST_PROPS_FLOAT(0.0), - "slope", GST_PROPS_FLOAT(1.0), - "channels", GST_PROPS_INT (1) + "audio/x-raw-float", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS ) ); } diff --git a/gst/filter/gstiir.c b/gst/filter/gstiir.c index 06aa8f53..fcf2f43f 100644 --- a/gst/filter/gstiir.c +++ b/gst/filter/gstiir.c @@ -175,7 +175,7 @@ gst_iir_sink_connect (GstPad * pad, GstCaps * caps) if (!GST_CAPS_IS_FIXED (caps)) return GST_PAD_LINK_DELAYED; - set_retval = gst_pad_try_set_caps(filter->srcpad, caps); + set_retval = gst_pad_try_set_caps(filter->srcpad, gst_caps_ref (caps)); if (set_retval > 0) { /* connection works, so init the filter */ /* FIXME: remember to free it */ diff --git a/gst/filter/gstlpwsinc.c b/gst/filter/gstlpwsinc.c index 64e104d6..54eb81d3 100644 --- a/gst/filter/gstlpwsinc.c +++ b/gst/filter/gstlpwsinc.c @@ -183,7 +183,7 @@ gst_lpwsinc_sink_connect (GstPad * pad, GstCaps * caps) if (!GST_CAPS_IS_FIXED (caps)) return GST_PAD_LINK_DELAYED; - set_retval = gst_pad_try_set_caps(filter->srcpad, caps); + set_retval = gst_pad_try_set_caps(filter->srcpad, gst_caps_ref (caps)); if (set_retval > 0) { diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c index 0f4fac18..b14a701e 100644 --- a/gst/flx/gstflxdec.c +++ b/gst/flx/gstflxdec.c @@ -24,6 +24,7 @@ #include "flx_fmt.h" #include "gstflxdec.h" +#include <gst/video/video.h> #define JIFFIE (GST_SECOND/70) @@ -64,7 +65,7 @@ GST_PAD_TEMPLATE_FACTORY (sink_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "flxdec_sink", - "video/fli", + "video/x-fli", NULL ) ) @@ -76,16 +77,16 @@ GST_PAD_TEMPLATE_FACTORY (src_video_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "src_video", - "video/raw", - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R', 'G', 'B', ' ')), + "video/x-raw-rgb", "bpp", GST_PROPS_INT (32), "depth", GST_PROPS_INT (32), - "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN), - "red_mask", GST_PROPS_INT (0x00ff0000), - "green_mask", GST_PROPS_INT (0x0000ff00), - "blue_mask", GST_PROPS_INT (0x000000ff), + "endianness", GST_PROPS_INT (G_BIG_ENDIAN), + "red_mask", GST_PROPS_INT (R_MASK_32), + "green_mask", GST_PROPS_INT (G_MASK_32), + "blue_mask", GST_PROPS_INT (B_MASK_32), "width", GST_PROPS_INT_RANGE(320, 1280), - "height", GST_PROPS_INT_RANGE(200, 1024) + "height", GST_PROPS_INT_RANGE(200, 1024), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) ) ) @@ -520,20 +521,18 @@ gst_flxdec_loop (GstElement *element) } gst_pad_try_set_caps (flxdec->srcpad, - gst_caps_new ( + GST_CAPS_NEW ( "src_video", - "video/raw", - gst_props_new ( - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R', 'G', 'B', ' ')), - "bpp", GST_PROPS_INT (32), - "depth", GST_PROPS_INT (32), - "endianness", GST_PROPS_INT (G_LITTLE_ENDIAN), - "red_mask", GST_PROPS_INT (0x00ff0000), - "green_mask", GST_PROPS_INT (0x0000ff00), - "blue_mask", GST_PROPS_INT (0x000000ff), - "width", GST_PROPS_INT (flxh->width), - "height", GST_PROPS_INT (flxh->height), - NULL))); + "video/x-raw-rgb", + "bpp", GST_PROPS_INT (32), + "depth", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BIG_ENDIAN), + "red_mask", GST_PROPS_INT (R_MASK_32), + "green_mask", GST_PROPS_INT (G_MASK_32), + "blue_mask", GST_PROPS_INT (B_MASK_32), + "width", GST_PROPS_INT (flxh->width), + "height", GST_PROPS_INT (flxh->height), + "framerate", GST_PROPS_FLOAT (GST_SECOND/flxdec->frame_time))); if (flxh->depth <= 8) flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height); diff --git a/gst/mixmatrix/mixmatrix.c b/gst/mixmatrix/mixmatrix.c index bf9e9c90..bd16c3c5 100644 --- a/gst/mixmatrix/mixmatrix.c +++ b/gst/mixmatrix/mixmatrix.c @@ -4,6 +4,7 @@ #include <config.h> #include <gst/gst.h> #include <gst/bytestream/bytestream.h> +#include <gst/audio/audio.h> #include <string.h> #define GST_TYPE_MIXMATRIX \ @@ -75,14 +76,10 @@ GST_PAD_TEMPLATE_FACTORY (mixmatrix_sink_factory, "sink%d", GST_PAD_SINK, GST_PAD_REQUEST, - GST_CAPS_NEW ( + gst_caps_new ( "float_src", - "audio/raw", - "format", GST_PROPS_STRING ("float"), - "layout", GST_PROPS_STRING ("gfloat"), - "intercept", GST_PROPS_FLOAT (0.0), - "slope", GST_PROPS_FLOAT (1.0), - "channels", GST_PROPS_INT (1) + "audio/x-raw-float", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS ) ); @@ -90,14 +87,10 @@ GST_PAD_TEMPLATE_FACTORY (mixmatrix_src_factory, "src%d", GST_PAD_SRC, GST_PAD_REQUEST, - GST_CAPS_NEW ( + gst_caps_new ( "float_sink", - "audio/raw", - "format", GST_PROPS_STRING ("float"), - "layout", GST_PROPS_STRING ("gfloat"), - "intercept", GST_PROPS_FLOAT (0.0), - "slope", GST_PROPS_FLOAT (1.0), - "channels", GST_PROPS_INT (1) + "audio/x-raw-float", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS ) ); @@ -316,7 +309,7 @@ gst_mixmatrix_connect (GstPad *pad, GstCaps *caps) for (i=0;i<mix->srcpadalloc;i++) { if (mix->srcpads[i]) { if (GST_PAD_CAPS(mix->srcpads[i]) == NULL) - if (gst_pad_try_set_caps(mix->srcpads[i], caps) <= 0) + if (gst_pad_try_set_caps(mix->srcpads[i], gst_caps_ref (caps)) <= 0) return GST_PAD_LINK_REFUSED; } } diff --git a/gst/modplug/gstmodplug.cc b/gst/modplug/gstmodplug.cc index 01cea4fe..9270938b 100644 --- a/gst/modplug/gstmodplug.cc +++ b/gst/modplug/gstmodplug.cc @@ -41,8 +41,8 @@ GstElementDetails modplug_details = { "LGPL", "Module decoder based on modplug engine", VERSION, - "Jeremy SIMON <jsimon13@yahoo.fr> " - "Kenton Varda <temporal@gauge3d.org> " + "Jeremy SIMON <jsimon13@yahoo.fr>\n" + "Kenton Varda <temporal@gauge3d.org>\n" "Olivier Lapicque <olivierl@jps.net>", "(C) 2001" }; @@ -63,13 +63,10 @@ enum { ARG_MEGABASS, ARG_MEGABASS_AMOUNT, ARG_MEGABASS_RANGE, - ARG_FREQUENCY, ARG_NOISE_REDUCTION, ARG_SURROUND, ARG_SURROUND_DEPTH, ARG_SURROUND_DELAY, - ARG_CHANNEL, - ARG_16BIT, ARG_OVERSAMP, ARG_METADATA, ARG_STREAMINFO @@ -79,29 +76,10 @@ GST_PAD_TEMPLATE_FACTORY (modplug_src_template_factory, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( - "modplug_src", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (TRUE), - "width", GST_PROPS_INT (16), - "depth", GST_PROPS_INT (16), - "rate", GST_PROPS_INT_RANGE (11025, 44100), - "channels", GST_PROPS_INT_RANGE (1, 2) - ), - GST_CAPS_NEW ( + gst_caps_new ( "modplug_src", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (FALSE), - "width", GST_PROPS_INT (8), - "depth", GST_PROPS_INT (8), - "rate", GST_PROPS_INT_RANGE (11025, 44100), - "channels", GST_PROPS_INT_RANGE (1, 2) + "audio/x-raw-int", + GST_AUDIO_INT_PAD_TEMPLATE_PROPS ) ) @@ -113,21 +91,6 @@ GST_PAD_TEMPLATE_FACTORY (modplug_sink_template_factory, "modplug_sink", "audio/x-mod", NULL - ), - GST_CAPS_NEW ( - "modplug_sink", - "audio/x-xm", - NULL - ), - GST_CAPS_NEW ( - "modplug_sink", - "audio/x-s3m", - NULL - ), - GST_CAPS_NEW ( - "modplug_sink", - "audio/x-it", - NULL ) ) @@ -138,100 +101,64 @@ enum { }; -static void gst_modplug_class_init (GstModPlugClass *klass); -static void gst_modplug_init (GstModPlug *filter); -static void gst_modplug_set_property (GObject *object, guint id, const GValue *value, GParamSpec *pspec ); -static void gst_modplug_get_property (GObject *object, guint id, GValue *value, GParamSpec *pspec ); -static void gst_modplug_loop (GstElement *element); -static void gst_modplug_setup (GstModPlug *modplug); -static const GstFormat* - gst_modplug_get_formats (GstPad *pad); -static const GstQueryType* - gst_modplug_get_query_types (GstPad *pad); -static gboolean - gst_modplug_src_event (GstPad *pad, GstEvent *event); -static gboolean - gst_modplug_src_query (GstPad *pad, GstQueryType type, GstFormat *format, gint64 *value); +static void gst_modplug_class_init (GstModPlugClass *klass); +static void gst_modplug_init (GstModPlug *filter); +static void gst_modplug_set_property (GObject *object, + guint id, + const GValue *value, + GParamSpec *pspec ); +static void gst_modplug_get_property (GObject *object, + guint id, + GValue *value, + GParamSpec *pspec ); +static GstPadLinkReturn + gst_modplug_srclink (GstPad *pad, GstCaps *caps); +static void gst_modplug_loop (GstElement *element); +static void gst_modplug_setup (GstModPlug *modplug); +static const GstFormat * + gst_modplug_get_formats (GstPad *pad); +static const GstQueryType * + gst_modplug_get_query_types (GstPad *pad); +static gboolean gst_modplug_src_event (GstPad *pad, GstEvent *event); +static gboolean gst_modplug_src_query (GstPad *pad, + GstQueryType type, + GstFormat *format, + gint64 *value); static GstElementStateReturn - gst_modplug_change_state (GstElement *element); + gst_modplug_change_state (GstElement *element); static GstElementClass *parent_class = NULL; -#define GST_TYPE_MODPLUG_MIXFREQ (gst_modplug_mixfreq_get_type()) - -static GType -gst_modplug_mixfreq_get_type (void) -{ - static GType modplug_mixfreq_type = 0; - static GEnumValue modplug_mixfreq[] = { - { 0, "8000", "8000 Hz" }, - { 1, "11025", "11025 Hz" }, - { 2, "22100", "22100 Hz" }, - { 3, "44100", "44100 Hz" }, - { 0, NULL, NULL }, - }; - if (! modplug_mixfreq_type ) { - modplug_mixfreq_type = g_enum_register_static ("GstModPlugmixfreq", modplug_mixfreq); - } - return modplug_mixfreq_type; -} - - static GstCaps* modplug_type_find (GstBuffer *buf, gpointer priv) { - if (MOD_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (Mod_669_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (Amf_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (Dsm_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (Fam_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (Gdm_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (Imf_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (It_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-it", NULL); - - if (M15_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - /* FIXME - if ( Med_CheckType( buf ) ) - return gst_caps_new ("mikmod_type_find", "audio/x-mod", NULL); - */ - - if (Mtm_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (Okt_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-mod", NULL); - - if (S3m_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-s3m", NULL); - - if (Xm_CheckType (buf)) - return gst_caps_new ("modplug_type_find", "audio/x-xm", NULL); + if (MOD_CheckType (buf) || + Mod_669_CheckType (buf) || + Amf_CheckType (buf) || + Dsm_CheckType (buf) || + Fam_CheckType (buf) || + Gdm_CheckType (buf) || + Imf_CheckType (buf) || + It_CheckType (buf) || + M15_CheckType (buf) || + /*Med_CheckType (buf) || <- FIXME */ + Mtm_CheckType (buf) || + Okt_CheckType (buf) || + S3m_CheckType (buf) || + Xm_CheckType (buf)) { + return gst_caps_new ("modplug_type_find", + "audio/x-mod", + NULL); + } return NULL; } static GstTypeDefinition modplug_definitions[] = { - { "modplug_audio/mod", "audio/x-mod", ".mod .sam .med .stm .mtm .669 .ult .far .amf .dsm .imf .gdm .stx .okt", modplug_type_find }, - { "modplug_audio/xm", "audio/x-xm", ".xm", modplug_type_find }, - { "modplug_audio/it", "audio/x-it", ".it", modplug_type_find }, - { "modplug_audio/s3m", "audio/x-s3m", ".s3m", modplug_type_find }, + { "modplug_audio/mod", "audio/x-mod", + ".mod .sam .med .stm .mtm .669 .ult .far .amf " + ".dsm .imf .gdm .stx .okt .xm .it .s3m", + modplug_type_find }, { NULL, NULL, NULL, NULL } }; @@ -273,14 +200,6 @@ gst_modplug_class_init (GstModPlugClass *klass) g_param_spec_string("songname","Songname","The song name", "", G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FREQUENCY, - g_param_spec_enum("mixfreq", "mixfreq", "mixfreq", - GST_TYPE_MODPLUG_MIXFREQ, 3,(GParamFlags)G_PARAM_READWRITE )); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_16BIT, - g_param_spec_boolean("use16bit", "use16bit", "use16bit", - TRUE, (GParamFlags)G_PARAM_READWRITE )); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_REVERB, g_param_spec_boolean("reverb", "reverb", "reverb", FALSE, (GParamFlags)G_PARAM_READWRITE )); @@ -347,6 +266,7 @@ gst_modplug_init (GstModPlug *modplug) modplug->srcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (modplug_src_template_factory), "src"); gst_element_add_pad (GST_ELEMENT(modplug), modplug->srcpad); + gst_pad_set_link_function (modplug->srcpad, gst_modplug_srclink); gst_pad_set_event_function (modplug->srcpad, (GstPadEventFunction)GST_DEBUG_FUNCPTR(gst_modplug_src_event)); gst_pad_set_query_function (modplug->srcpad, gst_modplug_src_query); @@ -376,7 +296,6 @@ gst_modplug_init (GstModPlug *modplug) modplug->state = MODPLUG_STATE_NEED_TUNE; } - static void gst_modplug_setup (GstModPlug *modplug) { @@ -549,10 +468,10 @@ gst_modplug_update_metadata (GstModPlug *modplug) } - -static gboolean +static GstPadLinkReturn modplug_negotiate (GstModPlug *modplug) { + GstPadLinkReturn ret = GST_PAD_LINK_OK; gboolean sign; modplug->length = 1152 * modplug->channel; @@ -567,32 +486,49 @@ modplug_negotiate (GstModPlug *modplug) sign = FALSE; } - if (!GST_PAD_CAPS (modplug->srcpad)) { - if (!gst_pad_try_set_caps (modplug->srcpad, - GST_CAPS_NEW ( - "modplug_src", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (sign), - "width", GST_PROPS_INT (modplug->bitsPerSample), - "depth", GST_PROPS_INT (modplug->bitsPerSample), - "rate", GST_PROPS_INT (modplug->frequency), - "channels", GST_PROPS_INT (modplug->channel), - NULL) - )) - { - return FALSE; - } + if ((ret = gst_pad_try_set_caps (modplug->srcpad, + GST_CAPS_NEW ( + "modplug_src", + "audio/x-raw-int", + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "signed", GST_PROPS_BOOLEAN (sign), + "width", GST_PROPS_INT (modplug->bitsPerSample), + "depth", GST_PROPS_INT (modplug->bitsPerSample), + "rate", GST_PROPS_INT (modplug->frequency), + "channels", GST_PROPS_INT (modplug->channel), + NULL) + )) <= 0) { + return ret; } - gst_modplug_setup (modplug); + gst_modplug_setup (modplug); - return TRUE; + return ret; } +static GstPadLinkReturn +gst_modplug_srclink (GstPad *pad, GstCaps *caps) +{ + GstModPlug *modplug; + + modplug = GST_MODPLUG (gst_pad_get_parent (pad)); + + if (gst_caps_has_property_typed (caps, "depth", GST_PROPS_INT_TYPE)) { + gint depth; + gst_caps_get_int (caps, "depth", &depth); + modplug->_16bit = (depth == 16); + } + if (gst_caps_has_property_typed (caps, "channels", GST_PROPS_INT_TYPE)) { + gst_caps_get_int (caps, "channels", &modplug->channel); + } + if (gst_caps_has_property_typed (caps, "rate", GST_PROPS_INT_TYPE)) { + gst_caps_get_int (caps, "rate", &modplug->frequency); + } + + return modplug_negotiate(modplug); +} + static void gst_modplug_handle_event (GstModPlug *modplug) { @@ -684,7 +620,8 @@ gst_modplug_loop (GstElement *element) { modplug->mSoundFile = new CSoundFile; - if (!modplug_negotiate (modplug)) { + if (!GST_PAD_CAPS (modplug->srcpad) && + modplug_negotiate (modplug) <= 0) { gst_element_error (GST_ELEMENT (modplug), "could not negotiate format"); return; } @@ -839,12 +776,6 @@ gst_modplug_set_property (GObject *object, guint id, const GValue *value, GParam case ARG_MEGABASS_RANGE: modplug->megabass_range = g_value_get_int (value); break; - case ARG_FREQUENCY: - modplug->frequency = g_value_get_enum (value); - break; - case ARG_CHANNEL: - modplug->channel = g_value_get_int (value); - break; case ARG_NOISE_REDUCTION: modplug->noise_reduction = g_value_get_boolean (value); break; @@ -857,9 +788,6 @@ gst_modplug_set_property (GObject *object, guint id, const GValue *value, GParam case ARG_SURROUND_DELAY: modplug->surround_delay = g_value_get_int (value); break; - case ARG_16BIT: - modplug->_16bit = g_value_get_boolean (value); - break; default: break; } @@ -893,15 +821,6 @@ gst_modplug_get_property (GObject *object, guint id, GValue *value, GParamSpec * case ARG_MEGABASS_RANGE: g_value_set_int (value, modplug->megabass_range); break; - case ARG_FREQUENCY: - g_value_set_enum (value, modplug->frequency); - break; - case ARG_CHANNEL: - g_value_set_int (value, modplug->channel); - break; - case ARG_16BIT: - g_value_set_boolean (value, modplug->_16bit); - break; case ARG_SURROUND: g_value_set_boolean (value, modplug->surround); break; diff --git a/gst/mpeg1sys/gstmpeg1systemencode.c b/gst/mpeg1sys/gstmpeg1systemencode.c index 7e18121a..4073174c 100644 --- a/gst/mpeg1sys/gstmpeg1systemencode.c +++ b/gst/mpeg1sys/gstmpeg1systemencode.c @@ -59,7 +59,6 @@ GST_PAD_TEMPLATE_FACTORY (src_factory, GST_CAPS_NEW ( "src_video", "video/mpeg", - "mpegversion", GST_PROPS_INT (1), "systemstream", GST_PROPS_BOOLEAN (TRUE) ) ) @@ -72,6 +71,7 @@ GST_PAD_TEMPLATE_FACTORY (video_sink_factory, "video/mpeg", "mpegversion", GST_PROPS_INT (1), "systemstream", GST_PROPS_BOOLEAN (FALSE) + /* we don't care about width/height/framerate */ ) ) @@ -81,8 +81,8 @@ GST_PAD_TEMPLATE_FACTORY (audio_sink_factory, GST_PAD_REQUEST, GST_CAPS_NEW ( "sink_audio", - "audio/x-mp3", - NULL + "audio/mpeg", + NULL /* well, "don't care" */ ) ) diff --git a/gst/mpeg1videoparse/gstmp1videoparse.c b/gst/mpeg1videoparse/gstmp1videoparse.c index 332a259a..3a17dbe7 100644 --- a/gst/mpeg1videoparse/gstmp1videoparse.c +++ b/gst/mpeg1videoparse/gstmp1videoparse.c @@ -18,9 +18,6 @@ */ /*#define GST_DEBUG_ENABLED */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include "gstmp1videoparse.h" /* Start codes. */ @@ -45,42 +42,34 @@ static GstElementDetails mp1videoparse_details = { "(C) 2000", }; -static GstPadTemplate* -src_factory (void) -{ - return - gst_pad_template_new ( - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - gst_caps_new ( - "mp1videoparse_src", - "video/mpeg", - gst_props_new ( - "mpegversion", GST_PROPS_INT (1), - "systemstream", GST_PROPS_BOOLEAN (FALSE), - "sliced", GST_PROPS_BOOLEAN (TRUE), - NULL)), - NULL); -} - -static GstPadTemplate* -sink_factory (void) -{ - return - gst_pad_template_new ( - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - gst_caps_new ( - "mp1videoparse_sink", - "video/mpeg", - gst_props_new ( - "mpegversion", GST_PROPS_INT (1), - "systemstream", GST_PROPS_BOOLEAN (FALSE), - NULL)), - NULL); -} +GST_PAD_TEMPLATE_FACTORY (src_factory, + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "mp1videoparse_src", + "video/mpeg", + "mpegversion", GST_PROPS_INT (1), + "systemstream", GST_PROPS_BOOLEAN (FALSE), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096), + "pixel_width", GST_PROPS_INT_RANGE (1, 255), + "pixel_height", GST_PROPS_INT_RANGE (1, 255), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) + ) +); + +GST_PAD_TEMPLATE_FACTORY (sink_factory, + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "mp1videoparse_sink", + "video/mpeg", + "mpegversion", GST_PROPS_INT (1), + "systemstream", GST_PROPS_BOOLEAN (FALSE) + ) +); /* Mp1VideoParse signals and args */ enum { @@ -98,10 +87,9 @@ static void gst_mp1videoparse_init (Mp1VideoParse *mp1videoparse); static void gst_mp1videoparse_chain (GstPad *pad, GstBuffer *buf); static void gst_mp1videoparse_real_chain (Mp1VideoParse *mp1videoparse, GstBuffer *buf, GstPad *outpad); -/* defined but not used static void gst_mp1videoparse_flush (Mp1VideoParse *mp1videoparse); -*/ -static GstPadTemplate *src_template, *sink_template; +static GstElementStateReturn + gst_mp1videoparse_change_state (GstElement *element); static GstElementClass *parent_class = NULL; /*static guint gst_mp1videoparse_signals[LAST_SIGNAL] = { 0 }; */ @@ -136,40 +124,100 @@ gst_mp1videoparse_class_init (Mp1VideoParseClass *klass) parent_class = g_type_class_ref(GST_TYPE_ELEMENT); + gstelement_class->change_state = gst_mp1videoparse_change_state; } static void gst_mp1videoparse_init (Mp1VideoParse *mp1videoparse) { - mp1videoparse->sinkpad = gst_pad_new_from_template (sink_template, "sink"); + mp1videoparse->sinkpad = gst_pad_new_from_template ( + GST_PAD_TEMPLATE_GET (sink_factory), "sink"); gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->sinkpad); 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 ( + GST_PAD_TEMPLATE_GET (src_factory), "src"); gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->srcpad); mp1videoparse->partialbuf = NULL; mp1videoparse->need_resync = FALSE; mp1videoparse->last_pts = 0; mp1videoparse->picture_in_buffer = 0; + mp1videoparse->width = mp1videoparse->height = -1; + mp1videoparse->fps = mp1videoparse->asr = 0.; +} + +static void +mp1videoparse_parse_seq (Mp1VideoParse *mp1videoparse, GstBuffer *buf) +{ + gint width, height, asr_idx, fps_idx; + gfloat asr_table[] = { 0., 1., + 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, + 0.8935, 0.9157, 0.9815, 1.0255, 1.0695, + 1.0950, 1.1575, 1.2015 }; + gfloat fps_table[] = { 0., 24./1.001, 24., 25., + 30./1.001, 30., + 50., 60./1.001, 60. }; + guint32 n = GUINT32_FROM_BE (*(guint32 *) GST_BUFFER_DATA (buf)); + + width = (n & 0x00000fff) >> 0; + height = (n & 0x00fff000) >> 12; + asr_idx = (n & 0x0f000000) >> 24; + fps_idx = (n & 0xf0000000) >> 28; + + if (fps_idx >= 9 || fps_idx <= 0) + fps_idx = 3; /* well, we need a default */ + if (asr_idx >= 15 || asr_idx <= 0) + asr_idx = 1; /* no aspect ratio */ + + if (asr_table[asr_idx] != mp1videoparse->asr || + fps_table[fps_idx] != mp1videoparse->fps || + width != mp1videoparse->width || + height != mp1videoparse->height) { + GstCaps *caps; + + mp1videoparse->asr = asr_table[asr_idx]; + mp1videoparse->fps = fps_table[fps_idx]; + mp1videoparse->width = width; + mp1videoparse->height = height; + + caps = GST_CAPS_NEW ("mp1videoparse_src", + "video/mpeg", + "systemstream", GST_PROPS_BOOLEAN (FALSE), + "mpegversion", GST_PROPS_INT (1), + "width", GST_PROPS_INT (width), + "height", GST_PROPS_INT (height), + "framerate", GST_PROPS_FLOAT (fps_table[fps_idx]), + "pixel_width", GST_PROPS_INT (1), + "pixel_height", GST_PROPS_INT (1)); /* FIXME */ + + gst_caps_debug (caps, "New mpeg1videoparse caps"); + + if (gst_pad_try_set_caps (mp1videoparse->srcpad, caps) <= 0) { + gst_element_error (GST_ELEMENT (mp1videoparse), + "mp1videoparse: failed to negotiate a new format"); + return; + } + } } static gboolean -mp1videoparse_valid_sync (gulong head) +mp1videoparse_valid_sync (Mp1VideoParse *mp1videoparse, gulong head, GstBuffer *buf) { - if (head == SEQ_START_CODE) - return TRUE; - if (head == GOP_START_CODE) - return TRUE; - if (head == PICTURE_START_CODE) - return TRUE; - if (head >= SLICE_MIN_START_CODE && - head <= SLICE_MAX_START_CODE) - return TRUE; - if (head == USER_START_CODE) - return TRUE; - if (head == EXT_START_CODE) - return TRUE; + switch (head) { + case SEQ_START_CODE: + mp1videoparse_parse_seq(mp1videoparse, buf); + return TRUE; + case GOP_START_CODE: + case PICTURE_START_CODE: + case USER_START_CODE: + case EXT_START_CODE: + return TRUE; + default: + if (head >= SLICE_MIN_START_CODE && + head <= SLICE_MAX_START_CODE) + return TRUE; + } return FALSE; } @@ -207,7 +255,6 @@ mp1videoparse_find_next_gop (Mp1VideoParse *mp1videoparse, GstBuffer *buf) return -1; } -/* defined but not used static void gst_mp1videoparse_flush (Mp1VideoParse *mp1videoparse) { @@ -220,7 +267,7 @@ gst_mp1videoparse_flush (Mp1VideoParse *mp1videoparse) mp1videoparse->in_flush = TRUE; mp1videoparse->picture_in_buffer = 0; } -*/ + static void gst_mp1videoparse_chain (GstPad *pad,GstBuffer *buf) { @@ -249,15 +296,31 @@ gst_mp1videoparse_real_chain (Mp1VideoParse *mp1videoparse, GstBuffer *buf, GstP guint64 time_stamp; GstBuffer *temp; -/* g_return_if_fail(GST_IS_BUFFER(buf)); */ - - time_stamp = GST_BUFFER_TIMESTAMP(buf); - /* FIXME, handle events here */ - /* - gst_mp1videoparse_flush(mp1videoparse); - */ + if (GST_IS_EVENT (buf)) { + GstEvent *event = GST_EVENT (buf); + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + case GST_EVENT_DISCONTINUOUS: + gst_mp1videoparse_flush(mp1videoparse); + break; + case GST_EVENT_EOS: + gst_mp1videoparse_flush(mp1videoparse); + gst_event_ref(event); + gst_pad_push(outpad, GST_BUFFER (event)); + gst_element_set_eos (GST_ELEMENT (mp1videoparse)); + break; + default: + GST_DEBUG ("Unhandled event type %d", + GST_EVENT_TYPE (event)); + break; + } + + gst_event_unref (event); + return; + } if (mp1videoparse->partialbuf) { @@ -285,7 +348,9 @@ gst_mp1videoparse_real_chain (Mp1VideoParse *mp1videoparse, GstBuffer *buf, GstP GST_DEBUG ("mp1videoparse: head is %08x", (unsigned int)head); - if (!mp1videoparse_valid_sync(head) || mp1videoparse->need_resync) { + if (!mp1videoparse_valid_sync(mp1videoparse, head, + mp1videoparse->partialbuf) || + mp1videoparse->need_resync) { sync_pos = mp1videoparse_find_next_gop(mp1videoparse, mp1videoparse->partialbuf); if (sync_pos != -1) { mp1videoparse->need_resync = FALSE; @@ -362,9 +427,14 @@ gst_mp1videoparse_real_chain (Mp1VideoParse *mp1videoparse, GstBuffer *buf, GstP mp1videoparse->in_flush = FALSE; } - GST_DEBUG ("mp1videoparse: pushing %d bytes %" G_GUINT64_FORMAT, GST_BUFFER_SIZE(outbuf), GST_BUFFER_TIMESTAMP(outbuf)); - gst_pad_push(outpad, outbuf); - GST_DEBUG ("mp1videoparse: pushing done"); + if (GST_PAD_CAPS (outpad) != NULL) { + GST_DEBUG ("mp1videoparse: pushing %d bytes %" G_GUINT64_FORMAT, GST_BUFFER_SIZE(outbuf), GST_BUFFER_TIMESTAMP(outbuf)); + gst_pad_push(outpad, outbuf); + GST_DEBUG ("mp1videoparse: pushing done"); + } else { + GST_DEBUG ("No capsnego yet, delaying buffer push"); + gst_buffer_unref (outbuf); + } mp1videoparse->picture_in_buffer = 0; temp = gst_buffer_create_sub(mp1videoparse->partialbuf, offset, size-offset); @@ -376,7 +446,6 @@ gst_mp1videoparse_real_chain (Mp1VideoParse *mp1videoparse, GstBuffer *buf, GstP } } -/* FIXME static GstElementStateReturn gst_mp1videoparse_change_state (GstElement *element) { @@ -384,20 +453,22 @@ gst_mp1videoparse_change_state (GstElement *element) g_return_val_if_fail(GST_IS_MP1VIDEOPARSE(element),GST_STATE_FAILURE); mp1videoparse = GST_MP1VIDEOPARSE(element); - GST_DEBUG ("mp1videoparse: state pending %d", GST_STATE_PENDING(element)); - * if going down into NULL state, clear out buffers * - if (GST_STATE_PENDING(element) == GST_STATE_READY) { - gst_mp1videoparse_flush(mp1videoparse); + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_PAUSED_TO_READY: + gst_mp1videoparse_flush(mp1videoparse); + mp1videoparse->width = mp1videoparse->height = -1; + mp1videoparse->fps = mp1videoparse->asr = 0.; + break; + default: + break; } - * if we haven't failed already, give the parent class a chance to ;-) * if (GST_ELEMENT_CLASS(parent_class)->change_state) return GST_ELEMENT_CLASS(parent_class)->change_state(element); return GST_STATE_SUCCESS; } -*/ static gboolean plugin_init (GModule *module, GstPlugin *plugin) @@ -409,11 +480,10 @@ plugin_init (GModule *module, GstPlugin *plugin) &mp1videoparse_details); g_return_val_if_fail(factory != NULL, FALSE); - src_template = src_factory (); - gst_element_factory_add_pad_template (factory, src_template); - - sink_template = sink_factory (); - gst_element_factory_add_pad_template (factory, sink_template); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (src_factory)); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (sink_factory)); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); diff --git a/gst/mpeg1videoparse/gstmp1videoparse.h b/gst/mpeg1videoparse/gstmp1videoparse.h index 31cfcdda..5d06738c 100644 --- a/gst/mpeg1videoparse/gstmp1videoparse.h +++ b/gst/mpeg1videoparse/gstmp1videoparse.h @@ -57,6 +57,8 @@ struct _Mp1VideoParse { guint64 last_pts; gint picture_in_buffer; + gint width, height; + gfloat fps, asr; }; struct _Mp1VideoParseClass { diff --git a/gst/mpegaudioparse/gstmpegaudioparse.c b/gst/mpegaudioparse/gstmpegaudioparse.c index a5d8797c..d97fce17 100644 --- a/gst/mpegaudioparse/gstmpegaudioparse.c +++ b/gst/mpegaudioparse/gstmpegaudioparse.c @@ -46,13 +46,11 @@ mp3_src_factory (void) gst_caps_new ( "mp3parse_src", "audio/x-mp3", - /* gst_props_new ( "layer", GST_PROPS_INT_RANGE (1, 3), - "bitrate", GST_PROPS_INT_RANGE (8, 320), - "framed", GST_PROPS_BOOLEAN (TRUE), - */ - NULL), + "rate", GST_PROPS_INT_RANGE (8000, 48000), + "channels", GST_PROPS_INT_RANGE (1, 2), + NULL)), NULL); } @@ -89,13 +87,14 @@ static GstPadTemplate *sink_temp, *src_temp; static void gst_mp3parse_class_init (GstMPEGAudioParseClass *klass); static void gst_mp3parse_init (GstMPEGAudioParse *mp3parse); -static void gst_mp3parse_loop (GstElement *element); static void gst_mp3parse_chain (GstPad *pad,GstBuffer *buf); static long bpf_from_header (GstMPEGAudioParse *parse, unsigned long header); static int head_check (unsigned long head); static void gst_mp3parse_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_mp3parse_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static GstElementStateReturn + gst_mp3parse_change_state (GstElement *element); static GstElementClass *parent_class = NULL; /*static guint gst_mp3parse_signals[LAST_SIGNAL] = { 0 }; */ @@ -133,13 +132,15 @@ gst_mp3parse_class_init (GstMPEGAudioParseClass *klass) g_param_spec_int("skip","skip","skip", G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BIT_RATE, - g_param_spec_int("bit_rate","bit_rate","bit_rate", + g_param_spec_int("bitrate","Bitrate","Bit Rate", G_MININT,G_MAXINT,0,G_PARAM_READABLE)); /* CHECKME */ parent_class = g_type_class_ref(GST_TYPE_ELEMENT); gobject_class->set_property = gst_mp3parse_set_property; gobject_class->get_property = gst_mp3parse_get_property; + + gstelement_class->change_state = gst_mp3parse_change_state; } static void @@ -148,11 +149,8 @@ gst_mp3parse_init (GstMPEGAudioParse *mp3parse) mp3parse->sinkpad = gst_pad_new_from_template(sink_temp, "sink"); gst_element_add_pad(GST_ELEMENT(mp3parse),mp3parse->sinkpad); - gst_element_set_loop_function (GST_ELEMENT(mp3parse),gst_mp3parse_loop); -#if 1 /* set this to one to use the old chaining code */ gst_pad_set_chain_function(mp3parse->sinkpad,gst_mp3parse_chain); gst_element_set_loop_function (GST_ELEMENT(mp3parse),NULL); -#endif mp3parse->srcpad = gst_pad_new_from_template(src_temp, "src"); gst_element_add_pad(GST_ELEMENT(mp3parse),mp3parse->srcpad); @@ -161,6 +159,8 @@ gst_mp3parse_init (GstMPEGAudioParse *mp3parse) mp3parse->partialbuf = NULL; mp3parse->skip = 0; mp3parse->in_flush = FALSE; + + mp3parse->rate = mp3parse->channels = mp3parse->layer = -1; } static guint32 @@ -170,7 +170,6 @@ gst_mp3parse_next_header (guchar *buf,guint32 len,guint32 start) int f = 0; while (offset < (len - 4)) { - fprintf(stderr,"%02x ",buf[offset]); if (buf[offset] == 0xff) f = 1; else if (f && ((buf[offset] >> 4) == 0x0f)) @@ -183,52 +182,6 @@ gst_mp3parse_next_header (guchar *buf,guint32 len,guint32 start) } static void -gst_mp3parse_loop (GstElement *element) -{ - GstMPEGAudioParse *parse = GST_MP3PARSE(element); - GstBuffer *inbuf, *outbuf; - guint32 size, offset; - guchar *data; - guint32 start; - guint32 header; - gint bpf; - - while (1) { - /* get a new buffer */ - inbuf = gst_pad_pull (parse->sinkpad); - size = GST_BUFFER_SIZE (inbuf); - data = GST_BUFFER_DATA (inbuf); - offset = 0; -fprintf(stderr, "have buffer of %d bytes\n",size); - - /* loop through it and find all the frames */ - while (offset < (size - 4)) { - start = gst_mp3parse_next_header (data,size,offset); -fprintf(stderr, "skipped %d bytes searching for the next header\n",start-offset); - header = GUINT32_FROM_BE(*((guint32 *)(data+start))); -fprintf(stderr, "header is 0x%08x\n",header); - - /* figure out how big the frame is supposed to be */ - bpf = bpf_from_header (parse, header); - - /* see if there are enough bytes in this buffer for the whole frame */ - if ((start + bpf) <= size) { - outbuf = gst_buffer_create_sub (inbuf,start,bpf); -fprintf(stderr, "sending buffer of %d bytes\n",bpf); - gst_pad_push (parse->srcpad, outbuf); - offset = start + bpf; - - /* if not, we have to deal with it somehow */ - } else { -fprintf(stderr,"don't have enough data for this frame\n"); - - break; - } - } - } -} - -static void gst_mp3parse_chain (GstPad *pad, GstBuffer *buf) { GstMPEGAudioParse *mp3parse; @@ -337,7 +290,13 @@ gst_mp3parse_chain (GstPad *pad, GstBuffer *buf) mp3parse->in_flush = FALSE; } GST_BUFFER_TIMESTAMP(outbuf) = last_ts; - gst_pad_push(mp3parse->srcpad,outbuf); + + if (GST_PAD_CAPS (mp3parse->srcpad) != NULL) { + gst_pad_push(mp3parse->srcpad,outbuf); + } else { + GST_DEBUG ("No capsnego yet, delaying buffer push"); + gst_buffer_unref (outbuf); + } } else { GST_DEBUG ("mp3parse: skipping buffer of %d bytes",GST_BUFFER_SIZE(outbuf)); @@ -382,8 +341,9 @@ static long mp3parse_freqs[9] = static long bpf_from_header (GstMPEGAudioParse *parse, unsigned long header) { - int layer_index,layer,lsf,samplerate_index,padding; + int layer_index,layer,lsf,samplerate_index,padding,mode; long bpf; + gint channels, rate; /*mpegver = (header >> 19) & 0x3; // don't need this for bpf */ layer_index = (header >> 17) & 0x3; @@ -392,6 +352,7 @@ bpf_from_header (GstMPEGAudioParse *parse, unsigned long header) parse->bit_rate = mp3parse_tabsel[lsf][layer - 1][((header >> 12) & 0xf)]; samplerate_index = (header >> 10) & 0x3; padding = (header >> 9) & 0x1; + mode = (header >> 6) & 0x3; if (layer == 1) { bpf = parse->bit_rate * 12000; @@ -403,6 +364,26 @@ bpf_from_header (GstMPEGAudioParse *parse, unsigned long header) bpf += padding; } + channels = (mode == 3) ? 1 : 2; + rate = mp3parse_freqs[samplerate_index]; + if (channels != parse->channels || + rate != parse->rate || + layer != parse->layer) { + GstCaps *caps = GST_CAPS_NEW ("mp3parse_src", + "audio/mpeg", + "layer", GST_PROPS_INT (layer), + "channels", GST_PROPS_INT (channels), + "rate", GST_PROPS_INT (rate)); + if (gst_pad_try_set_caps(parse->srcpad, caps) <= 0) { + gst_element_error (GST_ELEMENT (parse), + "mp3parse: failed to negotiate format with next element"); + } + + parse->channels = channels; + parse->layer = layer; + parse->rate = rate; + } + /*g_print("%08x: layer %d lsf %d bitrate %d samplerate_index %d padding %d - bpf %d\n", */ /*header,layer,lsf,bitrate,samplerate_index,padding,bpf); */ @@ -478,6 +459,28 @@ gst_mp3parse_get_property (GObject *object, guint prop_id, GValue *value, GParam } } +static GstElementStateReturn +gst_mp3parse_change_state (GstElement *element) +{ + GstMPEGAudioParse *src; + + g_return_val_if_fail(GST_IS_MP3PARSE(element), GST_STATE_FAILURE); + src = GST_MP3PARSE(element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_PAUSED_TO_READY: + src->channels = -1; src->rate = -1; src->layer = -1; + break; + default: + break; + } + + if (GST_ELEMENT_CLASS(parent_class)->change_state) + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + + return GST_STATE_SUCCESS; +} + static gboolean plugin_init (GModule *module, GstPlugin *plugin) { diff --git a/gst/mpegaudioparse/gstmpegaudioparse.h b/gst/mpegaudioparse/gstmpegaudioparse.h index f929a5d9..7d1edc95 100644 --- a/gst/mpegaudioparse/gstmpegaudioparse.h +++ b/gst/mpegaudioparse/gstmpegaudioparse.h @@ -53,6 +53,7 @@ struct _GstMPEGAudioParse { GstBuffer *partialbuf; /* previous buffer (if carryover) */ guint skip; /* number of frames to skip */ guint bit_rate; + gint channels, rate, layer; gboolean in_flush; }; diff --git a/gst/passthrough/gstpassthrough.c b/gst/passthrough/gstpassthrough.c index 75856aac..fca1e941 100644 --- a/gst/passthrough/gstpassthrough.c +++ b/gst/passthrough/gstpassthrough.c @@ -61,9 +61,9 @@ passthrough_sink_factory (void) if (! template) { template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - gst_caps_append (gst_caps_new ("sink_int", "audio/raw", + gst_caps_append (gst_caps_new ("sink_int", "audio/x-raw-int", GST_AUDIO_INT_PAD_TEMPLATE_PROPS), - gst_caps_new ("sink_float", "audio/raw", + gst_caps_new ("sink_float", "audio/x-raw-float", GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS)), NULL); } @@ -78,9 +78,9 @@ passthrough_src_factory (void) if (! template) template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - gst_caps_append (gst_caps_new ("src_float", "audio/raw", + gst_caps_append (gst_caps_new ("src_float", "audio/x-raw-float", GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS), - gst_caps_new ("src_int", "audio/raw", + gst_caps_new ("src_int", "audio/x-raw-float", GST_AUDIO_INT_PAD_TEMPLATE_PROPS)), NULL); @@ -115,7 +115,7 @@ passthrough_get_bufferpool (GstPad *pad) static GstPadLinkReturn passthrough_connect_sink (GstPad *pad, GstCaps *caps) { - const gchar *format; + const gchar *mimetype; GstPassthrough *filter; g_return_val_if_fail (pad != NULL, GST_PAD_LINK_DELAYED); @@ -125,12 +125,12 @@ passthrough_connect_sink (GstPad *pad, GstCaps *caps) g_return_val_if_fail (filter != NULL, GST_PAD_LINK_REFUSED); g_return_val_if_fail (GST_IS_PASSTHROUGH (filter), GST_PAD_LINK_REFUSED); - gst_caps_get_string(caps, "format", &format); + mimetype = gst_caps_get_mime(caps); gst_caps_get_int (caps, "rate", &filter->rate); gst_caps_get_int (caps, "channels", &filter->channels); - if (strcmp (format, "int") == 0) { + if (strcmp (mimetype, "audio/x-raw-int") == 0) { filter->format = GST_PASSTHROUGH_FORMAT_INT; gst_caps_get_int (caps, "width", &filter->width); gst_caps_get_int (caps, "depth", &filter->depth); @@ -144,7 +144,7 @@ passthrough_connect_sink (GstPad *pad, GstCaps *caps) g_print ("Passthrough : format int, bit width %d, endianness %d, signed %s\n", filter->width, filter->endianness, filter->is_signed ? "yes" : "no"); } - } else if (strcmp (format, "float") == 0) { + } else if (strcmp (mimetype, "audio/x-raw-float") == 0) { filter->format = GST_PASSTHROUGH_FORMAT_FLOAT; gst_caps_get_string (caps, "layout", &filter->layout); gst_caps_get_float (caps, "intercept", &filter->intercept); diff --git a/gst/playondemand/gstplayondemand.c b/gst/playondemand/gstplayondemand.c index dcffbf36..eb8a296f 100644 --- a/gst/playondemand/gstplayondemand.c +++ b/gst/playondemand/gstplayondemand.c @@ -61,9 +61,9 @@ play_on_demand_sink_factory (void) if (!template) { template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - gst_caps_append(gst_caps_new ("sink_int", "audio/raw", + gst_caps_append(gst_caps_new ("sink_int", "audio/x-raw-int", GST_AUDIO_INT_PAD_TEMPLATE_PROPS), - gst_caps_new ("sink_float", "audio/raw", + gst_caps_new ("sink_float", "audio/x-raw-float", GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS)), NULL); } @@ -79,9 +79,9 @@ play_on_demand_src_factory (void) if (!template) template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - gst_caps_append (gst_caps_new ("src_float", "audio/raw", + gst_caps_append (gst_caps_new ("src_float", "audio/x-raw-float", GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS), - gst_caps_new ("src_int", "audio/raw", + gst_caps_new ("src_int", "audio/x-raw-int", GST_AUDIO_INT_PAD_TEMPLATE_PROPS)), NULL); @@ -370,7 +370,7 @@ play_on_demand_get_bufferpool (GstPad *pad) static GstPadLinkReturn play_on_demand_pad_link (GstPad *pad, GstCaps *caps) { - const gchar *format; + const gchar *mimetype; GstPlayOnDemand *filter; g_return_val_if_fail(caps != NULL, GST_PAD_LINK_DELAYED); @@ -378,14 +378,14 @@ play_on_demand_pad_link (GstPad *pad, GstCaps *caps) filter = GST_PLAYONDEMAND(GST_PAD_PARENT(pad)); - gst_caps_get_string(caps, "format", &format); + mimetype = gst_caps_get_mime(caps); gst_caps_get_int(caps, "rate", &filter->rate); gst_caps_get_int(caps, "channels", &filter->channels); - if (strcmp(format, "int") == 0) { + if (strcmp(mimetype, "audio/x-raw-int") == 0) { filter->format = GST_PLAYONDEMAND_FORMAT_INT; gst_caps_get_int (caps, "width", &filter->width); - } else if (strcmp(format, "float") == 0) { + } else if (strcmp(mimetype, "audio/x-raw-float") == 0) { filter->format = GST_PLAYONDEMAND_FORMAT_FLOAT; } diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index be187752..4852db93 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -59,6 +59,7 @@ struct _QtDemuxSample { int size; guint32 offset; guint64 timestamp; + guint64 duration; }; struct _QtDemuxStream { @@ -73,6 +74,7 @@ struct _QtDemuxStream { int width; int height; + float fps; double rate; int n_channels; }; @@ -125,25 +127,12 @@ GST_PAD_TEMPLATE_FACTORY (sink_templ, GST_PAD_ALWAYS, GST_CAPS_NEW ( "qtdemux_sink", - "video/quicktime", - NULL + "video/quicktime", + NULL ) ) -GST_PAD_TEMPLATE_FACTORY (src_video_templ, - "video_%02d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - NULL -) - -GST_PAD_TEMPLATE_FACTORY (src_audio_templ, - "audio_%02d", - GST_PAD_SRC, - GST_PAD_SOMETIMES, - NULL -) - +static GstPadTemplate *videosrctempl, *audiosrctempl; static GstElementClass *parent_class = NULL; static void gst_qtdemux_class_init (GstQTDemuxClass *klass); @@ -223,6 +212,15 @@ plugin_init (GModule *module, GstPlugin *plugin) { GstElementFactory *factory; GstTypeFactory *type; + GstCaps *audiocaps = NULL, *videocaps = NULL, *temp; + const guint32 audio_fcc[] = { + /* FILLME */ + 0, + }, video_fcc[] = { + /* FILLME */ + 0, + }; + gint i; if (!gst_library_load ("gstbytestream")) return FALSE; @@ -232,9 +230,27 @@ plugin_init (GModule *module, GstPlugin *plugin) g_return_val_if_fail(factory != NULL, FALSE); gst_element_factory_set_rank (factory, GST_ELEMENT_RANK_PRIMARY); + for (i = 0; audio_fcc[i] != 0; i++) { + temp = qtdemux_audio_caps (NULL, audio_fcc[i]); + audiocaps = gst_caps_append (audiocaps, temp); + } + audiosrctempl = gst_pad_template_new ("audio_%02d", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + audiocaps, NULL); + + for (i = 0; video_fcc[i] != 0; i++) { + temp = qtdemux_video_caps (NULL, video_fcc[i]); + videocaps = gst_caps_append (videocaps, temp); + } + videosrctempl = gst_pad_template_new ("video_%02d", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + videocaps, NULL); + gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (sink_templ)); - gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (src_video_templ)); - gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (src_audio_templ)); + gst_element_factory_add_pad_template (factory, videosrctempl); + gst_element_factory_add_pad_template (factory, audiosrctempl); type = gst_type_factory_new (&quicktimedefinition); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type)); @@ -484,7 +500,20 @@ static void gst_qtdemux_loop_header (GstElement *element) }while(TRUE); if(buf){ + /* hum... */ + if(stream->subtype == GST_MAKE_FOURCC('v','i','d','e')){ + float fps = 1. * GST_SECOND / stream->samples[stream->sample_index].duration; + if (fps != stream->fps) { + gst_props_remove_entry_by_name(stream->caps->properties, "framerate"); + gst_props_add_entry(stream->caps->properties, + gst_props_entry_new("framerate", GST_PROPS_FLOAT(fps))); + stream->fps = fps; + gst_pad_try_set_caps(stream->pad, stream->caps); + } + } + GST_BUFFER_TIMESTAMP(buf) = stream->samples[stream->sample_index].timestamp; + GST_BUFFER_DURATION(buf) = stream->samples[stream->sample_index].duration; gst_pad_push(stream->pad, buf); } stream->sample_index++; @@ -554,27 +583,31 @@ gst_qtdemux_src_link(GstPad *pad, GstCaps *caps) void gst_qtdemux_add_stream(GstQTDemux *qtdemux, QtDemuxStream *stream) { if(stream->subtype == GST_MAKE_FOURCC('v','i','d','e')){ - stream->pad = gst_pad_new_from_template ( - GST_PAD_TEMPLATE_GET (src_video_templ), g_strdup_printf ("video_%02d", - qtdemux->n_video_streams)); + stream->pad = gst_pad_new_from_template (videosrctempl, + g_strdup_printf ("video_%02d", qtdemux->n_video_streams)); + stream->fps = 1. * GST_SECOND / stream->samples[0].duration; if(stream->caps){ - stream->caps->properties = gst_props_intersect( + GstProps *properties = gst_props_intersect( stream->caps->properties, gst_props_new("width",GST_PROPS_INT(stream->width), - "height",GST_PROPS_INT(stream->height), NULL)); + "height",GST_PROPS_INT(stream->height), + "framerate", GST_PROPS_FLOAT(stream->fps), NULL)); + if (stream->caps->properties != NULL) + gst_props_unref (stream->caps->properties); + stream->caps->properties = properties; } qtdemux->n_video_streams++; }else{ - stream->pad = gst_pad_new_from_template ( - GST_PAD_TEMPLATE_GET (src_audio_templ), g_strdup_printf ("audio_%02d", - qtdemux->n_audio_streams)); + stream->pad = gst_pad_new_from_template (audiosrctempl, + g_strdup_printf ("audio_%02d", qtdemux->n_audio_streams)); if(stream->caps){ - g_print("props were %s\n",gst_props_to_string(stream->caps->properties)); - stream->caps->properties = gst_props_intersect( + GstProps *properties = gst_props_intersect( stream->caps->properties, gst_props_new("rate",GST_PROPS_INT((int)stream->rate), "channels",GST_PROPS_INT(stream->n_channels), NULL)); - g_print("props now %s\n",gst_props_to_string(stream->caps->properties)); + if (stream->caps->properties != NULL) + gst_props_unref (stream->caps->properties); + stream->caps->properties = properties; } qtdemux->n_audio_streams++; } @@ -1302,6 +1335,7 @@ static void qtdemux_parse_trak(GstQTDemux *qtdemux, GNode *trak) stream->width = QTDEMUX_GUINT16_GET(stsd->data+offset+32); stream->height = QTDEMUX_GUINT16_GET(stsd->data+offset+34); + stream->fps = 0.; /* this is filled in later */ g_print("frame count: %u\n", QTDEMUX_GUINT16_GET(stsd->data+offset+48)); @@ -1416,6 +1450,7 @@ done: time = (GST_SECOND * duration)/stream->timescale; for(j=0;j<n;j++){ samples[index].timestamp = timestamp; + samples[index].duration = time; timestamp += time; index++; } @@ -1487,6 +1522,7 @@ done2: size = samples[index+1].sample_index - samples[index].sample_index; time = (GST_SECOND * duration * samples[index].size)/stream->timescale ; timestamp += time; + samples[index].duration = time; } } } @@ -1509,43 +1545,87 @@ static GstCaps *qtdemux_video_caps(GstQTDemux *qtdemux, guint32 fourcc) switch(fourcc){ case GST_MAKE_FOURCC('j','p','e','g'): /* JPEG */ - return GST_CAPS_NEW("jpeg_caps","video/jpeg",NULL); + return GST_CAPS_NEW("jpeg_caps","video/x-jpeg", + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('m','j','p','a'): /* Motion-JPEG (format A) */ - return GST_CAPS_NEW("mjpa_caps","video/jpeg",NULL); + return GST_CAPS_NEW("mjpa_caps","video/x-jpeg", + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('m','j','p','b'): /* Motion-JPEG (format B) */ - return GST_CAPS_NEW("mjpa_caps","video/jpeg",NULL); + return GST_CAPS_NEW("mjpb_caps","video/x-jpeg", + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('S','V','Q','3'): return GST_CAPS_NEW("SVQ3_caps","video/x-svq", - "svqversion", GST_PROPS_INT(3),NULL); + "svqversion", GST_PROPS_INT(3), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('s','v','q','i'): case GST_MAKE_FOURCC('S','V','Q','1'): return GST_CAPS_NEW("SVQ1_caps","video/x-svq", - "svqversion", GST_PROPS_INT(1),NULL); + "svqversion", GST_PROPS_INT(1), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('r','a','w',' '): /* uncompressed RGB */ - return GST_CAPS_NEW("raw__caps","video/raw", - "format",GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' '))); + return GST_CAPS_NEW("raw__caps","video/x-raw-rgb", + "endianness",GST_PROPS_INT(G_BIG_ENDIAN), + /*"bpp", GST_PROPS_INT(x), + "depth", GST_PROPS_INT(x), + "red_mask", GST_PROPS_INT(x), + "green_mask", GST_PROPS_INT(x), + "blue_mask", GST_PROPS_INT(x), FIXME! */ + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('Y','u','v','2'): /* uncompressed YUV2 */ - return GST_CAPS_NEW("Yuv2_caps","video/raw", - "format",GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','V','2'))); + return GST_CAPS_NEW("Yuv2_caps","video/x-raw-yuv", + "format",GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','V','2')), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('m','p','e','g'): /* MPEG */ - return GST_CAPS_NEW("mpeg_caps","video/mpeg",NULL); + return GST_CAPS_NEW("mpeg_caps","video/mpeg", + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096), + "systemstream", GST_PROPS_BOOLEAN(FALSE), + "mpegversion", GST_PROPS_INT(1)); case GST_MAKE_FOURCC('g','i','f',' '): - return GST_CAPS_NEW("gif__caps","image/gif",NULL); + return GST_CAPS_NEW("gif__caps","image/gif", + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('h','2','6','3'): /* H.263 */ /* ffmpeg uses the height/width props, don't know why */ - return GST_CAPS_NEW("h263_caps","video/h263",NULL); + return GST_CAPS_NEW("h263_caps","video/x-h263", + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('m','p','4','v'): /* MPEG-4 */ return GST_CAPS_NEW("mp4v_caps", "video/mpeg", - "mpegversion",GST_PROPS_INT(4)); + "mpegversion",GST_PROPS_INT(4), + "systemstream", GST_PROPS_BOOLEAN(FALSE), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('3','I','V','1'): - return GST_CAPS_NEW("3IV1_caps", "video/3ivx",NULL); + return GST_CAPS_NEW("3IV1_caps", "video/x-3ivx", + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096)); case GST_MAKE_FOURCC('r','p','z','a'): case GST_MAKE_FOURCC('c','v','i','d'): /* Cinepak */ @@ -1564,12 +1644,10 @@ static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc) { switch(fourcc){ case GST_MAKE_FOURCC('N','O','N','E'): - return GST_CAPS_NEW("NONE_caps","audio/raw",NULL); + return NULL; /*GST_CAPS_NEW("NONE_caps","audio/raw",NULL);*/ case GST_MAKE_FOURCC('r','a','w',' '): /* FIXME */ - return GST_CAPS_NEW("raw__caps","audio/raw", - "format",GST_PROPS_STRING("int"), - "law", GST_PROPS_INT(0), + return GST_CAPS_NEW("raw__caps","audio/x-raw-int", "width",GST_PROPS_INT(8), "depth",GST_PROPS_INT(8), "signed",GST_PROPS_BOOLEAN(FALSE), @@ -1577,9 +1655,7 @@ static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc) "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('t','w','o','s'): /* FIXME */ - return GST_CAPS_NEW("twos_caps","audio/raw", - "format",GST_PROPS_STRING("int"), - "law", GST_PROPS_INT(0), + return GST_CAPS_NEW("twos_caps","audio/x-raw-int", "width",GST_PROPS_INT(16), "depth",GST_PROPS_INT(16), "endianness",GST_PROPS_INT(G_BIG_ENDIAN), @@ -1588,9 +1664,7 @@ static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc) "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('s','o','w','t'): /* FIXME */ - return GST_CAPS_NEW("sowt_caps","audio/raw", - "format",GST_PROPS_STRING("int"), - "law", GST_PROPS_INT(0), + return GST_CAPS_NEW("sowt_caps","audio/x-raw-int", "width",GST_PROPS_INT(16), "depth",GST_PROPS_INT(16), "endianness",GST_PROPS_INT(G_LITTLE_ENDIAN), @@ -1598,22 +1672,24 @@ static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc) "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('f','l','6','4'): - return GST_CAPS_NEW("fl64_caps","audio/raw", - "format",GST_PROPS_STRING("float"), - "layout",GST_PROPS_STRING("gdouble"), + return GST_CAPS_NEW("fl64_caps","audio/x-raw-float", + "depth",GST_PROPS_INT (64), + "endianness",GST_PROPS_INT (G_BIG_ENDIAN), + "intercept",GST_PROPS_FLOAT (0.0), + "slope",GST_PROPS_FLOAT (1.0), "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('f','l','3','2'): - return GST_CAPS_NEW("fl32_caps","audio/raw", - "format",GST_PROPS_STRING("float"), - "layout",GST_PROPS_STRING("gfloat"), + return GST_CAPS_NEW("fl32_caps","audio/x-raw-float", + "depth",GST_PROPS_INT (32), + "endianness",GST_PROPS_INT (G_BIG_ENDIAN), + "intercept",GST_PROPS_FLOAT (0.0), + "slope",GST_PROPS_FLOAT (1.0), "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('i','n','2','4'): /* FIXME */ - return GST_CAPS_NEW("in24_caps","audio/raw", - "format",GST_PROPS_STRING("int"), - "law", GST_PROPS_INT(0), + return GST_CAPS_NEW("in24_caps","audio/x-raw-int", "width",GST_PROPS_INT(24), "depth",GST_PROPS_INT(32), "endianness",GST_PROPS_INT(G_BIG_ENDIAN), @@ -1622,9 +1698,7 @@ static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc) "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('i','n','3','2'): /* FIXME */ - return GST_CAPS_NEW("in32_caps","audio/raw", - "format",GST_PROPS_STRING("int"), - "law", GST_PROPS_INT(0), + return GST_CAPS_NEW("in32_caps","audio/x-raw-int", "width",GST_PROPS_INT(24), "depth",GST_PROPS_INT(32), "endianness",GST_PROPS_INT(G_BIG_ENDIAN), @@ -1632,42 +1706,70 @@ static GstCaps *qtdemux_audio_caps(GstQTDemux *qtdemux, guint32 fourcc) "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('u','l','a','w'): /* FIXME */ - return GST_CAPS_NEW("ulaw_caps","audio/raw", - "format",GST_PROPS_STRING("int"), - "law", GST_PROPS_INT(2), + return GST_CAPS_NEW("ulaw_caps","audio/x-mulaw", "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case GST_MAKE_FOURCC('a','l','a','w'): /* FIXME */ - return GST_CAPS_NEW("alaw_caps","audio/raw", - "format",GST_PROPS_STRING("int"), - "law", GST_PROPS_INT(1), + return GST_CAPS_NEW("alaw_caps","audio/x-alaw", "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), "channels",GST_PROPS_INT_RANGE(1,G_MAXINT)); case 0x6d730002: /* Microsoft ADPCM-ACM code 2 */ - return GST_CAPS_NEW("msxx_caps","audio/adpcm",NULL); + return GST_CAPS_NEW("msxx_caps","audio/x-adpcm", + "layout", GST_PROPS_STRING("microsoft"), + "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), + "channels",GST_PROPS_INT_RANGE(1,G_MAXINT), + NULL); case 0x6d730011: /* FIXME DVI/Intel IMA ADPCM/ACM code 17 */ - return GST_CAPS_NEW("msxx_caps","audio/adpcm",NULL); + return GST_CAPS_NEW("msxx_caps","audio/x-adpcm", + "layout", GST_PROPS_STRING("quicktime"), + "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), + "channels",GST_PROPS_INT_RANGE(1,G_MAXINT), + NULL); case 0x6d730055: /* MPEG layer 3, CBR only (pre QT4.1) */ case GST_MAKE_FOURCC('.','m','p','3'): /* MPEG layer 3, CBR & VBR (QT4.1 and later) */ - return GST_CAPS_NEW("_mp3_caps","audio/x-mp3",NULL); + return GST_CAPS_NEW("_mp3_caps","audio/mpeg", + "layer", GST_PROPS_INT(3), + "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), + "channels",GST_PROPS_INT_RANGE(1,G_MAXINT), + NULL); case GST_MAKE_FOURCC('M','A','C','3'): /* MACE 3:1 */ return GST_CAPS_NEW("MAC3_caps","audio/x-mace", - "maceversion",GST_PROPS_INT(3), NULL); + "maceversion",GST_PROPS_INT(3), + "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), + "channels",GST_PROPS_INT_RANGE(1,G_MAXINT), + NULL); case GST_MAKE_FOURCC('M','A','C','6'): /* MACE 6:1 */ return GST_CAPS_NEW("MAC3_caps","audio/x-mace", - "maceversion",GST_PROPS_INT(6)); + "maceversion",GST_PROPS_INT(6), + "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), + "channels",GST_PROPS_INT_RANGE(1,G_MAXINT), + NULL); case GST_MAKE_FOURCC('O','g','g','V'): /* Ogg Vorbis */ - return GST_CAPS_NEW("OggV_caps","application/x-ogg", NULL); + return GST_CAPS_NEW("OggV_caps","application/ogg", + "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), + "channels",GST_PROPS_INT_RANGE(1,G_MAXINT), + NULL); case GST_MAKE_FOURCC('d','v','c','a'): /* DV audio */ + return GST_CAPS_NEW("dvca_caps","audio/x-dv", + "rate",GST_PROPS_INT_RANGE(1,G_MAXINT), + "channels",GST_PROPS_INT_RANGE(1,G_MAXINT), + NULL); + case GST_MAKE_FOURCC('m','p','4','a'): + /* MPEG-4 AAC */ + return GST_CAPS_NEW("mp4a_caps", "audio/mpeg", + "mpegversion", GST_PROPS_INT(4), + "rate", GST_PROPS_INT_RANGE(1, G_MAXINT), + "channels", GST_PROPS_INT_RANGE(1, G_MAXINT), + "systemstream", GST_PROPS_BOOLEAN(FALSE), NULL); case GST_MAKE_FOURCC('q','t','v','r'): /* ? */ case GST_MAKE_FOURCC('Q','D','M','2'): diff --git a/gst/rtjpeg/gstrtjpeg.c b/gst/rtjpeg/gstrtjpeg.c index 25ef3dfd..c8842882 100644 --- a/gst/rtjpeg/gstrtjpeg.c +++ b/gst/rtjpeg/gstrtjpeg.c @@ -27,7 +27,7 @@ extern GstElementDetails gst_rtjpegdec_details; GstTypeDefinition rtjpegdefinition = { "rtjpeg_video/rtjpeg", - "video/rtjpeg", + "video/x-rtjpeg", ".rtj", NULL, }; diff --git a/gst/smooth/gstsmooth.c b/gst/smooth/gstsmooth.c index d174977e..ec86c99d 100644 --- a/gst/smooth/gstsmooth.c +++ b/gst/smooth/gstsmooth.c @@ -22,6 +22,7 @@ #endif #include <string.h> #include <gstsmooth.h> +#include <gst/video/video.h> /* elementfactory information */ static GstElementDetails smooth_details = { @@ -53,10 +54,11 @@ GST_PAD_TEMPLATE_FACTORY (smooth_src_factory, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "smooth_src", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -64,10 +66,11 @@ GST_PAD_TEMPLATE_FACTORY (smooth_sink_factory, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "smooth_src", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -144,7 +147,7 @@ gst_smooth_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &filter->width); gst_caps_get_int (caps, "height", &filter->height); - return GST_PAD_LINK_OK; + return gst_pad_try_set_caps (filter->srcpad, caps); } static void diff --git a/gst/smpte/gstsmpte.c b/gst/smpte/gstsmpte.c index b6761427..bf042e4c 100644 --- a/gst/smpte/gstsmpte.c +++ b/gst/smpte/gstsmpte.c @@ -22,6 +22,7 @@ #endif #include <string.h> #include <gstsmpte.h> +#include <gst/video/video.h> #include "paint.h" /* elementfactory information */ @@ -39,10 +40,11 @@ GST_PAD_TEMPLATE_FACTORY (smpte_src_factory, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "smpte_src", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -50,12 +52,11 @@ GST_PAD_TEMPLATE_FACTORY (smpte_sink1_factory, "sink1", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "smpte_sink1", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT_RANGE (0, 4096), - "height", GST_PROPS_INT_RANGE (0, 4096) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -63,12 +64,11 @@ GST_PAD_TEMPLATE_FACTORY (smpte_sink2_factory, "sink2", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "smpte_sink2", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT_RANGE (0, 4096), - "height", GST_PROPS_INT_RANGE (0, 4096) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -174,8 +174,8 @@ gst_smpte_class_init (GstSMPTEClass *klass) g_param_spec_enum ("type", "Type", "The type of transition to use", GST_TYPE_SMPTE_TRANSITION_TYPE, 1, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FPS, - g_param_spec_int ("fps", "FPS", "Frames per second if no input files are given", - 1, 255, 1, G_PARAM_READWRITE)); + g_param_spec_float ("fps", "FPS", "Frames per second if no input files are given", + 0., G_MAXFLOAT, 25., G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BORDER, g_param_spec_int ("border", "Border", "The border width of the transition", 0, G_MAXINT, 0, G_PARAM_READWRITE)); @@ -235,6 +235,7 @@ gst_smpte_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &smpte->width); gst_caps_get_int (caps, "height", &smpte->height); + gst_caps_get_float (caps, "framerate", &smpte->fps); gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width, smpte->height); @@ -263,10 +264,10 @@ gst_smpte_init (GstSMPTE *smpte) smpte->width = 320; smpte->height = 200; + smpte->fps = 25.; smpte->duration = 64; smpte->position = 0; smpte->type = 1; - smpte->fps = 1; smpte->border = 0; smpte->depth = 16; gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width, smpte->height); @@ -359,7 +360,8 @@ gst_smpte_loop (GstElement *element) "video/raw", "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), "width", GST_PROPS_INT (smpte->width), - "height", GST_PROPS_INT (smpte->height) + "height", GST_PROPS_INT (smpte->height), + "framerate", GST_PROPS_FLOAT (smpte->fps) ))) { gst_element_error (element, "cannot set caps"); @@ -408,12 +410,12 @@ gst_smpte_set_property (GObject *object, guint prop_id, smpte->width, smpte->height); break; } - case ARG_FPS: - smpte->fps = g_value_get_int (value); - break; case ARG_BORDER: smpte->border = g_value_get_int (value); break; + case ARG_FPS: + smpte->fps = g_value_get_float (value); + break; case ARG_DEPTH: { gint depth = g_value_get_int (value); @@ -443,7 +445,7 @@ gst_smpte_get_property (GObject *object, guint prop_id, } break; case ARG_FPS: - g_value_set_int (value, smpte->fps); + g_value_set_float (value, smpte->fps); break; case ARG_BORDER: g_value_set_int (value, smpte->border); diff --git a/gst/smpte/gstsmpte.h b/gst/smpte/gstsmpte.h index 5c863890..c51d4fbe 100644 --- a/gst/smpte/gstsmpte.h +++ b/gst/smpte/gstsmpte.h @@ -44,6 +44,7 @@ struct _GstSMPTE { gint format; gint width; gint height; + gfloat fps; gint duration; gint position; @@ -53,7 +54,6 @@ struct _GstSMPTE { *sinkpad2; gint type; - gint fps; gint border; gint depth; GstMask *mask; diff --git a/gst/speed/gstspeed.c b/gst/speed/gstspeed.c index 42f9bb33..de91f3ca 100644 --- a/gst/speed/gstspeed.c +++ b/gst/speed/gstspeed.c @@ -65,9 +65,9 @@ speed_sink_factory (void) if (!template) { template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - gst_caps_append(gst_caps_new ("sink_int", "audio/raw", + gst_caps_append(gst_caps_new ("sink_int", "audio/x-raw-int", GST_AUDIO_INT_MONO_PAD_TEMPLATE_PROPS), - gst_caps_new ("sink_float", "audio/raw", + gst_caps_new ("sink_float", "audio/x-raw-float", GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS)), NULL); } @@ -82,9 +82,9 @@ speed_src_factory (void) if (!template) template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - gst_caps_append (gst_caps_new ("src_float", "audio/raw", + gst_caps_append (gst_caps_new ("src_float", "audio/x-raw-float", GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS), - gst_caps_new ("src_int", "audio/raw", + gst_caps_new ("src_int", "audio/x-raw-int", GST_AUDIO_INT_MONO_PAD_TEMPLATE_PROPS)), NULL); @@ -138,17 +138,17 @@ speed_connect (GstPad *pad, GstCaps *caps) static gboolean speed_parse_caps (GstSpeed *filter, GstCaps *caps) { - const gchar *format; + const gchar *mimetype; g_return_val_if_fail(filter!=NULL,-1); g_return_val_if_fail(caps!=NULL,-1); - gst_caps_get_string(caps, "format", &format); + mimetype = gst_caps_get_mime (caps); gst_caps_get_int (caps, "rate", &filter->rate); gst_caps_get_int (caps, "channels", &filter->channels); - if (strcmp(format, "int")==0) { + if (strcmp(mimetype, "audio/x-raw-int")==0) { filter->format = GST_SPEED_FORMAT_INT; gst_caps_get_int (caps, "width", &filter->width); gst_caps_get_int (caps, "depth", &filter->depth); @@ -162,17 +162,16 @@ speed_parse_caps (GstSpeed *filter, GstCaps *caps) g_print ("Speed : format int, bit width %d, endianness %d, signed %s\n", filter->width, filter->endianness, filter->is_signed ? "yes" : "no"); } - } else if (strcmp(format, "float")==0) { + } else if (strcmp(mimetype, "audio/x-raw-float")==0) { filter->format = GST_SPEED_FORMAT_FLOAT; - gst_caps_get_string (caps, "layout", &filter->layout); gst_caps_get_float (caps, "intercept", &filter->intercept); gst_caps_get_float (caps, "slope", &filter->slope); if (!filter->silent) { g_print ("Speed : channels %d, rate %d\n", filter->channels, filter->rate); - g_print ("Speed : format float, layout %s, intercept %f, slope %f\n", - filter->layout, filter->intercept, filter->slope); + g_print ("Speed : format float, intercept %f, slope %f\n", + filter->intercept, filter->slope); } } else { return FALSE; diff --git a/gst/speed/gstspeed.h b/gst/speed/gstspeed.h index 93694dfc..73fc783e 100644 --- a/gst/speed/gstspeed.h +++ b/gst/speed/gstspeed.h @@ -85,8 +85,6 @@ struct _GstSpeed { /* the next three are valid only for format==GST_SPEED_FORMAT_FLOAT */ - const gchar *layout; - gfloat slope; gfloat intercept; diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c index 53628471..6f10391b 100644 --- a/gst/videocrop/gstvideocrop.c +++ b/gst/videocrop/gstvideocrop.c @@ -21,6 +21,7 @@ #include "config.h" #endif #include <gst/gst.h> +#include <gst/video/video.h> #include <string.h> @@ -47,8 +48,8 @@ struct _GstVideoCrop { /* caps */ gint width, height; - gint crop_x, crop_y; - gint crop_width, crop_height; + gfloat fps; + gint crop_left, crop_right, crop_top, crop_bottom; }; struct _GstVideoCropClass { @@ -75,10 +76,10 @@ enum { enum { ARG_0, - ARG_X, - ARG_Y, - ARG_WIDTH, - ARG_HEIGHT, + ARG_LEFT, + ARG_RIGHT, + ARG_TOP, + ARG_BOTTOM, /* FILL ME */ }; @@ -86,10 +87,11 @@ GST_PAD_TEMPLATE_FACTORY (video_crop_src_template_factory, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "video_crop_src", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -97,10 +99,11 @@ GST_PAD_TEMPLATE_FACTORY (video_crop_sink_template_factory, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "video_crop_sink", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -157,17 +160,17 @@ gst_video_crop_class_init (GstVideoCropClass *klass) parent_class = g_type_class_ref(GST_TYPE_ELEMENT); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_X, - g_param_spec_int ("x", "X", "X offset of image", + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LEFT, + g_param_spec_int ("left", "Left", "Pixels to crop at left", 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_Y, - g_param_spec_int ("y", "Y", "Y offset of image", + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_RIGHT, + g_param_spec_int ("right", "Right", "Pixels to crop at right", 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_WIDTH, - g_param_spec_int ("width", "Width", "Width of image", + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TOP, + g_param_spec_int ("top", "Top", "Pixels to crop at top", 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_HEIGHT, - g_param_spec_int ("height", "Height", "Height of image", + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BOTTOM, + g_param_spec_int ("bottom", "Bottom", "Pixels to crop at bottom", 0, G_MAXINT, 0, G_PARAM_READWRITE)); gobject_class->set_property = gst_video_crop_set_property; @@ -190,10 +193,10 @@ gst_video_crop_init (GstVideoCrop *video_crop) GST_PAD_TEMPLATE_GET (video_crop_src_template_factory), "src"); gst_element_add_pad (GST_ELEMENT (video_crop), video_crop->srcpad); - video_crop->crop_x = 0; - video_crop->crop_y = 0; - video_crop->crop_width = 128; - video_crop->crop_height = 128; + video_crop->crop_right = 0; + video_crop->crop_left = 0; + video_crop->crop_top = 0; + video_crop->crop_bottom = 0; GST_FLAG_SET (video_crop, GST_ELEMENT_EVENT_AWARE); } @@ -210,17 +213,17 @@ gst_video_crop_set_property (GObject *object, guint prop_id, const GValue *value video_crop = GST_VIDEO_CROP (object); switch (prop_id) { - case ARG_X: - video_crop->crop_x = g_value_get_int (value); + case ARG_LEFT: + video_crop->crop_left = g_value_get_int (value); break; - case ARG_Y: - video_crop->crop_y = g_value_get_int (value); + case ARG_RIGHT: + video_crop->crop_right = g_value_get_int (value); break; - case ARG_WIDTH: - video_crop->crop_width = g_value_get_int (value); + case ARG_TOP: + video_crop->crop_top = g_value_get_int (value); break; - case ARG_HEIGHT: - video_crop->crop_height = g_value_get_int (value); + case ARG_BOTTOM: + video_crop->crop_bottom = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -238,17 +241,17 @@ gst_video_crop_get_property (GObject *object, guint prop_id, GValue *value, GPar video_crop = GST_VIDEO_CROP (object); switch (prop_id) { - case ARG_X: - g_value_set_int (value, video_crop->crop_x); + case ARG_LEFT: + g_value_set_int (value, video_crop->crop_left); break; - case ARG_Y: - g_value_set_int (value, video_crop->crop_y); + case ARG_RIGHT: + g_value_set_int (value, video_crop->crop_right); break; - case ARG_WIDTH: - g_value_set_int (value, video_crop->crop_width); + case ARG_TOP: + g_value_set_int (value, video_crop->crop_top); break; - case ARG_HEIGHT: - g_value_set_int (value, video_crop->crop_height); + case ARG_BOTTOM: + g_value_set_int (value, video_crop->crop_bottom); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -269,11 +272,7 @@ gst_video_crop_sink_connect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &video_crop->width); gst_caps_get_int (caps, "height", &video_crop->height); - - if (video_crop->crop_width + video_crop->crop_x > video_crop->width) - video_crop->crop_width = video_crop->width - video_crop->crop_x; - if (video_crop->crop_height + video_crop->crop_y > video_crop->height) - video_crop->crop_height = video_crop->height - video_crop->crop_y; + gst_caps_get_float (caps, "framerate", &video_crop->fps); return GST_PAD_LINK_OK; } @@ -283,44 +282,48 @@ gst_video_crop_i420 (GstVideoCrop *video_crop, GstBuffer *src_buffer, GstBuffer { guint8 *srcY, *srcU, *srcV; guint8 *destY, *destU, *destV; - gint width = video_crop->crop_width; - gint crop_height = video_crop->crop_height; + gint out_width = video_crop->width - + (video_crop->crop_left + video_crop->crop_right); + gint out_height = video_crop->height - + (video_crop->crop_top + video_crop->crop_bottom); gint src_stride = video_crop->width; - gint frame_size = video_crop->width * video_crop->height; + gint src_size = video_crop->width * video_crop->height; gint j; - srcY = GST_BUFFER_DATA (src_buffer) + (src_stride * video_crop->crop_y + video_crop->crop_x); + srcY = GST_BUFFER_DATA (src_buffer) + + (src_stride * video_crop->crop_top + video_crop->crop_left); destY = GST_BUFFER_DATA (dest_buffer); /* copy Y plane first */ - for (j = crop_height; j; j--) { - memcpy (destY, srcY, width); + for (j = 0; j < out_height; j++) { + memcpy (destY, srcY, out_width); srcY += src_stride; - destY += width; + destY += out_width; } - width >>= 1; + out_width >>= 1; src_stride >>= 1; - crop_height >>= 1; + out_height >>= 1; destU = destY; - destV = destU + ((video_crop->crop_width * crop_height) >> 1); + destV = destU + ((out_width * out_height) >> 1); - srcU = GST_BUFFER_DATA (src_buffer) + frame_size + ((src_stride * video_crop->crop_y + video_crop->crop_x) >> 1); - srcV = srcU + (frame_size >> 2); + srcU = GST_BUFFER_DATA (src_buffer) + src_size + + ((src_stride * video_crop->crop_top + video_crop->crop_left) >> 1); + srcV = srcU + (src_size >> 2); /* copy U plane */ - for (j = crop_height; j; j--) { - memcpy (destU, srcU, width); + for (j = 0; j < out_height; j++) { + memcpy (destU, srcU, out_width); srcU += src_stride; - destU += width; + destU += out_width; } /* copy U plane */ - for (j = crop_height; j; j--) { - memcpy (destV, srcV, width); + for (j = 0; j < out_height; j++) { + memcpy (destV, srcV, out_width); srcV += src_stride; - destV += width; + destV += out_width; } } @@ -329,6 +332,7 @@ gst_video_crop_chain (GstPad *pad, GstBuffer *buffer) { GstVideoCrop *video_crop; GstBuffer *outbuf; + gint new_width, new_height; video_crop = GST_VIDEO_CROP (gst_pad_get_parent (pad)); @@ -343,14 +347,20 @@ gst_video_crop_chain (GstPad *pad, GstBuffer *buffer) return; } + new_width = video_crop->width - + (video_crop->crop_left + video_crop->crop_right); + new_height = video_crop->height - + (video_crop->crop_top + video_crop->crop_bottom); + if (GST_PAD_CAPS (video_crop->srcpad) == NULL) { if (gst_pad_try_set_caps (video_crop->srcpad, GST_CAPS_NEW ( "video_crop_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT (video_crop->crop_width), - "height", GST_PROPS_INT (video_crop->crop_height) + "width", GST_PROPS_INT (new_width), + "height", GST_PROPS_INT (new_height), + "framerate", GST_PROPS_FLOAT (video_crop->fps) )) <= 0) { gst_element_error (GST_ELEMENT (video_crop), "could not negotiate pads"); @@ -358,7 +368,7 @@ gst_video_crop_chain (GstPad *pad, GstBuffer *buffer) } } - outbuf = gst_buffer_new_and_alloc ((video_crop->crop_width * video_crop->crop_height * 3) / 2); + outbuf = gst_buffer_new_and_alloc ((new_width * new_height * 3) / 2); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer); gst_video_crop_i420 (video_crop, buffer, outbuf); diff --git a/gst/virtualdub/gstvirtualdub.c b/gst/virtualdub/gstvirtualdub.c index 4c7f9c8e..99122bcc 100644 --- a/gst/virtualdub/gstvirtualdub.c +++ b/gst/virtualdub/gstvirtualdub.c @@ -45,8 +45,7 @@ gst_virtualdub_src_factory (void) GST_PAD_ALWAYS, GST_CAPS_NEW ( "virtualdub_src", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), + "video/x-raw-rgb", "bpp", GST_PROPS_INT (32), "depth", GST_PROPS_INT (32), "endianness", GST_PROPS_INT (G_BYTE_ORDER), @@ -54,7 +53,8 @@ gst_virtualdub_src_factory (void) "green_mask", GST_PROPS_INT (0xff00), "blue_mask", GST_PROPS_INT (0xff), "width", GST_PROPS_INT_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096) + "height", GST_PROPS_INT_RANGE (16, 4096), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) ) ); } @@ -72,8 +72,7 @@ gst_virtualdub_sink_factory (void) GST_PAD_ALWAYS, GST_CAPS_NEW ( "virtualdub_sink", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), + "video/x-raw-rgb", "bpp", GST_PROPS_INT (32), "depth", GST_PROPS_INT (32), "endianness", GST_PROPS_INT (G_BYTE_ORDER), @@ -81,7 +80,8 @@ gst_virtualdub_sink_factory (void) "green_mask", GST_PROPS_INT (0xff00), "blue_mask", GST_PROPS_INT (0xff), "width", GST_PROPS_INT_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096) + "height", GST_PROPS_INT_RANGE (16, 4096), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) ) ); } diff --git a/gst/y4m/gsty4mencode.c b/gst/y4m/gsty4mencode.c index d84873bd..9c413f08 100644 --- a/gst/y4m/gsty4mencode.c +++ b/gst/y4m/gsty4mencode.c @@ -21,14 +21,16 @@ #include "config.h" #endif #include <string.h> +#include <math.h> #include <gst/gst.h> +#include <gst/video/video.h> #include "gsty4mencode.h" -static GstElementDetails lavencode_details = { - "LavEncode", +static GstElementDetails y4mencode_details = { + "Y4mEncode", "Codec/Video/Encoder", "LGPL", - "Encodes a YUV frame into the lav format (mjpeg_tools)", + "Encodes a YUV frame into the yuv4mpeg format (mjpegtools)", VERSION, "Wim Taymans <wim.taymans@chello.be>", "(C) 2001", @@ -45,65 +47,75 @@ enum { ARG_0 }; -GST_PAD_TEMPLATE_FACTORY (lavencode_src_factory, +GST_PAD_TEMPLATE_FACTORY (y4mencode_src_factory, "src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_CAPS_NEW ( "test_src", - "application/x-lav", - NULL + "application/x-yuv4mpeg", + "y4mversion", GST_PROPS_INT (1) ) ) -GST_PAD_TEMPLATE_FACTORY (lavencode_sink_factory, +GST_PAD_TEMPLATE_FACTORY (y4mencode_sink_factory, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "test_src", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) -static void gst_lavencode_class_init (GstLavEncodeClass *klass); -static void gst_lavencode_init (GstLavEncode *filter); +static void gst_y4mencode_class_init (GstY4mEncodeClass *klass); +static void gst_y4mencode_init (GstY4mEncode *filter); -static void gst_lavencode_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_lavencode_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_y4mencode_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gst_y4mencode_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); -static void gst_lavencode_chain (GstPad *pad, GstBuffer *buf); -static GstElementStateReturn gst_lavencode_change_state (GstElement *element); +static void gst_y4mencode_chain (GstPad *pad, + GstBuffer *buf); +static GstElementStateReturn + gst_y4mencode_change_state (GstElement *element); static GstElementClass *parent_class = NULL; /*static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; */ GType -gst_lavencode_get_type(void) { - static GType lavencode_type = 0; +gst_y4mencode_get_type(void) { + static GType y4mencode_type = 0; - if (!lavencode_type) { - static const GTypeInfo lavencode_info = { - sizeof(GstLavEncodeClass), NULL, + if (!y4mencode_type) { + static const GTypeInfo y4mencode_info = { + sizeof(GstY4mEncodeClass), + NULL, NULL, - (GClassInitFunc)gst_lavencode_class_init, + (GClassInitFunc)gst_y4mencode_class_init, NULL, NULL, - sizeof(GstLavEncode), + sizeof(GstY4mEncode), 0, - (GInstanceInitFunc)gst_lavencode_init, + (GInstanceInitFunc)gst_y4mencode_init, }; - lavencode_type = g_type_register_static(GST_TYPE_ELEMENT, "GstLavEncode", &lavencode_info, 0); + y4mencode_type = g_type_register_static(GST_TYPE_ELEMENT, + "GstY4mEncode", + &y4mencode_info, 0); } - return lavencode_type; + return y4mencode_type; } static void -gst_lavencode_class_init (GstLavEncodeClass *klass) +gst_y4mencode_class_init (GstY4mEncodeClass *klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; @@ -113,48 +125,74 @@ gst_lavencode_class_init (GstLavEncodeClass *klass) parent_class = g_type_class_ref(GST_TYPE_ELEMENT); - gstelement_class->change_state = gst_lavencode_change_state; + gstelement_class->change_state = gst_y4mencode_change_state; - gobject_class->set_property = gst_lavencode_set_property; - gobject_class->get_property = gst_lavencode_get_property; + gobject_class->set_property = gst_y4mencode_set_property; + gobject_class->get_property = gst_y4mencode_get_property; } static GstPadLinkReturn -gst_lavencode_sinkconnect (GstPad *pad, GstCaps *caps) +gst_y4mencode_sinkconnect (GstPad *pad, GstCaps *caps) { - GstLavEncode *filter; - - filter = GST_LAVENCODE (gst_pad_get_parent (pad)); + GstY4mEncode *filter; + gint idx = -1, i; + gfloat fps; + float framerates[] = { + 00.000, + 23.976, 24.000, /* 24fps movie */ + 25.000, /* PAL */ + 29.970, 30.000, /* NTSC */ + 50.000, + 59.940, 60.000 + }; + + filter = GST_Y4MENCODE (gst_pad_get_parent (pad)); if (!GST_CAPS_IS_FIXED (caps)) return GST_PAD_LINK_DELAYED; gst_caps_get_int (caps, "width", &filter->width); gst_caps_get_int (caps, "height", &filter->height); + gst_caps_get_float (caps, "framerate", &fps); + + /* find fps idx */ + for (i = 1; i < 9; i++) { + if (idx == -1) { + idx = i; + } else { + gfloat old_diff = fabs(framerates[idx] - fps), + new_diff = fabs(framerates[i] - fps); + + if (new_diff < old_diff) { + idx = i; + } + } + } + filter->fps_idx = idx; return GST_PAD_LINK_OK; } static void -gst_lavencode_init (GstLavEncode *filter) +gst_y4mencode_init (GstY4mEncode *filter) { filter->sinkpad = gst_pad_new_from_template( - GST_PAD_TEMPLATE_GET (lavencode_sink_factory), "sink"); + GST_PAD_TEMPLATE_GET (y4mencode_sink_factory), "sink"); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); - gst_pad_set_chain_function (filter->sinkpad, gst_lavencode_chain); - gst_pad_set_link_function (filter->sinkpad, gst_lavencode_sinkconnect); + gst_pad_set_chain_function (filter->sinkpad, gst_y4mencode_chain); + gst_pad_set_link_function (filter->sinkpad, gst_y4mencode_sinkconnect); filter->srcpad = gst_pad_new_from_template( - GST_PAD_TEMPLATE_GET (lavencode_src_factory), "src"); + GST_PAD_TEMPLATE_GET (y4mencode_src_factory), "src"); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); filter->init = TRUE; } static void -gst_lavencode_chain (GstPad *pad,GstBuffer *buf) +gst_y4mencode_chain (GstPad *pad,GstBuffer *buf) { - GstLavEncode *filter; + GstY4mEncode *filter; GstBuffer* outbuf; gchar *header; gint len; @@ -163,9 +201,9 @@ gst_lavencode_chain (GstPad *pad,GstBuffer *buf) g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(buf != NULL); - filter = GST_LAVENCODE (gst_pad_get_parent (pad)); + filter = GST_Y4MENCODE (gst_pad_get_parent (pad)); g_return_if_fail(filter != NULL); - g_return_if_fail(GST_IS_LAVENCODE(filter)); + g_return_if_fail(GST_IS_Y4MENCODE(filter)); outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (buf) + 256); @@ -178,7 +216,8 @@ gst_lavencode_chain (GstPad *pad,GstBuffer *buf) header = "FRAME\n"; } - snprintf (GST_BUFFER_DATA (outbuf), 255, header, filter->width, filter->height, 3); + snprintf (GST_BUFFER_DATA (outbuf), 255, header, + filter->width, filter->height, filter->fps_idx); len = strlen (GST_BUFFER_DATA (outbuf)); memcpy (GST_BUFFER_DATA (outbuf) + len, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); @@ -190,13 +229,13 @@ gst_lavencode_chain (GstPad *pad,GstBuffer *buf) } static void -gst_lavencode_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +gst_y4mencode_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - GstLavEncode *filter; + GstY4mEncode *filter; /* it's not null if we got it, but it might not be ours */ - g_return_if_fail(GST_IS_LAVENCODE(object)); - filter = GST_LAVENCODE(object); + g_return_if_fail(GST_IS_Y4MENCODE(object)); + filter = GST_Y4MENCODE(object); switch (prop_id) { default: @@ -205,13 +244,13 @@ gst_lavencode_set_property (GObject *object, guint prop_id, const GValue *value, } static void -gst_lavencode_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +gst_y4mencode_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - GstLavEncode *filter; + GstY4mEncode *filter; /* it's not null if we got it, but it might not be ours */ - g_return_if_fail(GST_IS_LAVENCODE(object)); - filter = GST_LAVENCODE(object); + g_return_if_fail(GST_IS_Y4MENCODE(object)); + filter = GST_Y4MENCODE(object); switch (prop_id) { default: @@ -221,13 +260,13 @@ gst_lavencode_get_property (GObject *object, guint prop_id, GValue *value, GPara } static GstElementStateReturn -gst_lavencode_change_state (GstElement *element) +gst_y4mencode_change_state (GstElement *element) { - GstLavEncode *filter; + GstY4mEncode *filter; - g_return_val_if_fail (GST_IS_LAVENCODE (element), GST_STATE_FAILURE); + g_return_val_if_fail (GST_IS_Y4MENCODE (element), GST_STATE_FAILURE); - filter = GST_LAVENCODE(element); + filter = GST_Y4MENCODE(element); if (GST_STATE_TRANSITION (element) == GST_STATE_NULL_TO_READY) { filter->init = TRUE; @@ -244,14 +283,14 @@ plugin_init (GModule *module, GstPlugin *plugin) { GstElementFactory *factory; - factory = gst_element_factory_new("lavenc",GST_TYPE_LAVENCODE, - &lavencode_details); + factory = gst_element_factory_new("y4menc",GST_TYPE_Y4MENCODE, + &y4mencode_details); g_return_val_if_fail(factory != NULL, FALSE); gst_element_factory_add_pad_template (factory, - GST_PAD_TEMPLATE_GET (lavencode_src_factory)); + GST_PAD_TEMPLATE_GET (y4mencode_src_factory)); gst_element_factory_add_pad_template (factory, - GST_PAD_TEMPLATE_GET (lavencode_sink_factory)); + GST_PAD_TEMPLATE_GET (y4mencode_sink_factory)); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); @@ -261,6 +300,6 @@ plugin_init (GModule *module, GstPlugin *plugin) GstPluginDesc plugin_desc = { GST_VERSION_MAJOR, GST_VERSION_MINOR, - "lavenc", + "y4menc", plugin_init }; diff --git a/gst/y4m/gsty4mencode.h b/gst/y4m/gsty4mencode.h index 2e0af15f..a42ad727 100644 --- a/gst/y4m/gsty4mencode.h +++ b/gst/y4m/gsty4mencode.h @@ -18,8 +18,8 @@ */ -#ifndef __GST_LAVENCODE_H__ -#define __GST_LAVENCODE_H__ +#ifndef __GST_Y4MENCODE_H__ +#define __GST_Y4MENCODE_H__ #include <config.h> @@ -32,40 +32,41 @@ extern "C" { #endif /* __cplusplus */ -#define GST_TYPE_LAVENCODE \ - (gst_lavencode_get_type()) -#define GST_LAVENCODE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_LAVENCODE,GstLavEncode)) -#define GST_LAVENCODE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstLavEncode)) -#define GST_IS_LAVENCODE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_LAVENCODE)) -#define GST_IS_LAVENCODE_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_LAVENCODE)) +#define GST_TYPE_Y4MENCODE \ + (gst_y4mencode_get_type()) +#define GST_Y4MENCODE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_Y4MENCODE,GstY4mEncode)) +#define GST_Y4MENCODE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstY4mEncode)) +#define GST_IS_Y4MENCODE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_Y4MENCODE)) +#define GST_IS_Y4MENCODE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_Y4MENCODE)) -typedef struct _GstLavEncode GstLavEncode; -typedef struct _GstLavEncodeClass GstLavEncodeClass; +typedef struct _GstY4mEncode GstY4mEncode; +typedef struct _GstY4mEncodeClass GstY4mEncodeClass; -struct _GstLavEncode { +struct _GstY4mEncode { GstElement element; GstPad *sinkpad,*srcpad; gint width, height; + gfloat fps_idx; gboolean init; }; -struct _GstLavEncodeClass { +struct _GstY4mEncodeClass { GstElementClass parent_class; }; -GType gst_lavencode_get_type(void); +GType gst_y4mencode_get_type(void); #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* __GST_STEREO_H__ */ +#endif /* __GST_Y4MENCODE_H__ */ |