diff options
74 files changed, 1863 insertions, 1585 deletions
diff --git a/configure.ac b/configure.ac index 08981793f..18d7bece0 100644 --- a/configure.ac +++ b/configure.ac @@ -409,34 +409,35 @@ dnl FIXME: add check if this platform can support linking to a dnl non-PIC libXv, if not then don not use Xv. dnl FIXME: perhaps warn user if they have a shared libXv since dnl this is an error until XFree86 starts shipping one -translit(dnm, m, l) AM_CONDITIONAL(USE_XVIDEO, true) - -GST_CHECK_FEATURE(XVIDEO, [X11 XVideo extensions], xvideosink, [ - if test -z $X_DISPLAY_MISSING; then - HAVE_XVIDEO=yes +translit(dnm, m, l) AM_CONDITIONAL(USE_XFREE, true) +GST_CHECK_FEATURE(XFREE, [X11 XFree86], xvideosink-X, [ + if test "-DX_DISPLAY_MISSING" = "$X_CFLAGS"; then + HAVE_XFREE=no else - HAVE_XVIDEO=no + HAVE_XFREE=yes fi ]) dnl Check for Xv extension - -if test x$HAVE_XVIDEO = xyes; then - AC_CHECK_LIB(Xv_pic, XvQueryExtension, HAVE_XV="yes", HAVE_XV="no", $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) - - if test x$HAVE_XV = xyes; then - AC_DEFINE(HAVE_XV, 1, [Define if Xv extension is available]) +translit(dnm, m, l) AM_CONDITIONAL(USE_XVIDEO, true) +GST_CHECK_FEATURE(XVIDEO, [X11 XVideo extensions], xvideosink-Xv, [ + if test x$HAVE_XFREE = xyes; then + AC_CHECK_LIB(Xv_pic, XvQueryExtension, + HAVE_XVIDEO="yes", HAVE_XVIDEO="no", + $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) XVIDEO_LIBS="-lXv_pic -lXext" - AC_SUBST(XVIDEO_LIBS) - else - AC_CHECK_LIB(Xv, XvQueryExtension, HAVE_XVIDEO="yes", HAVE_XVIDEO="no", $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) - if test x$HAVE_XV = xyes; then - AC_DEFINE(HAVE_XV, 1, [Define if Xv extension is available]) + + dnl try again using something else if we didn't find it first + if test x$HAVE_XVIDEO = xno; then + AC_CHECK_LIB(Xv, XvQueryExtension, + HAVE_XVIDEO="yes", HAVE_XVIDEO="no", + $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) XVIDEO_LIBS="-lXv -lXext" - AC_SUBST(XVIDEO_LIBS) fi + + AC_SUBST(XVIDEO_LIBS) fi -fi +]) dnl Next, check for the optional libraries: dnl These are all libraries used in building plug-ins diff --git a/ext/arts/gst_arts.c b/ext/arts/gst_arts.c index 482c91b4e..fd2d1be3a 100644 --- a/ext/arts/gst_arts.c +++ b/ext/arts/gst_arts.c @@ -47,9 +47,7 @@ GST_PAD_TEMPLATE_FACTORY ( sink_temp, GST_PAD_ALWAYS, GST_CAPS_NEW ( "arts_sample", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), + "audio/x-raw-int", "depth", GST_PROPS_INT (16), "width", GST_PROPS_INT (16), "signed", GST_PROPS_BOOLEAN (TRUE), @@ -64,9 +62,7 @@ GST_PAD_TEMPLATE_FACTORY ( src_temp, GST_PAD_ALWAYS, GST_CAPS_NEW ( "arts_sample", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), + "audio/x-raw-int", "depth", GST_PROPS_INT (16), "width", GST_PROPS_INT (16), "signed", GST_PROPS_BOOLEAN (TRUE), diff --git a/ext/artsd/gstartsdsink.c b/ext/artsd/gstartsdsink.c index 2847d8af1..894b3cd5a 100644 --- a/ext/artsd/gstartsdsink.c +++ b/ext/artsd/gstartsdsink.c @@ -45,9 +45,6 @@ enum { enum { ARG_0, ARG_MUTE, - ARG_DEPTH, - ARG_CHANNELS, - ARG_RATE, ARG_NAME, }; @@ -57,27 +54,24 @@ GST_PAD_TEMPLATE_FACTORY (sink_factory, GST_PAD_ALWAYS, /* ALWAYS/SOMETIMES */ GST_CAPS_NEW ( "artsdsink_sink", /* the name of the caps */ - "audio/raw", /* the mime type of the caps */ + "audio/x-raw-int", /* the mime type of the caps */ "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), + "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, 96000), - "channels", GST_PROPS_LIST (GST_PROPS_INT (1), GST_PROPS_INT (2)) - ), - GST_CAPS_NEW ( - "artsdsink_sink", /* the name of the caps */ - "audio/raw", /* the mime type of the caps */ - "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_LIST (GST_PROPS_INT (1), GST_PROPS_INT (2)) + "channels", GST_PROPS_LIST ( + GST_PROPS_INT (1), + GST_PROPS_INT (2) + ) ) ); @@ -88,7 +82,7 @@ static gboolean gst_artsdsink_open_audio (GstArtsdsink *sink); static void gst_artsdsink_close_audio (GstArtsdsink *sink); static GstElementStateReturn gst_artsdsink_change_state (GstElement *element); static gboolean gst_artsdsink_sync_parms (GstArtsdsink *artsdsink); - +static GstPadLinkReturn gst_artsdsink_link (GstPad *pad, GstCaps *caps); static void gst_artsdsink_chain (GstPad *pad, GstBuffer *buf); static void gst_artsdsink_set_property (GObject *object, guint prop_id, @@ -96,39 +90,6 @@ static void gst_artsdsink_set_property (GObject *object, guint prop_id, static void gst_artsdsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -#define GST_TYPE_ARTSDSINK_DEPTHS (gst_artsdsink_depths_get_type()) -static GType -gst_artsdsink_depths_get_type (void) -{ - static GType artsdsink_depths_type = 0; - static GEnumValue artsdsink_depths[] = { - {8, "8", "8 Bits"}, - {16, "16", "16 Bits"}, - {0, NULL, NULL}, - }; - if (!artsdsink_depths_type) { - artsdsink_depths_type = g_enum_register_static("GstArtsdsinkDepths", artsdsink_depths); - } - return artsdsink_depths_type; -} - -#define GST_TYPE_ARTSDSINK_CHANNELS (gst_artsdsink_channels_get_type()) -static GType -gst_artsdsink_channels_get_type (void) -{ - static GType artsdsink_channels_type = 0; - static GEnumValue artsdsink_channels[] = { - {1, "1", "Mono"}, - {2, "2", "Stereo"}, - {0, NULL, NULL}, - }; - if (!artsdsink_channels_type) { - artsdsink_channels_type = g_enum_register_static("GstArtsdsinkChannels", artsdsink_channels); - } - return artsdsink_channels_type; -} - - static GstElementClass *parent_class = NULL; /*static guint gst_artsdsink_signals[LAST_SIGNAL] = { 0 }; */ @@ -167,15 +128,7 @@ gst_artsdsink_class_init (GstArtsdsinkClass *klass) g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MUTE, g_param_spec_boolean("mute","mute","mute", TRUE,G_PARAM_READWRITE)); /* CHECKME */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEPTH, - g_param_spec_enum("depth","depth","depth", - GST_TYPE_ARTSDSINK_DEPTHS,16,G_PARAM_READWRITE)); /* CHECKME! */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CHANNELS, - g_param_spec_enum("channels","channels","channels", - GST_TYPE_ARTSDSINK_CHANNELS,2,G_PARAM_READWRITE)); /* CHECKME! */ - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_RATE, - g_param_spec_int("frequency","frequency","frequency", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); /* CHECKME */ + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NAME, g_param_spec_string("name","name","name", NULL, G_PARAM_READWRITE)); /* CHECKME */ @@ -193,15 +146,10 @@ gst_artsdsink_init(GstArtsdsink *artsdsink) GST_PAD_TEMPLATE_GET (sink_factory), "sink"); gst_element_add_pad(GST_ELEMENT(artsdsink), artsdsink->sinkpad); gst_pad_set_chain_function(artsdsink->sinkpad, gst_artsdsink_chain); + gst_pad_set_link_function(artsdsink->sinkpad, gst_artsdsink_link); artsdsink->connected = FALSE; artsdsink->mute = FALSE; - - /* FIXME: get default from somewhere better than just putting them inline. */ - artsdsink->signd = TRUE; - artsdsink->depth = 16; - artsdsink->channels = 2; - artsdsink->frequency = 44100; artsdsink->connect_name = NULL; } @@ -218,6 +166,26 @@ gst_artsdsink_sync_parms (GstArtsdsink *artsdsink) return gst_artsdsink_open_audio (artsdsink); } +static GstPadLinkReturn +gst_artsdsink_link (GstPad *pad, GstCaps *caps) +{ + GstArtsdsink *artsdsink = GST_ARTSDSINK (gst_pad_get_parent (pad)); + + if (!GST_CAPS_FIXED (caps)) + return GST_PAD_LINK_DELAYED; + + gst_caps_get (caps, + "rate", &artsdsink->frequency, + "depth", &artsdsink->depth, + "signed", &artsdsink->signd, + "channels", &artsdsink->channels, + NULL); + + if (gst_artsdsink_sync_parms (artsdsink)) + return GST_PAD_LINK_OK; + + return GST_PAD_LINK_REFUSED; +} static void gst_artsdsink_chain (GstPad *pad, GstBuffer *buf) @@ -267,18 +235,6 @@ gst_artsdsink_set_property (GObject *object, guint prop_id, const GValue *value, case ARG_MUTE: artsdsink->mute = g_value_get_boolean (value); break; - case ARG_DEPTH: - artsdsink->depth = g_value_get_enum (value); - gst_artsdsink_sync_parms (artsdsink); - break; - case ARG_CHANNELS: - artsdsink->channels = g_value_get_enum (value); - gst_artsdsink_sync_parms (artsdsink); - break; - case ARG_RATE: - artsdsink->frequency = g_value_get_int (value); - gst_artsdsink_sync_parms (artsdsink); - break; case ARG_NAME: if (artsdsink->connect_name != NULL) g_free(artsdsink->connect_name); if (g_value_get_string (value) == NULL) @@ -304,15 +260,6 @@ gst_artsdsink_get_property (GObject *object, guint prop_id, GValue *value, GPara case ARG_MUTE: g_value_set_boolean (value, artsdsink->mute); break; - case ARG_DEPTH: - g_value_set_enum (value, artsdsink->depth); - break; - case ARG_CHANNELS: - g_value_set_enum (value, artsdsink->channels); - break; - case ARG_RATE: - g_value_set_int (value, artsdsink->frequency); - break; case ARG_NAME: g_value_set_string (value, artsdsink->connect_name); break; diff --git a/ext/audiofile/gstafparse.c b/ext/audiofile/gstafparse.c index 2ceb4ee70..255247e8c 100644 --- a/ext/audiofile/gstafparse.c +++ b/ext/audiofile/gstafparse.c @@ -59,9 +59,7 @@ GST_PAD_TEMPLATE_FACTORY (afparse_src_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "audiofile_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_LIST (GST_PROPS_BOOLEAN (TRUE), GST_PROPS_BOOLEAN (FALSE)), "width", GST_PROPS_INT_RANGE (8, 16), @@ -87,7 +85,7 @@ GST_PAD_TEMPLATE_FACTORY (afparse_sink_factory, ), GST_CAPS_NEW ( "afparse_sink_snd", - "audio/basic", + "audio/x-au", NULL ) ) @@ -215,7 +213,7 @@ gst_afparse_loop(GstElement *element) } if (bypass_afread){ - g_print("will bypass afReadFrames\n"); + GST_DEBUG("will bypass afReadFrames\n"); } frames_to_bytes = afparse->channels * afparse->width / 8; @@ -352,7 +350,7 @@ gst_afparse_open_file (GstAFParse *afparse) /* open the file */ - g_print("opening vfile %p\n", afparse->vfile); + GST_DEBUG("opening vfile %p\n", afparse->vfile); afparse->file = afOpenVirtualFile (afparse->vfile, "r", AF_NULL_FILESETUP); if (afparse->file == AF_NULL_FILEHANDLE) { @@ -361,7 +359,7 @@ gst_afparse_open_file (GstAFParse *afparse) return FALSE; } - g_print("vfile opened\n"); + GST_DEBUG("vfile opened\n"); /* get the audiofile audio parameters */ { int sampleFormat, sampleWidth; @@ -393,9 +391,7 @@ gst_afparse_open_file (GstAFParse *afparse) gst_pad_try_set_caps (afparse->srcpad, GST_CAPS_NEW ( "af_src", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), /*FIXME */ + "audio/x-raw-int", "endianness", GST_PROPS_INT (G_BYTE_ORDER), /*FIXME */ "signed", GST_PROPS_BOOLEAN (afparse->is_signed), "width", GST_PROPS_INT (afparse->width), @@ -444,22 +440,19 @@ gst_afparse_vf_read (AFvirtualfile *vfile, void *data, size_t nbytes) /*g_print("no event found with %u bytes\n", got_bytes);*/ return 0; } - if (event){ - g_print("got event\n"); - if (GST_EVENT_TYPE(event) == GST_EVENT_EOS){ + switch (GST_EVENT_TYPE(event)) { + case GST_EVENT_EOS: return 0; - } - else if (GST_EVENT_TYPE(event) == GST_EVENT_FLUSH){ - g_print("flush\n"); - } - else if (GST_EVENT_TYPE(event) == GST_EVENT_DISCONTINUOUS){ - g_print("seek done\n"); + case GST_EVENT_FLUSH: + GST_DEBUG("flush"); + break; + case GST_EVENT_DISCONTINUOUS: + GST_DEBUG("seek done"); got_bytes = gst_bytestream_peek_bytes(bs, &bytes, nbytes); - } - else { - g_print("unknown event %d", GST_EVENT_TYPE(event)); + break; + default: + g_warning("unknown event %d", GST_EVENT_TYPE(event)); got_bytes = gst_bytestream_peek_bytes(bs, &bytes, nbytes); - } } } @@ -493,7 +486,7 @@ gst_afparse_vf_seek (AFvirtualfile *vfile, long offset, int is_relative) } if (gst_bytestream_seek(bs, (gint64)offset, method)){ - g_print("doing seek to %d\n", (gint)offset); + GST_DEBUG("doing seek to %d", (gint)offset); return offset; } return 0; @@ -502,11 +495,12 @@ gst_afparse_vf_seek (AFvirtualfile *vfile, long offset, int is_relative) static long gst_afparse_vf_length (AFvirtualfile *vfile) { - /*GstByteStream *bs = (GstByteStream*)vfile->closure;*/ - /* FIXME there is currently no practical way to do this. - * wait for the events rewrite to drop */ - g_warning("cannot get length at the moment"); - return G_MAXLONG; + GstByteStream *bs = (GstByteStream*)vfile->closure; + guint64 length; + + length = gst_bytestream_length(bs); + GST_DEBUG("doing length: %" G_GUINT64_FORMAT, length); + return length; } static ssize_t @@ -522,7 +516,7 @@ gst_afparse_vf_destroy(AFvirtualfile *vfile) { /* GstByteStream *bs = (GstByteStream*)vfile->closure;*/ - g_print("doing destroy\n"); + GST_DEBUG("doing destroy"); } static long @@ -532,7 +526,7 @@ gst_afparse_vf_tell (AFvirtualfile *vfile) guint64 offset; offset = gst_bytestream_tell(bs); - g_print("doing tell: %" G_GUINT64_FORMAT "\n", offset); + GST_DEBUG("doing tell: %" G_GUINT64_FORMAT, offset); return offset; } diff --git a/ext/audiofile/gstafsink.c b/ext/audiofile/gstafsink.c index e9783ac20..3392717c4 100644 --- a/ext/audiofile/gstafsink.c +++ b/ext/audiofile/gstafsink.c @@ -61,9 +61,7 @@ GST_PAD_TEMPLATE_FACTORY (afsink_sink_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "audiofile_sink", - "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_LIST ( GST_PROPS_BOOLEAN (TRUE), diff --git a/ext/audiofile/gstafsrc.c b/ext/audiofile/gstafsrc.c index cf2ebb568..2b8173102 100644 --- a/ext/audiofile/gstafsrc.c +++ b/ext/audiofile/gstafsrc.c @@ -60,9 +60,7 @@ GST_PAD_TEMPLATE_FACTORY (afsrc_src_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "audiofile_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_LIST ( GST_PROPS_BOOLEAN (TRUE), @@ -345,9 +343,7 @@ gst_afsrc_open_file (GstAFSrc *src) gst_pad_try_set_caps (src->srcpad, GST_CAPS_NEW ( "af_src", - "audio/raw", - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), /*FIXME */ + "audio/x-raw-int", "endianness", GST_PROPS_INT (G_BYTE_ORDER), /*FIXME */ "signed", GST_PROPS_BOOLEAN (src->is_signed), "width", GST_PROPS_INT (src->width), diff --git a/ext/divx/gstdivxdec.c b/ext/divx/gstdivxdec.c index 0ee308b81..011836f9b 100644 --- a/ext/divx/gstdivxdec.c +++ b/ext/divx/gstdivxdec.c @@ -43,28 +43,42 @@ GST_PAD_TEMPLATE_FACTORY(sink_template, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW("divxdec_sink", - "video/divx", - NULL) + GST_CAPS_NEW( + "divxdec_sink", + "video/x-divx", + "divxversion", GST_PROPS_INT_RANGE(3, 5), + "width", GST_PROPS_INT_RANGE(0, G_MAXINT), + "height", GST_PROPS_INT_RANGE(0, G_MAXINT), + "framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT) + ) ) GST_PAD_TEMPLATE_FACTORY(src_template, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW("divxdec_src", - "video/raw", - "format", GST_PROPS_LIST( - GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','Y','U','V')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) - ), - "width", GST_PROPS_INT_RANGE(0, G_MAXINT), - "height", GST_PROPS_INT_RANGE(0, G_MAXINT), - NULL) + gst_caps_new( + "divxdec_src", + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_LIST( + GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) + ) + ) + ), + gst_caps_new( + "divxdec_src_rgb1", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32 + ), + gst_caps_new( + "divxdec_src_rgb2", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16 + ) ) @@ -87,6 +101,7 @@ static void gst_divxdec_chain (GstPad *pad, GstBuffer *buf); static GstPadLinkReturn gst_divxdec_connect (GstPad *pad, GstCaps *vscapslist); +static GstPadLinkReturn gst_divxdec_negotiate (GstDivxDec *divxdec); static GstElementClass *parent_class = NULL; /* static guint gst_divxdec_signals[LAST_SIGNAL] = { 0 }; */ @@ -261,10 +276,12 @@ gst_divxdec_chain (GstPad *pad, divxdec = GST_DIVXDEC(GST_OBJECT_PARENT(pad)); if (!divxdec->handle) { - gst_element_error(GST_ELEMENT(divxdec), - "No format set - aborting"); - gst_buffer_unref(buf); - return; + if (gst_divxdec_negotiate(divxdec) <= 0) { + gst_element_error(GST_ELEMENT(divxdec), + "No format set - aborting"); + gst_buffer_unref(buf); + return; + } } outbuf = gst_buffer_new_and_alloc(divxdec->width * @@ -297,10 +314,9 @@ gst_divxdec_chain (GstPad *pad, static GstPadLinkReturn -gst_divxdec_connect (GstPad *pad, - GstCaps *vscaps) +gst_divxdec_negotiate (GstDivxDec *divxdec) { - GstDivxDec *divxdec; + GstPadLinkReturn ret; GstCaps *caps; struct { guint32 fourcc; @@ -314,8 +330,6 @@ gst_divxdec_connect (GstPad *pad, GST_MAKE_FOURCC('U','Y','V','Y'), 0 }, { GST_MAKE_FOURCC('I','4','2','0'), 12, 12, GST_MAKE_FOURCC('I','4','2','0'), 0 }, - { GST_MAKE_FOURCC('I','Y','U','V'), 12, 12, - GST_MAKE_FOURCC('I','4','2','0'), 0 }, { GST_MAKE_FOURCC('Y','V','1','2'), 12, 12, GST_MAKE_FOURCC('Y','V','1','2'), 0 }, { GST_MAKE_FOURCC('R','G','B',' '), 32, 32, @@ -338,69 +352,59 @@ gst_divxdec_connect (GstPad *pad, }; gint i; - divxdec = GST_DIVXDEC(gst_pad_get_parent (pad)); - - /* if there's something old around, remove it */ - if (divxdec->handle) { - gst_divxdec_unset(divxdec); - } - - /* we are not going to act on variable caps */ - if (!GST_CAPS_IS_FIXED(vscaps)) - return GST_PAD_LINK_DELAYED; - - /* if we get here, we know the input is divx. we - * only need to bother with the output colorspace */ - gst_caps_get_int(vscaps, "width", &divxdec->width); - gst_caps_get_int(vscaps, "height", &divxdec->height); - for (i = 0; fmt_list[i].fourcc != 0; i++) { divxdec->csp = fmt_list[i].csp; /* try making a caps to set on the other side */ if (fmt_list[i].fourcc == GST_MAKE_FOURCC('R','G','B',' ')) { guint32 r_mask = 0, b_mask = 0, g_mask = 0; + gint endianness = 0; switch (fmt_list[i].depth) { case 15: + endianness = G_BYTE_ORDER; r_mask = 0xf800; g_mask = 0x07c0; b_mask = 0x003e; break; case 16: + endianness = G_BYTE_ORDER; r_mask = 0xf800; g_mask = 0x07e0; b_mask = 0x001f; break; case 24: - r_mask = 0xff0000; g_mask = 0x00ff00; b_mask = 0x0000ff; + endianness = G_BIG_ENDIAN; + r_mask = R_MASK_24; g_mask = G_MASK_24; b_mask = B_MASK_24; break; case 32: - r_mask = 0xff000000; g_mask = 0x00ff0000; b_mask = 0x0000ff00; + endianness = G_BIG_ENDIAN; + r_mask = R_MASK_32; g_mask = G_MASK_32; b_mask = B_MASK_32; break; } caps = GST_CAPS_NEW("divxdec_src_pad_rgb", - "video/raw", + "video/x-raw-rgb", "width", GST_PROPS_INT(divxdec->width), "height", GST_PROPS_INT(divxdec->height), - "format", GST_PROPS_FOURCC(fmt_list[i].fourcc), + "framerate", GST_PROPS_FLOAT(divxdec->fps), "depth", GST_PROPS_INT(fmt_list[i].depth), "bpp", GST_PROPS_INT(fmt_list[i].bpp), - "endianness", GST_PROPS_INT(G_BYTE_ORDER), + "endianness", GST_PROPS_INT(endianness), "red_mask", GST_PROPS_INT(r_mask), "green_mask", GST_PROPS_INT(g_mask), - "blue_mask", GST_PROPS_INT(b_mask), - NULL); + "blue_mask", GST_PROPS_INT(b_mask)); } else { caps = GST_CAPS_NEW("divxdec_src_pad_yuv", - "video/raw", + "video/x-raw-yuv", "width", GST_PROPS_INT(divxdec->width), "height", GST_PROPS_INT(divxdec->height), - "format", GST_PROPS_FOURCC(fmt_list[i].fourcc), - NULL); + "framerate", GST_PROPS_FLOAT(divxdec->fps), + "format", GST_PROPS_FOURCC(fmt_list[i].fourcc)); } - if (gst_pad_try_set_caps(divxdec->srcpad, caps) > 0) { + if ((ret = gst_pad_try_set_caps(divxdec->srcpad, caps)) > 0) { divxdec->csp = fmt_list[i].csp; divxdec->bpp = fmt_list[i].bpp; divxdec->bitcnt = fmt_list[i].bitcnt; if (gst_divxdec_setup(divxdec)) return GST_PAD_LINK_OK; + } else if (ret == GST_PAD_LINK_DELAYED) { + return ret; /* trying more is useless */ } } @@ -409,6 +413,33 @@ gst_divxdec_connect (GstPad *pad, } +static GstPadLinkReturn +gst_divxdec_connect (GstPad *pad, + GstCaps *vscaps) +{ + GstDivxDec *divxdec; + + divxdec = GST_DIVXDEC(gst_pad_get_parent (pad)); + + /* if there's something old around, remove it */ + if (divxdec->handle) { + gst_divxdec_unset(divxdec); + } + + /* we are not going to act on variable caps */ + if (!GST_CAPS_IS_FIXED(vscaps)) + return GST_PAD_LINK_DELAYED; + + /* if we get here, we know the input is divx. we + * only need to bother with the output colorspace */ + gst_caps_get_int(vscaps, "width", &divxdec->width); + gst_caps_get_int(vscaps, "height", &divxdec->height); + gst_caps_get_float(vscaps, "framerate", &divxdec->fps); + + return gst_divxdec_negotiate(divxdec); +} + + static gboolean plugin_init (GModule *module, GstPlugin *plugin) diff --git a/ext/divx/gstdivxdec.h b/ext/divx/gstdivxdec.h index 35876bdb8..9f1da3ffe 100644 --- a/ext/divx/gstdivxdec.h +++ b/ext/divx/gstdivxdec.h @@ -55,6 +55,7 @@ struct _GstDivxDec { guint32 csp; int bitcnt, bpp; int width, height; + float fps; }; struct _GstDivxDecClass { diff --git a/ext/divx/gstdivxenc.c b/ext/divx/gstdivxenc.c index 24a266846..bd7547a14 100644 --- a/ext/divx/gstdivxenc.c +++ b/ext/divx/gstdivxenc.c @@ -44,28 +44,43 @@ GST_PAD_TEMPLATE_FACTORY(sink_template, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW("divxenc_sink", - "video/raw", - "format", GST_PROPS_LIST( - GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','Y','U','V')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) - ), - "width", GST_PROPS_INT_RANGE(0, G_MAXINT), - "height", GST_PROPS_INT_RANGE(0, G_MAXINT), - NULL) + gst_caps_new( + "divxdec_src", + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS( + GST_PROPS_LIST( + GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) + ) + ) + ), + gst_caps_new( + "divxdec_src_rgb1", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32 + ), + gst_caps_new( + "divxdec_src_rgb2", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16 + ) ) GST_PAD_TEMPLATE_FACTORY(src_template, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW("divxenc_src", - "video/divx", - NULL) + GST_CAPS_NEW( + "divxenc_sink", + "video/x-divx", + "divxversion", GST_PROPS_INT(5), + "width", GST_PROPS_INT_RANGE(0, G_MAXINT), + "height", GST_PROPS_INT_RANGE(0, G_MAXINT), + "framerate", GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT) + ) ) @@ -246,11 +261,8 @@ gst_divxenc_setup (GstDivxEnc *divxenc) void *handle = NULL; SETTINGS output; DivXBitmapInfoHeader input; - gdouble fps; int ret; - fps = gst_video_frame_rate(GST_PAD_PEER(divxenc->sinkpad)); - /* set it up */ memset(&input, 0, sizeof(DivXBitmapInfoHeader)); input.biSize = sizeof(DivXBitmapInfoHeader); @@ -266,9 +278,9 @@ gst_divxenc_setup (GstDivxEnc *divxenc) output.use_bidirect = 0; output.input_clock = 0; output.input_frame_period = 1000000; - output.internal_timescale = fps * 1000000; + output.internal_timescale = divxenc->fps * 1000000; output.max_key_interval = (divxenc->max_key_interval == -1) ? - (2 * fps) : + (2 * divxenc->fps) : divxenc->max_key_interval; output.key_frame_threshold = 0; output.vbv_bitrate = 0; @@ -340,13 +352,6 @@ gst_divxenc_chain (GstPad *pad, divxenc = GST_DIVXENC(GST_OBJECT_PARENT(pad)); - if (!divxenc->handle) { - if (!gst_divxenc_setup(divxenc)) { - gst_buffer_unref(buf); - return; - } - } - outbuf = gst_buffer_new_and_alloc(divxenc->buffer_size); GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf); @@ -397,21 +402,21 @@ gst_divxenc_connect (GstPad *pad, return GST_PAD_LINK_DELAYED; for (caps = vscaps; caps != NULL; caps = caps->next) { - int w,h,d; + gint w,h,d; + gfloat fps; guint32 fourcc; guint32 divx_cs; gint bitcnt = 0; gst_caps_get_int(caps, "width", &w); gst_caps_get_int(caps, "height", &h); + gst_caps_get_float(caps, "framerate", &fps); gst_caps_get_fourcc_int(caps, "format", &fourcc); switch (fourcc) { case GST_MAKE_FOURCC('I','4','2','0'): - case GST_MAKE_FOURCC('I','Y','U','V'): divx_cs = GST_MAKE_FOURCC('I','4','2','0'); break; case GST_MAKE_FOURCC('Y','U','Y','2'): - case GST_MAKE_FOURCC('Y','U','Y','V'): divx_cs = GST_MAKE_FOURCC('Y','U','Y','2'); break; case GST_MAKE_FOURCC('Y','V','1','2'): @@ -442,18 +447,32 @@ gst_divxenc_connect (GstPad *pad, goto trynext; } - /* grmbl, we only know the peer pad *after* - * linking, so we accept here, get the fps on - * the first cycle and set it all up then */ divxenc->csp = divx_cs; divxenc->bitcnt = bitcnt; divxenc->width = w; divxenc->height = h; - return gst_pad_try_set_caps(divxenc->srcpad, - GST_CAPS_NEW("divxenc_src_caps", - "video/divx", - "width", GST_PROPS_INT(w), - "height", GST_PROPS_INT(h))); + divxenc->fps = fps; + + /* try it */ + if (gst_divxenc_setup(divxenc)) { + GstPadLinkReturn ret; + GstCaps *new_caps; + + new_caps = GST_CAPS_NEW("divxenc_src_caps", + "video/x-divx", + "divxversion", GST_PROPS_INT(5), + "width", GST_PROPS_INT(w), + "height", GST_PROPS_INT(h), + "framerate", GST_PROPS_FLOAT(fps)); + + ret = gst_pad_try_set_caps(divxenc->srcpad, new_caps); + + if (ret <= 0) { + gst_divxenc_unset(divxenc); + } + + return ret; + } trynext: continue; diff --git a/ext/divx/gstdivxenc.h b/ext/divx/gstdivxenc.h index be1ddae5f..206659d32 100644 --- a/ext/divx/gstdivxenc.h +++ b/ext/divx/gstdivxenc.h @@ -64,6 +64,7 @@ struct _GstDivxEnc { guint32 csp; gint bitcnt; gint width, height; + gfloat fps; }; struct _GstDivxEncClass { diff --git a/ext/gsm/gstgsm.c b/ext/gsm/gstgsm.c index 32225ff78..e50dec2bb 100644 --- a/ext/gsm/gstgsm.c +++ b/ext/gsm/gstgsm.c @@ -32,16 +32,15 @@ GST_CAPS_FACTORY (gsm_caps_factory, GST_CAPS_NEW ( "gsm_gsm", "audio/x-gsm", - "rate", GST_PROPS_INT_RANGE (1000, 48000) + "rate", GST_PROPS_INT_RANGE (1000, 48000), + "channels", GST_PROPS_INT (1) ) ) GST_CAPS_FACTORY (raw_caps_factory, GST_CAPS_NEW ( "gsm_raw", - "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/ext/gsm/gstgsmdec.c b/ext/gsm/gstgsmdec.c index 957b832d2..e857feffa 100644 --- a/ext/gsm/gstgsmdec.c +++ b/ext/gsm/gstgsmdec.c @@ -122,9 +122,7 @@ gst_gsmdec_sinkconnect (GstPad *pad, GstCaps *caps) if (gst_pad_try_set_caps (gsmdec->srcpad, GST_CAPS_NEW ( "gsm_raw", - "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/ext/gsm/gstgsmenc.c b/ext/gsm/gstgsmenc.c index 2b25042fe..9a41430b7 100644 --- a/ext/gsm/gstgsmenc.c +++ b/ext/gsm/gstgsmenc.c @@ -131,7 +131,8 @@ gst_gsmenc_sinkconnect (GstPad *pad, GstCaps *caps) if (gst_pad_try_set_caps (gsmenc->srcpad, GST_CAPS_NEW ( "gsm_gsm", "audio/x-gsm", - "rate", GST_PROPS_INT (gsmenc->rate) + "rate", GST_PROPS_INT (gsmenc->rate), + "channels", GST_PROPS_INT (1) )) > 0) { return GST_PAD_LINK_OK; @@ -158,7 +159,8 @@ gst_gsmenc_chain (GstPad *pad, GstBuffer *buf) GST_CAPS_NEW ( "gsm_enc", "audio/x-gsm", - "rate", GST_PROPS_INT (gsmenc->rate) + "rate", GST_PROPS_INT (gsmenc->rate), + "channels", GST_PROPS_INT (1) )); } diff --git a/ext/hermes/gstcolorspace.c b/ext/hermes/gstcolorspace.c index 7e99a7497..86b3fc6be 100644 --- a/ext/hermes/gstcolorspace.c +++ b/ext/hermes/gstcolorspace.c @@ -21,6 +21,7 @@ #include "config.h" #endif #include <gst/gst.h> +#include <gst/video/video.h> #include "gstcolorspace.h" #include "yuv2rgb.h" @@ -50,42 +51,6 @@ enum { ARG_DEST, }; -GST_PAD_TEMPLATE_FACTORY (colorspace_src_template_factory, - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_CAPS_NEW ( - "colorspace_src", - "video/raw", - "format", GST_PROPS_LIST ( - GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YV12")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")) - ), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT) - ) -) - -GST_PAD_TEMPLATE_FACTORY (colorspace_sink_template_factory, - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_CAPS_NEW ( - "colorspace_sink", - "video/raw", - "format", GST_PROPS_LIST ( - GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YV12")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")) - ), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT) - ) -) - static void gst_colorspace_class_init (GstColorspaceClass *klass); static void gst_colorspace_init (GstColorspace *space); @@ -110,6 +75,7 @@ extern void gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *de extern void gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height); +static GstPadTemplate *srctempl, *sinktempl; static GstElementClass *parent_class = NULL; /*static guint gst_colorspace_signals[LAST_SIGNAL] = { 0 }; */ @@ -134,10 +100,20 @@ colorspace_setup_converter (GstColorspace *space, GstCaps *from_caps, GstCaps *t g_return_val_if_fail (to_caps != NULL, FALSE); g_return_val_if_fail (from_caps != NULL, FALSE); - gst_caps_get_fourcc_int (from_caps, "format", &from_space); - gst_caps_get_fourcc_int (to_caps, "format", &to_space); + if (gst_caps_has_property (from_caps, "format")) + gst_caps_get_fourcc_int (from_caps, "format", &from_space); + else + from_space = GST_MAKE_FOURCC ('R','G','B',' '); + + if (gst_caps_has_property (to_caps, "format")) + gst_caps_get_fourcc_int (to_caps, "format", &to_space); + else + to_space = GST_MAKE_FOURCC ('R','G','B',' '); - GST_INFO ( "set up converter for %08x to %08x", from_space, to_space); + GST_INFO ("set up converter for " GST_FOURCC_FORMAT + " (%08x) to " GST_FOURCC_FORMAT " (%08x)", + GST_FOURCC_ARGS (from_space), from_space, + GST_FOURCC_ARGS (to_space), to_space); switch (from_space) { case GST_MAKE_FOURCC ('R','G','B',' '): @@ -308,6 +284,7 @@ gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &space->width); gst_caps_get_int (caps, "height", &space->height); + gst_caps_get_float (caps, "framerate", &space->fps); GST_INFO ( "size: %dx%d", space->width, space->height); @@ -367,12 +344,20 @@ gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps) gst_caps_unref (peercaps); } - to_intersect = GST_CAPS_NEW ( + to_intersect = gst_caps_append ( + GST_CAPS_NEW ( "colorspace_filter", - "video/raw", - "width", GST_PROPS_INT (space->width), - "height", GST_PROPS_INT (space->height) - ); + "video/x-raw-yuv", + "width", GST_PROPS_INT (space->width), + "height", GST_PROPS_INT (space->height), + "framerate", GST_PROPS_FLOAT (space->fps) + ), GST_CAPS_NEW ( + "colorspace_filter", + "video/x-raw-rgb", + "width", GST_PROPS_INT (space->width), + "height", GST_PROPS_INT (space->height), + "framerate", GST_PROPS_FLOAT (space->fps) + )); /* then see what the peer has that matches the size */ peercaps = gst_caps_intersect (caps, to_intersect); @@ -456,16 +441,14 @@ gst_colorspace_class_init (GstColorspaceClass *klass) static void gst_colorspace_init (GstColorspace *space) { - space->sinkpad = gst_pad_new_from_template ( - GST_PAD_TEMPLATE_GET (colorspace_sink_template_factory), "sink"); + space->sinkpad = gst_pad_new_from_template (sinktempl, "sink"); gst_pad_set_link_function (space->sinkpad, gst_colorspace_sinkconnect); gst_pad_set_getcaps_function (space->sinkpad, gst_colorspace_getcaps); gst_pad_set_bufferpool_function (space->sinkpad, colorspace_get_bufferpool); gst_pad_set_chain_function(space->sinkpad,gst_colorspace_chain); gst_element_add_pad(GST_ELEMENT(space),space->sinkpad); - space->srcpad = gst_pad_new_from_template ( - GST_PAD_TEMPLATE_GET (colorspace_src_template_factory), "src"); + space->srcpad = gst_pad_new_from_template (srctempl, "src"); gst_element_add_pad(GST_ELEMENT(space),space->srcpad); gst_pad_set_link_function (space->srcpad, gst_colorspace_srcconnect); @@ -623,6 +606,7 @@ static gboolean plugin_init (GModule *module, GstPlugin *plugin) { GstElementFactory *factory; + GstCaps *caps; #ifdef HAVE_HERMES gint hermes_res; @@ -634,11 +618,37 @@ plugin_init (GModule *module, GstPlugin *plugin) &colorspace_details); g_return_val_if_fail (factory != NULL, FALSE); gst_element_factory_set_rank (factory, GST_ELEMENT_RANK_PRIMARY); - - gst_element_factory_add_pad_template (factory, - GST_PAD_TEMPLATE_GET (colorspace_src_template_factory)); - gst_element_factory_add_pad_template (factory, - GST_PAD_TEMPLATE_GET (colorspace_sink_template_factory)); + + /* create caps for templates */ + caps = gst_caps_new ("csp_templ_yuv", + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("YV12")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2"))))); + caps = gst_caps_append (caps, + gst_caps_new ("csp_templ_rgb24_32", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32)); + caps = gst_caps_append (caps, + gst_caps_new ("csp_templ_rgb15_16", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16)); + + /* build templates */ + srctempl = gst_pad_template_new ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + caps, NULL); + gst_caps_ref (caps); + sinktempl = gst_pad_template_new ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + caps, NULL); + + gst_element_factory_add_pad_template (factory, srctempl); + gst_element_factory_add_pad_template (factory, sinktempl); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); diff --git a/ext/hermes/gstcolorspace.h b/ext/hermes/gstcolorspace.h index 37a80c5cd..45371c72d 100644 --- a/ext/hermes/gstcolorspace.h +++ b/ext/hermes/gstcolorspace.h @@ -76,6 +76,7 @@ struct _GstColorspace { GstColorSpaceConverterType type; gint width, height; + gfloat fps; gint srcbpp, destbpp; gboolean disabled; diff --git a/ext/ivorbis/vorbis.c b/ext/ivorbis/vorbis.c index b543f88f3..4a95c14eb 100644 --- a/ext/ivorbis/vorbis.c +++ b/ext/ivorbis/vorbis.c @@ -37,7 +37,7 @@ vorbis_caps_factory (void) return gst_caps_new ( "tremor_tremor", - "application/x-ogg", + "application/ogg", NULL); } @@ -47,10 +47,8 @@ raw_caps_factory (void) return gst_caps_new ( "tremor_raw", - "audio/raw", + "audio/x-raw-int", gst_props_new ( - "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), @@ -66,18 +64,18 @@ raw_caps2_factory (void) return gst_caps_new ( "tremor_raw_float", - "audio/raw", + "audio/x-raw-float", gst_props_new ( - "format", GST_PROPS_STRING ("float"), - "layout", GST_PROPS_STRING ("IEEE"), + "depth", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), "rate", GST_PROPS_INT_RANGE (11025, 48000), - "channels", GST_PROPS_INT (2), + "channels", GST_PROPS_INT (2), /* ?? */ NULL)); } static GstTypeDefinition vorbisdefinition = { "tremor_audio/x-ogg", - "application/x-ogg", + "application/ogg", ".ogg", vorbis_type_find, }; @@ -90,7 +88,7 @@ vorbis_type_find (GstBuffer *buf, gpointer private) if (head != 0x4F676753) return NULL; - return gst_caps_new ("vorbis_type_find", "application/x-ogg", NULL); + return gst_caps_new ("vorbis_type_find", "application/ogg", NULL); } diff --git a/ext/ivorbis/vorbisfile.c b/ext/ivorbis/vorbisfile.c index 76763f220..3e869e1dc 100644 --- a/ext/ivorbis/vorbisfile.c +++ b/ext/ivorbis/vorbisfile.c @@ -82,7 +82,7 @@ GstElementDetails ivorbisfile_details = "GPL", "Decodes OGG Vorbis audio using the Tremor vorbisfile API", VERSION, - "Monty <monty@xiph.org>, " + "Monty <monty@xiph.org>\n" "Wim Taymans <wim.taymans@chello.be>", "(C) 2000", }; @@ -448,26 +448,24 @@ static gboolean gst_ivorbisfile_new_link (Ivorbisfile *ivorbisfile, gint link) { vorbis_info *vi = ov_info (&ivorbisfile->vf, link); + GstCaps *newcaps; /* new logical bitstream */ ivorbisfile->current_link = link; gst_ivorbisfile_update_metadata (ivorbisfile, link); gst_ivorbisfile_update_streaminfo (ivorbisfile, link); - - if (gst_pad_try_set_caps (ivorbisfile->srcpad, - GST_CAPS_NEW ("vorbisdec_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 (vi->rate), - "channels", GST_PROPS_INT (vi->channels) - )) <= 0) - { + + newcaps = GST_CAPS_NEW ("vorbisdec_src", + "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 (vi->rate), + "channels", GST_PROPS_INT (vi->channels) + ); + if (gst_pad_try_set_caps (ivorbisfile->srcpad, newcaps) <= 0) { return FALSE; } diff --git a/ext/jack/gstjack.c b/ext/jack/gstjack.c index 8db6c56b0..700cf0aea 100644 --- a/ext/jack/gstjack.c +++ b/ext/jack/gstjack.c @@ -167,11 +167,14 @@ gst_jack_src_request_pad_factory(void) { static GstPadTemplate *template = NULL; - if (!template) - template = gst_pad_template_new("%s", GST_PAD_SRC, GST_PAD_REQUEST, - gst_caps_new("src", "audio/raw", - GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS), - NULL); + if (!template) { + GstCaps *caps; + caps = gst_caps_new("src", + "audio/x-raw-float", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS); + template = gst_pad_template_new("%s", GST_PAD_SRC, + GST_PAD_REQUEST, caps, NULL); + } return template; } @@ -181,11 +184,14 @@ gst_jack_sink_request_pad_factory(void) { static GstPadTemplate *template = NULL; - if (!template) - template = gst_pad_template_new("%s", GST_PAD_SINK, GST_PAD_REQUEST, - gst_caps_new("sink", "audio/raw", - GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS), - NULL); + if (!template) { + GstCaps *caps; + caps = gst_caps_new ("sink", + "audio/x-raw-float", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS); + template = gst_pad_template_new("%s", GST_PAD_SINK, + GST_PAD_REQUEST, caps, NULL); + } return template; } diff --git a/ext/ladspa/gstladspa.c b/ext/ladspa/gstladspa.c index 55c0186db..ddaa7970d 100644 --- a/ext/ladspa/gstladspa.c +++ b/ext/ladspa/gstladspa.c @@ -33,10 +33,10 @@ GST_PAD_TEMPLATE_FACTORY (ladspa_sink_factory, GST_PAD_REQUEST, GST_CAPS_NEW ( "ladspa_sink", - "audio/raw", + "audio/x-raw-float", + "width", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), "rate", GST_PROPS_INT_RANGE (4000, 96000), - "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) @@ -49,10 +49,10 @@ GST_PAD_TEMPLATE_FACTORY (ladspa_src_factory, GST_PAD_REQUEST, GST_CAPS_NEW ( "ladspa_src", - "audio/raw", + "audio/x-raw-float", + "width", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), "rate", GST_PROPS_INT_RANGE (4000, 96000), - "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) @@ -542,10 +542,10 @@ gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad) GST_DEBUG ("forcing caps with rate %d", ladspa->samplerate); gst_pad_try_set_caps (pad, gst_caps_new ( "ladspa_src_caps", - "audio/raw", + "audio/x-raw-float", gst_props_new ( - "format", GST_PROPS_STRING ("float"), - "layout", GST_PROPS_STRING ("gfloat"), + "width", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), "intercept", GST_PROPS_FLOAT(0.0), "slope", GST_PROPS_FLOAT(1.0), "rate", GST_PROPS_INT (ladspa->samplerate), diff --git a/ext/lcs/gstcolorspace.c b/ext/lcs/gstcolorspace.c index c457f9a75..0ed3b2788 100644 --- a/ext/lcs/gstcolorspace.c +++ b/ext/lcs/gstcolorspace.c @@ -21,6 +21,7 @@ #include "config.h" #endif #include <gst/gst.h> +#include <gst/video/video.h> #include <lcs/lcs.h> #define GST_TYPE_COLORSPACE \ @@ -51,6 +52,7 @@ struct _GstColorspace { GstColorSpaceConverterType type; gint width, height; + gfloat fps; gboolean disabled; GstCaps *sinkcaps; @@ -86,42 +88,6 @@ enum { ARG_DEST, }; -GST_PAD_TEMPLATE_FACTORY (colorspace_src_template_factory, - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_CAPS_NEW ( - "colorspace_src", - "video/raw", - "format", GST_PROPS_LIST ( - GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YV12")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")) - ), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT) - ) -) - -GST_PAD_TEMPLATE_FACTORY (colorspace_sink_template_factory, - "sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_CAPS_NEW ( - "colorspace_sink", - "video/raw", - "format", GST_PROPS_LIST ( - GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YV12")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")) - ), - "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT) - ) -) - static GType gst_colorspace_get_type (void); static void gst_colorspace_class_init (GstColorspaceClass *klass); @@ -142,6 +108,7 @@ static void gst_colorspace_chain (GstPad *pad, GstBuffer *buf); static GstElementStateReturn gst_colorspace_change_state (GstElement *element); +static GstPadTemplate *srctempl, *sinktempl; static GstElementClass *parent_class = NULL; /*static guint gst_colorspace_signals[LAST_SIGNAL] = { 0 }; */ @@ -207,8 +174,15 @@ colorspace_setup_converter (GstColorspace *space, GstCaps *from_caps, GstCaps *t g_return_val_if_fail (to_caps != NULL, FALSE); g_return_val_if_fail (from_caps != NULL, FALSE); - gst_caps_get_fourcc_int (from_caps, "format", &from_space); - gst_caps_get_fourcc_int (to_caps, "format", &to_space); + if (gst_caps_has_property (from_caps, "format")) + gst_caps_get_fourcc_int (from_caps, "format", &from_space); + else + from_space = GST_MAKE_FOURCC ('R','G','B',' '); + + if (gst_caps_has_property (to_caps, "format")) + gst_caps_get_fourcc_int (to_caps, "format", &to_space); + else + to_space = GST_MAKE_FOURCC ('R','G','B',' '); from_format = colorspace_find_lcs_format (from_caps); to_format = colorspace_find_lcs_format (to_caps); @@ -260,6 +234,7 @@ gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &space->width); gst_caps_get_int (caps, "height", &space->height); + gst_caps_get_float (caps, "framerate", &space->fps); GST_INFO ( "size: %dx%d", space->width, space->height); @@ -313,12 +288,20 @@ gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps) } /* then see what the peer has that matches the size */ peercaps = gst_caps_intersect (caps, + gst_caps_append ( GST_CAPS_NEW ( "colorspace_filter", - "video/raw", - "width", GST_PROPS_INT (space->width), - "height", GST_PROPS_INT (space->height) - )); + "video/x-raw-yuv", + "width", GST_PROPS_INT (space->width), + "height", GST_PROPS_INT (space->height), + "framerate", GST_PROPS_FLOAT (space->fps) + ), GST_CAPS_NEW ( + "colorspace_filter", + "video/x-raw-rgb", + "width", GST_PROPS_INT (space->width), + "height", GST_PROPS_INT (space->height), + "framerate", GST_PROPS_FLOAT (space->fps) + ))); /* we are looping over the caps, so we have to get rid of the lists */ peercaps = gst_caps_normalize (peercaps); @@ -384,16 +367,14 @@ gst_colorspace_class_init (GstColorspaceClass *klass) static void gst_colorspace_init (GstColorspace *space) { - space->sinkpad = gst_pad_new_from_template ( - GST_PAD_TEMPLATE_GET (colorspace_sink_template_factory), "sink"); + space->sinkpad = gst_pad_new_from_template (sinktempl, "sink"); gst_pad_set_link_function (space->sinkpad, gst_colorspace_sinkconnect); gst_pad_set_getcaps_function (space->sinkpad, gst_colorspace_getcaps); gst_pad_set_bufferpool_function (space->sinkpad, colorspace_get_bufferpool); gst_pad_set_chain_function(space->sinkpad,gst_colorspace_chain); gst_element_add_pad(GST_ELEMENT(space),space->sinkpad); - space->srcpad = gst_pad_new_from_template ( - GST_PAD_TEMPLATE_GET (colorspace_src_template_factory), "src"); + space->srcpad = gst_pad_new_from_template (srctempl, "src"); gst_element_add_pad(GST_ELEMENT(space),space->srcpad); gst_pad_set_link_function (space->srcpad, gst_colorspace_srcconnect); @@ -511,17 +492,44 @@ static gboolean plugin_init (GModule *module, GstPlugin *plugin) { GstElementFactory *factory; + GstCaps *caps; lcs_init (NULL, NULL); factory = gst_element_factory_new ("colorspacelcs", GST_TYPE_COLORSPACE, &colorspace_details); g_return_val_if_fail (factory != NULL, FALSE); - - gst_element_factory_add_pad_template (factory, - GST_PAD_TEMPLATE_GET (colorspace_src_template_factory)); - gst_element_factory_add_pad_template (factory, - GST_PAD_TEMPLATE_GET (colorspace_sink_template_factory)); + + /* create caps for templates */ + caps = gst_caps_new ("csp_templ_yuv", + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("YV12")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2"))))); + caps = gst_caps_append (caps, + gst_caps_new ("csp_templ_rgb24_32", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32)); + caps = gst_caps_append (caps, + gst_caps_new ("csp_templ_rgb15_16", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16)); + + /* build templates */ + srctempl = gst_pad_template_new ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + caps, NULL); + gst_caps_ref (caps); + sinktempl = gst_pad_template_new ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + caps, NULL); + + gst_element_factory_add_pad_template (factory, srctempl); + gst_element_factory_add_pad_template (factory, sinktempl); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); @@ -534,11 +542,3 @@ GstPluginDesc plugin_desc = { "colorspacelcs", plugin_init }; - - - - - - - - diff --git a/ext/libfame/gstfamedec.c b/ext/libfame/gstfamedec.c index 03805f845..3cfa28696 100644 --- a/ext/libfame/gstfamedec.c +++ b/ext/libfame/gstfamedec.c @@ -24,6 +24,7 @@ #include <string.h> #include "gstlibfame.h" +#include <gst/video/video.h> #define FAMEENC_BUFFER_SIZE (300 * 1024) @@ -51,7 +52,6 @@ enum { enum { ARG_0, ARG_VERSION, - ARG_FRAMERATE, ARG_BITRATE, ARG_QUALITY, ARG_PATTERN, @@ -67,12 +67,11 @@ GST_PAD_TEMPLATE_FACTORY (sink_template_factory, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "famedec_sink_caps", - "video/raw", - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), - "width", GST_PROPS_INT_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0'))) ) ) @@ -83,72 +82,15 @@ GST_PAD_TEMPLATE_FACTORY (src_template_factory, GST_CAPS_NEW ( "famedec_src_caps", "video/mpeg", - "mpegversion", GST_PROPS_LIST ( - GST_PROPS_INT (1), GST_PROPS_INT (4)), + /* we don't need width/height/framerate */ + "mpegversion", GST_PROPS_LIST ( + GST_PROPS_INT (1), + GST_PROPS_INT (4) + ), "systemstream", GST_PROPS_BOOLEAN (FALSE) ) ); -#define MAX_FRAME_RATES 16 -typedef struct -{ - gint num; - gint den; -} frame_rate_entry; - -static const frame_rate_entry frame_rates[] = -{ - { 0, 0 }, - { 24000, 1001 }, - { 24, 1 }, - { 25, 1 }, - { 30000, 1001 }, - { 30, 1 }, - { 50, 1 }, - { 60000, 1001 }, - { 60, 1 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, -}; - -static gint -framerate_to_index (num, den) -{ - gint i; - - for (i = 0; i < MAX_FRAME_RATES; i++) { - if (frame_rates[i].num == num && frame_rates[i].den == den) - return i; - } - return 0; -} - -#define GST_TYPE_FAMEENC_FRAMERATE (gst_famedec_framerate_get_type()) -static GType -gst_famedec_framerate_get_type(void) { - static GType famedec_framerate_type = 0; - static GEnumValue famedec_framerate[] = { - {1, "1", "24000/1001 (23.97)"}, - {2, "2", "24"}, - {3, "3", "25"}, - {4, "4", "30000/1001 (29.97)"}, - {5, "5", "30"}, - {6, "6", "50"}, - {7, "7", "60000/1001 (59.94)"}, - {8, "8", "60"}, - {0, NULL, NULL}, - }; - if (!famedec_framerate_type) { - famedec_framerate_type = g_enum_register_static("GstFameEncFrameRate", famedec_framerate); - } - return famedec_framerate_type; -} - static void gst_famedec_class_init (GstFameEncClass *klass); static void gst_famedec_init (GstFameEnc *famedec); static void gst_famedec_dispose (GObject *object); @@ -276,9 +218,6 @@ gst_famedec_class_init (GstFameEncClass *klass) } } - g_object_class_install_property (gobject_class, ARG_FRAMERATE, - g_param_spec_enum ("framerate", "Frame Rate", "Number of frames per second", - GST_TYPE_FAMEENC_FRAMERATE, 3, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_BITRATE, g_param_spec_int ("bitrate", "Bitrate", "Target bitrate (0 = VBR)", 0, 5000000, 0, G_PARAM_READWRITE)); @@ -471,14 +410,6 @@ gst_famedec_set_property (GObject *object, guint prop_id, } switch (prop_id) { - case ARG_FRAMERATE: - { - gint index = g_value_get_enum (value); - - famedec->fp.frame_rate_num = frame_rates[index].num; - famedec->fp.frame_rate_den = frame_rates[index].den; - break; - } case ARG_BITRATE: famedec->fp.bitrate = g_value_get_int (value); break; @@ -525,13 +456,6 @@ gst_famedec_get_property (GObject *object, guint prop_id, famedec = GST_FAMEENC (object); switch (prop_id) { - case ARG_FRAMERATE: - { - gint index = framerate_to_index (famedec->fp.frame_rate_num, - famedec->fp.frame_rate_den); - g_value_set_enum (value, index); - break; - } case ARG_BITRATE: g_value_set_int (value, famedec->fp.bitrate); break; diff --git a/ext/libfame/gstlibfame.c b/ext/libfame/gstlibfame.c index 45ffee4ea..5d7be4738 100644 --- a/ext/libfame/gstlibfame.c +++ b/ext/libfame/gstlibfame.c @@ -22,8 +22,10 @@ #endif #include <fame.h> #include <string.h> +#include <math.h> #include "gstlibfame.h" +#include <gst/video/video.h> #define FAMEENC_BUFFER_SIZE (300 * 1024) @@ -50,7 +52,6 @@ enum { enum { ARG_0, ARG_VERSION, - ARG_FRAMERATE, ARG_BITRATE, ARG_QUALITY, ARG_PATTERN, @@ -66,12 +67,11 @@ GST_PAD_TEMPLATE_FACTORY (sink_template_factory, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "fameenc_sink_caps", - "video/raw", - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), - "width", GST_PROPS_INT_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0'))) ) ) @@ -82,13 +82,27 @@ GST_PAD_TEMPLATE_FACTORY (src_template_factory, GST_CAPS_NEW ( "fameenc_src_caps", "video/mpeg", - "mpegversion", GST_PROPS_LIST ( - GST_PROPS_INT (1), GST_PROPS_INT (4)), - "systemstream", GST_PROPS_BOOLEAN (FALSE) + "mpegversion", GST_PROPS_LIST ( + GST_PROPS_INT (1), + GST_PROPS_INT (4) + ), + "systemstream", GST_PROPS_BOOLEAN (FALSE), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096), + "framerate", GST_PROPS_LIST ( + GST_PROPS_FLOAT (24/1.001), + GST_PROPS_FLOAT (24.), + GST_PROPS_FLOAT (25.), + GST_PROPS_FLOAT (30/1.001), + GST_PROPS_FLOAT (30.), + GST_PROPS_FLOAT (50.), + GST_PROPS_FLOAT (60/1.001), + GST_PROPS_FLOAT (60.) + ) ) ); -#define MAX_FRAME_RATES 16 +#define MAX_FRAME_RATES 9 typedef struct { gint num; @@ -106,46 +120,30 @@ static const frame_rate_entry frame_rates[] = { 50, 1 }, { 60000, 1001 }, { 60, 1 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, }; static gint -framerate_to_index (num, den) +framerate_to_index (gfloat fps) { gint i; + gint idx = -1; - for (i = 0; i < MAX_FRAME_RATES; i++) { - if (frame_rates[i].num == num && frame_rates[i].den == den) - return i; + for (i = 1; i < MAX_FRAME_RATES; i++) { + if (idx == -1) { + idx = i; + } else { + gfloat old_diff = fabs((1. * frame_rates[idx].num / + frame_rates[idx].den) - fps), + new_diff = fabs((1. * frame_rates[i].num / + frame_rates[i].den) - fps); + + if (new_diff < old_diff) { + idx = i; + } + } } - return 0; -} -#define GST_TYPE_FAMEENC_FRAMERATE (gst_fameenc_framerate_get_type()) -static GType -gst_fameenc_framerate_get_type(void) { - static GType fameenc_framerate_type = 0; - static GEnumValue fameenc_framerate[] = { - {1, "1", "24000/1001 (23.97)"}, - {2, "2", "24"}, - {3, "3", "25"}, - {4, "4", "30000/1001 (29.97)"}, - {5, "5", "30"}, - {6, "6", "50"}, - {7, "7", "60000/1001 (59.94)"}, - {8, "8", "60"}, - {0, NULL, NULL}, - }; - if (!fameenc_framerate_type) { - fameenc_framerate_type = g_enum_register_static("GstFameEncFrameRate", fameenc_framerate); - } - return fameenc_framerate_type; + return idx; } static void gst_fameenc_class_init (GstFameEncClass *klass); @@ -275,9 +273,6 @@ gst_fameenc_class_init (GstFameEncClass *klass) } } - g_object_class_install_property (gobject_class, ARG_FRAMERATE, - g_param_spec_enum ("framerate", "Frame Rate", "Number of frames per second", - GST_TYPE_FAMEENC_FRAMERATE, 3, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, ARG_BITRATE, g_param_spec_int ("bitrate", "Bitrate", "Target bitrate (0 = VBR)", 0, 5000000, 0, G_PARAM_READWRITE)); @@ -302,7 +297,8 @@ gst_fameenc_class_init (GstFameEncClass *klass) static GstPadLinkReturn gst_fameenc_sinkconnect (GstPad *pad, GstCaps *caps) { - gint width, height; + gint width, height, fps_idx; + gfloat fps; GstFameEnc *fameenc; fameenc = GST_FAMEENC (gst_pad_get_parent (pad)); @@ -317,11 +313,17 @@ gst_fameenc_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &width); gst_caps_get_int (caps, "height", &height); + gst_caps_get_float (caps, "framerate", &fps); /* fameenc requires width and height to be multiples of 16 */ if (width % 16 != 0 || height % 16 != 0) return GST_PAD_LINK_REFUSED; + fps_idx = framerate_to_index (fps); + fameenc->fp.frame_rate_num = frame_rates[fps_idx].num; + fameenc->fp.frame_rate_den = frame_rates[fps_idx].den; + fameenc->time_interval = 0; + fameenc->fp.width = width; fameenc->fp.height = height; fameenc->fp.coding = (const char *) fameenc->pattern; @@ -445,7 +447,7 @@ gst_fameenc_chain (GstPad *pad, GstBuffer *buf) g_warning ("FAMEENC_BUFFER_SIZE is defined too low, encoded slice has size %d !\n", length); if (!fameenc->time_interval) { - fameenc->time_interval = GST_SECOND / fameenc->fp.frame_rate_num; + fameenc->time_interval = GST_SECOND * fameenc->fp.frame_rate_den / fameenc->fp.frame_rate_num; } fameenc->next_time += fameenc->time_interval; @@ -482,15 +484,6 @@ gst_fameenc_set_property (GObject *object, guint prop_id, } switch (prop_id) { - case ARG_FRAMERATE: - { - gint index = g_value_get_enum (value); - - fameenc->fp.frame_rate_num = frame_rates[index].num; - fameenc->fp.frame_rate_den = frame_rates[index].den; - fameenc->time_interval = 0; - break; - } case ARG_BITRATE: fameenc->fp.bitrate = g_value_get_int (value); break; @@ -537,13 +530,6 @@ gst_fameenc_get_property (GObject *object, guint prop_id, fameenc = GST_FAMEENC (object); switch (prop_id) { - case ARG_FRAMERATE: - { - gint index = framerate_to_index (fameenc->fp.frame_rate_num, - fameenc->fp.frame_rate_den); - g_value_set_enum (value, index); - break; - } case ARG_BITRATE: g_value_set_int (value, fameenc->fp.bitrate); break; diff --git a/ext/mplex/gstmplex.cc b/ext/mplex/gstmplex.cc index eec819986..1142dd78d 100644 --- a/ext/mplex/gstmplex.cc +++ b/ext/mplex/gstmplex.cc @@ -86,8 +86,8 @@ GST_PAD_TEMPLATE_FACTORY (audio_sink_factory, GST_PAD_REQUEST, GST_CAPS_NEW ( "sink_audio", - "audio/mp3", - NULL + "audio/mpeg", + "layer", GST_PROPS_RANGE (1, 3) ) ) @@ -97,7 +97,7 @@ GST_PAD_TEMPLATE_FACTORY (private_1_sink_factory, GST_PAD_REQUEST, GST_CAPS_NEW ( "sink_private1", - "audio/ac3", + "audio/x-ac3", NULL ) ) diff --git a/ext/sdl/sdlvideosink.c b/ext/sdl/sdlvideosink.c index eb5c2cc49..4a47bef3c 100644 --- a/ext/sdl/sdlvideosink.c +++ b/ext/sdl/sdlvideosink.c @@ -207,7 +207,6 @@ gst_sdlvideosink_get_sdl_from_fourcc (GstSDLVideoSink *sdlvideosink, switch (code) { case GST_MAKE_FOURCC('I','4','2','0'): - case GST_MAKE_FOURCC('I','Y','U','V'): return SDL_IYUV_OVERLAY; case GST_MAKE_FOURCC('Y','V','1','2'): return SDL_YV12_OVERLAY; @@ -377,7 +376,6 @@ gst_sdlvideosink_sinkconnect (GstPad *pad, switch (format) { case GST_MAKE_FOURCC('I','4','2','0'): - case GST_MAKE_FOURCC('I','Y','U','V'): case GST_MAKE_FOURCC('Y','V','1','2'): case GST_MAKE_FOURCC('Y','U','Y','2'): case GST_MAKE_FOURCC('Y','V','Y','U'): @@ -458,8 +456,7 @@ gst_sdlvideosink_chain (GstPad *pad, GstBuffer *buf) /* buf->yuv */ if (sdlvideosink->format == GST_MAKE_FOURCC('I','4','2','0') || - sdlvideosink->format == GST_MAKE_FOURCC('Y','V','1','2') || - sdlvideosink->format == GST_MAKE_FOURCC('I','Y','U','V')) + sdlvideosink->format == GST_MAKE_FOURCC('Y','V','1','2')) { sdlvideosink->yuv[0] = GST_BUFFER_DATA(buf); sdlvideosink->yuv[1] = sdlvideosink->yuv[0] + sdlvideosink->image_width*sdlvideosink->image_height; @@ -598,7 +595,6 @@ plugin_init (GModule *module, GstPlugin *plugin) GstCaps *caps; gint i; gulong format[6] = { GST_MAKE_FOURCC('I','4','2','0'), - GST_MAKE_FOURCC('I','Y','U','V'), GST_MAKE_FOURCC('Y','V','1','2'), GST_MAKE_FOURCC('Y','U','Y','2'), GST_MAKE_FOURCC('Y','V','Y','U'), @@ -611,14 +607,15 @@ plugin_init (GModule *module, GstPlugin *plugin) g_return_val_if_fail(factory != NULL, FALSE); /* make a list of all available caps */ - for (i=0;i<6;i++) + for (i=0;i<5;i++) { caps = gst_caps_new ("sdlvideosink_caps", - "video/raw", + "video/x-raw-yuv", gst_props_new ( "format", GST_PROPS_FOURCC(format[i]), "width", GST_PROPS_INT_RANGE (0, G_MAXINT), "height", GST_PROPS_INT_RANGE (0, G_MAXINT), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT), NULL ) ); capslist = gst_caps_append(capslist, caps); diff --git a/ext/shout/gstshout.c b/ext/shout/gstshout.c index a17c0c8c0..46908ee33 100644 --- a/ext/shout/gstshout.c +++ b/ext/shout/gstshout.c @@ -78,8 +78,11 @@ sink_template_factory (void) GST_PAD_ALWAYS, gst_caps_new ( "icecastsend_sink", - "audio/x-mp3", - NULL), + "audio/mpeg", + gst_props_new ( + "layer", GST_PROPS_INT_RANGE (1, 3), + NULL + )), NULL); } diff --git a/ext/snapshot/gstsnapshot.c b/ext/snapshot/gstsnapshot.c index 6af87f2ca..859d56001 100644 --- a/ext/snapshot/gstsnapshot.c +++ b/ext/snapshot/gstsnapshot.c @@ -24,6 +24,7 @@ #include <inttypes.h> #include "gstsnapshot.h" +#include <gst/video/video.h> #define MAX_HEIGHT 2048 @@ -42,15 +43,14 @@ GST_PAD_TEMPLATE_FACTORY (snapshot_src_factory, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "snapshot_src", - "video/raw", - "format", GST_PROPS_LIST ( + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_LIST ( GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")) - ), - "width", GST_PROPS_INT_RANGE(0, G_MAXINT), - "height", GST_PROPS_INT_RANGE(0, G_MAXINT) + )) ) ) @@ -58,15 +58,14 @@ GST_PAD_TEMPLATE_FACTORY (snapshot_sink_factory, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "snapshot_src", - "video/raw", - "format", GST_PROPS_LIST ( - GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")) - ), - "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_LIST ( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")) + )) ) ) @@ -172,6 +171,7 @@ gst_snapshot_sinkconnect (GstPad *pad, GstCaps *caps) { GstSnapshot *filter; GstCaps *from_caps, *to_caps; + gfloat fps; filter = GST_SNAPSHOT (gst_pad_get_parent (pad)); @@ -180,20 +180,21 @@ gst_snapshot_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &filter->width); gst_caps_get_int (caps, "height", &filter->height); + gst_caps_get_float (caps, "framerate", &fps); gst_caps_get_fourcc_int (caps, "format", &filter->format); filter->to_bpp = 24; to_caps = GST_CAPS_NEW ( "snapshot_conversion", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), - "width", GST_PROPS_INT( filter->width ), - "height", GST_PROPS_INT( filter->height ), + "video/x-raw-rgb", + "width", GST_PROPS_INT( filter->width ), + "height", GST_PROPS_INT( filter->height ), "red_mask", GST_PROPS_INT (0x0000FF), "green_mask", GST_PROPS_INT (0x00FF00), "blue_mask", GST_PROPS_INT (0xFF0000), - "bpp", GST_PROPS_INT( 24 ) + "bpp", GST_PROPS_INT( 24 ), + "framerate", GST_PROPS_FLOAT (fps) ); switch ( filter->format ) @@ -202,10 +203,11 @@ gst_snapshot_sinkconnect (GstPad *pad, GstCaps *caps) case GST_MAKE_FOURCC('I','4','2','0'): from_caps = GST_CAPS_NEW ( "snapshot_from", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT( filter->width ), - "height", GST_PROPS_INT( filter->height ) + "video/x-raw-yuv", + "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + "width", GST_PROPS_INT( filter->width ), + "height", GST_PROPS_INT( filter->height ), + "framerate", GST_PROPS_FLOAT (fps) ); filter->converter = gst_colorspace_yuv2rgb_get_converter ( from_caps, to_caps ); diff --git a/ext/sndfile/gstsf.c b/ext/sndfile/gstsf.c index 2c5245b42..998bf9e73 100644 --- a/ext/sndfile/gstsf.c +++ b/ext/sndfile/gstsf.c @@ -67,13 +67,13 @@ GST_PAD_TEMPLATE_FACTORY (sf_src_factory, GST_PAD_REQUEST, GST_CAPS_NEW ( "sf_src", - "audio/raw", + "audio/x-raw-float", "rate", GST_PROPS_INT_RANGE (1, G_MAXINT), - "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) + "channels", GST_PROPS_INT (1), + "width", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER) ) ); @@ -83,13 +83,13 @@ GST_PAD_TEMPLATE_FACTORY (sf_sink_factory, GST_PAD_REQUEST, GST_CAPS_NEW ( "sf_sink", - "audio/raw", + "audio/x-raw-float", "rate", GST_PROPS_INT_RANGE (1, G_MAXINT), - "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) + "channels", GST_PROPS_INT (1), + "width", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER) ) ); diff --git a/ext/swfdec/gstswfdec.c b/ext/swfdec/gstswfdec.c index 139201970..e56b9da16 100644 --- a/ext/swfdec/gstswfdec.c +++ b/ext/swfdec/gstswfdec.c @@ -43,7 +43,6 @@ enum { enum { ARG_0, - ARG_FRAME_RATE, /* FILL ME */ }; @@ -53,8 +52,7 @@ GST_PAD_TEMPLATE_FACTORY (video_template_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "swfdec_videosrc", - "video/raw", - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')), + "video/x-raw-rgb", "width", GST_PROPS_INT_RANGE (16, 4096), "height", GST_PROPS_INT_RANGE (16, 4096), "bpp", GST_PROPS_INT (24), @@ -62,7 +60,8 @@ GST_PAD_TEMPLATE_FACTORY (video_template_factory, "endianness", GST_PROPS_INT (G_BIG_ENDIAN), "red_mask", GST_PROPS_INT (0xff0000), "green_mask", GST_PROPS_INT (0x00ff00), - "blue_mask", GST_PROPS_INT (0x0000ff) + "blue_mask", GST_PROPS_INT (0x0000ff), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) ) ); @@ -72,9 +71,7 @@ GST_PAD_TEMPLATE_FACTORY (audio_template_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "swfdec_audiosrc", - "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), @@ -156,10 +153,6 @@ gst_swfdec_class_init(GstSwfdecClass *klass) parent_class = g_type_class_ref(GST_TYPE_ELEMENT); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FRAME_RATE, - g_param_spec_float ("frame_rate","frame_rate","frame_rate", - 0.0, 1000.0, 0.0, G_PARAM_READABLE)); - gobject_class->set_property = gst_swfdec_set_property; gobject_class->get_property = gst_swfdec_get_property; gobject_class->dispose = gst_swfdec_dispose; @@ -176,8 +169,7 @@ static GstCaps *gst_swfdec_videosrc_getcaps(GstPad *pad, GstCaps *caps) c = GST_CAPS_NEW ( "swfdec_videosrc", - "video/raw", - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')), + "video/x-raw-rgb", "width", GST_PROPS_INT_RANGE (16, 4096), "height", GST_PROPS_INT_RANGE (16, 4096), "bpp", GST_PROPS_INT (24), @@ -185,7 +177,8 @@ static GstCaps *gst_swfdec_videosrc_getcaps(GstPad *pad, GstCaps *caps) "endianness", GST_PROPS_INT (G_BIG_ENDIAN), "red_mask", GST_PROPS_INT (0xff0000), "green_mask", GST_PROPS_INT (0x00ff00), - "blue_mask", GST_PROPS_INT (0x0000ff) + "blue_mask", GST_PROPS_INT (0x0000ff), + "framerate", GST_PROPS_FLOAT (swfdec->frame_rate) ); if(swfdec->height){ @@ -318,6 +311,8 @@ gst_swfdec_init (GstSwfdec *swfdec) swfdec_decoder_set_colorspace(swfdec->state, SWF_COLORSPACE_RGB888); GST_FLAG_SET (GST_ELEMENT (swfdec), GST_ELEMENT_EVENT_AWARE); + + swfdec->frame_rate = 0.; } static void @@ -626,9 +621,6 @@ gst_swfdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSp swfdec = GST_SWFDEC (object); switch (prop_id) { - case ARG_FRAME_RATE: - g_value_set_float (value, swfdec->frame_rate); - break; default: break; } diff --git a/ext/swfdec/gstswfdec.h b/ext/swfdec/gstswfdec.h index 38f58e888..d3e6355ed 100644 --- a/ext/swfdec/gstswfdec.h +++ b/ext/swfdec/gstswfdec.h @@ -63,7 +63,7 @@ struct _GstSwfdec { double rate; gint64 timestamp; gint64 interval; - gdouble frame_rate; + gfloat frame_rate; /* video state */ gint format; diff --git a/ext/tarkin/gsttarkin.c b/ext/tarkin/gsttarkin.c index fdee893a3..69fee01ae 100644 --- a/ext/tarkin/gsttarkin.c +++ b/ext/tarkin/gsttarkin.c @@ -35,8 +35,8 @@ tarkin_caps_factory (void) return gst_caps_new ( "tarkin_tarkin", - "video/x-ogg", - NULL); + "application/ogg", + NULL); } static GstCaps* @@ -45,8 +45,7 @@ raw_caps_factory (void) return GST_CAPS_NEW ( "tarkin_raw", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), + "video/x-raw-rgb", "bpp", GST_PROPS_INT (24), "depth", GST_PROPS_INT (24), "endianness", GST_PROPS_INT (G_BYTE_ORDER), @@ -54,14 +53,15 @@ raw_caps_factory (void) "green_mask", GST_PROPS_INT (0xff00), "blue_mask", GST_PROPS_INT (0xff), "width", GST_PROPS_INT_RANGE (0, G_MAXINT), - "height", GST_PROPS_INT_RANGE (0, G_MAXINT) + "height", GST_PROPS_INT_RANGE (0, G_MAXINT), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) ); } static GstTypeDefinition tarkindefinition = { "tarkin_video/x-ogg", - "video/x-ogg", + "application/ogg", ".ogg", tarkin_type_find, }; @@ -77,7 +77,7 @@ tarkin_type_find (GstBuffer *buf, gpointer private) if (head != 0x4F676753) return NULL; - return gst_caps_new ("tarkin_type_find", "video/x-ogg", NULL); + return gst_caps_new ("tarkin_type_find", "application/ogg", NULL); } @@ -88,7 +88,7 @@ plugin_init (GModule *module, GstPlugin *plugin) GstTypeFactory *type; GstCaps *raw_caps, *tarkin_caps; - gst_plugin_set_longname (plugin, "The OGG Vorbis Codec"); + gst_plugin_set_longname (plugin, "The OGG Tarkin Codec"); /* create an elementfactory for the tarkinenc element */ enc = gst_element_factory_new ("tarkinenc", GST_TYPE_TARKINENC, diff --git a/ext/tarkin/gsttarkindec.c b/ext/tarkin/gsttarkindec.c index 7d2c42c0f..f77e5c8f7 100644 --- a/ext/tarkin/gsttarkindec.c +++ b/ext/tarkin/gsttarkindec.c @@ -213,8 +213,7 @@ gst_tarkindec_chain (GstPad *pad, GstBuffer *buf) if (gst_pad_try_set_caps (tarkindec->srcpad, GST_CAPS_NEW ( "tarkin_raw", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), + "video/x-raw-rgb", "bpp", GST_PROPS_INT (24), "depth", GST_PROPS_INT (24), "endianness", GST_PROPS_INT (G_BYTE_ORDER), @@ -222,7 +221,8 @@ gst_tarkindec_chain (GstPad *pad, GstBuffer *buf) "green_mask", GST_PROPS_INT (0xff00), "blue_mask", GST_PROPS_INT (0xff), "width", GST_PROPS_INT (layer->width), - "height", GST_PROPS_INT (layer->height) + "height", GST_PROPS_INT (layer->height), + "framerate", GST_PROPS_FLOAT (0.) /* FIXME!!! */ )) <= 0) { gst_element_error (GST_ELEMENT (tarkindec), "could not output format"); diff --git a/ext/xvid/gstxviddec.c b/ext/xvid/gstxviddec.c index cd4ce3f5d..fcde219ba 100644 --- a/ext/xvid/gstxviddec.c +++ b/ext/xvid/gstxviddec.c @@ -44,28 +44,39 @@ GST_PAD_TEMPLATE_FACTORY(sink_template, GST_PAD_SINK, GST_PAD_ALWAYS, GST_CAPS_NEW("xviddec_sink", - "video/xvid", - NULL) + "video/x-xvid", + "width", GST_PROPS_INT_RANGE (0, G_MAXINT), + "height", GST_PROPS_INT_RANGE (0, G_MAXINT), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT)) ) GST_PAD_TEMPLATE_FACTORY(src_template, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW("xviddec_src", - "video/raw", - "format", GST_PROPS_LIST( - GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','Y','U','V')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','Y','U')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) - ), - "width", GST_PROPS_INT_RANGE(0, G_MAXINT), - "height", GST_PROPS_INT_RANGE(0, G_MAXINT), - NULL) + gst_caps_new( + "xviddec_sink", + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_LIST( + GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','Y','U')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) + ) + ) + ), + gst_caps_new( + "xviddec_sink_rgb24_32", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32 + ), + gst_caps_new( + "xviddec_sink_rgb15_16", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16 + ) ) @@ -88,6 +99,7 @@ static void gst_xviddec_chain (GstPad *pad, GstBuffer *buf); static GstPadLinkReturn gst_xviddec_connect (GstPad *pad, GstCaps *vscapslist); +static GstPadLinkReturn gst_xviddec_negotiate (GstXvidDec *xviddec); static GstElementClass *parent_class = NULL; /* static guint gst_xviddec_signals[LAST_SIGNAL] = { 0 }; */ @@ -216,10 +228,12 @@ gst_xviddec_chain (GstPad *pad, xviddec = GST_XVIDDEC(GST_OBJECT_PARENT(pad)); if (!xviddec->handle) { - gst_element_error(GST_ELEMENT(xviddec), - "No format set - aborting"); - gst_buffer_unref(buf); - return; + if (!gst_xviddec_negotiate(xviddec)) { + gst_element_error(GST_ELEMENT(xviddec), + "No format set - aborting"); + gst_buffer_unref(buf); + return; + } } outbuf = gst_buffer_new_and_alloc(xviddec->width * @@ -252,10 +266,9 @@ gst_xviddec_chain (GstPad *pad, static GstPadLinkReturn -gst_xviddec_connect (GstPad *pad, - GstCaps *vscaps) +gst_xviddec_negotiate (GstXvidDec *xviddec) { - GstXvidDec *xviddec; + GstPadLinkReturn ret; GstCaps *caps; struct { guint32 fourcc; @@ -266,7 +279,6 @@ gst_xviddec_connect (GstPad *pad, { GST_MAKE_FOURCC('U','Y','V','Y'), 16, 16, XVID_CSP_UYVY }, { GST_MAKE_FOURCC('Y','V','Y','U'), 16, 16, XVID_CSP_YVYU }, { GST_MAKE_FOURCC('I','4','2','0'), 12, 12, XVID_CSP_I420 }, - { GST_MAKE_FOURCC('I','Y','U','V'), 12, 12, XVID_CSP_I420 }, { GST_MAKE_FOURCC('Y','V','1','2'), 12, 12, XVID_CSP_YV12 }, { GST_MAKE_FOURCC('R','G','B',' '), 32, 32, XVID_CSP_RGB32 }, { GST_MAKE_FOURCC('R','G','B',' '), 24, 24, XVID_CSP_RGB24 }, @@ -276,68 +288,60 @@ gst_xviddec_connect (GstPad *pad, }; gint i; - xviddec = GST_XVIDDEC(gst_pad_get_parent (pad)); - - /* if there's something old around, remove it */ - if (xviddec->handle) { - gst_xviddec_unset(xviddec); - } - - /* we are not going to act on variable caps */ - if (!GST_CAPS_IS_FIXED(vscaps)) - return GST_PAD_LINK_DELAYED; - - /* if we get here, we know the input is xvid. we - * only need to bother with the output colorspace */ - gst_caps_get_int(vscaps, "width", &xviddec->width); - gst_caps_get_int(vscaps, "height", &xviddec->height); - for (i = 0; fmt_list[i].fourcc != 0; i++) { xviddec->csp = fmt_list[i].csp; /* try making a caps to set on the other side */ if (fmt_list[i].fourcc == GST_MAKE_FOURCC('R','G','B',' ')) { guint32 r_mask = 0, b_mask = 0, g_mask = 0; + gint endianness = 0; switch (fmt_list[i].depth) { case 15: + endianness = G_BYTE_ORDER; r_mask = 0xf800; g_mask = 0x07c0; b_mask = 0x003e; break; case 16: + endianness = G_BYTE_ORDER; r_mask = 0xf800; g_mask = 0x07e0; b_mask = 0x001f; break; case 24: - r_mask = 0xff0000; g_mask = 0x00ff00; b_mask = 0x0000ff; + endianness = G_BIG_ENDIAN; + r_mask = R_MASK_24; g_mask = G_MASK_24; b_mask = B_MASK_24; break; case 32: - r_mask = 0xff000000; g_mask = 0x00ff0000; b_mask = 0x0000ff00; + endianness = G_BIG_ENDIAN; + r_mask = R_MASK_32; g_mask = G_MASK_32; b_mask = B_MASK_32; break; } caps = GST_CAPS_NEW("xviddec_src_pad_rgb", - "video/raw", + "video/x-raw-rgb", "width", GST_PROPS_INT(xviddec->width), "height", GST_PROPS_INT(xviddec->height), - "format", GST_PROPS_FOURCC(fmt_list[i].fourcc), "depth", GST_PROPS_INT(fmt_list[i].depth), "bpp", GST_PROPS_INT(fmt_list[i].bpp), - "endianness", GST_PROPS_INT(G_BYTE_ORDER), + "endianness", GST_PROPS_INT(endianness), "red_mask", GST_PROPS_INT(r_mask), "green_mask", GST_PROPS_INT(g_mask), "blue_mask", GST_PROPS_INT(b_mask), + "framerate", GST_PROPS_FLOAT(xviddec->fps), NULL); } else { caps = GST_CAPS_NEW("xviddec_src_pad_yuv", - "video/raw", + "video/x-raw-yuv", "width", GST_PROPS_INT(xviddec->width), "height", GST_PROPS_INT(xviddec->height), "format", GST_PROPS_FOURCC(fmt_list[i].fourcc), + "framerate", GST_PROPS_FLOAT(xviddec->fps), NULL); } - if (gst_pad_try_set_caps(xviddec->srcpad, caps) > 0) { + if ((ret = gst_pad_try_set_caps(xviddec->srcpad, caps)) > 0) { xviddec->csp = fmt_list[i].csp; xviddec->bpp = fmt_list[i].bpp; if (gst_xviddec_setup(xviddec)) return GST_PAD_LINK_OK; + } else if (ret == GST_PAD_LINK_DELAYED) { + return ret; /* don't try further (yet) */ } } @@ -346,6 +350,33 @@ gst_xviddec_connect (GstPad *pad, } +static GstPadLinkReturn +gst_xviddec_connect (GstPad *pad, + GstCaps *vscaps) +{ + GstXvidDec *xviddec; + + xviddec = GST_XVIDDEC(gst_pad_get_parent (pad)); + + /* if there's something old around, remove it */ + if (xviddec->handle) { + gst_xviddec_unset(xviddec); + } + + /* we are not going to act on variable caps */ + if (!GST_CAPS_IS_FIXED(vscaps)) + return GST_PAD_LINK_DELAYED; + + /* if we get here, we know the input is xvid. we + * only need to bother with the output colorspace */ + gst_caps_get_int(vscaps, "width", &xviddec->width); + gst_caps_get_int(vscaps, "height", &xviddec->height); + gst_caps_get_float(vscaps, "framerate", &xviddec->fps); + + return gst_xviddec_negotiate(xviddec); +} + + gboolean gst_xviddec_plugin_init (GModule *module, GstPlugin *plugin) diff --git a/ext/xvid/gstxviddec.h b/ext/xvid/gstxviddec.h index cdee55400..6a08b2be9 100644 --- a/ext/xvid/gstxviddec.h +++ b/ext/xvid/gstxviddec.h @@ -54,6 +54,7 @@ struct _GstXvidDec { /* video (output) settings */ int csp, bpp; int width, height; + float fps; }; struct _GstXvidDecClass { diff --git a/ext/xvid/gstxvidenc.c b/ext/xvid/gstxvidenc.c index 7b3d62dd9..5a4156cea 100644 --- a/ext/xvid/gstxvidenc.c +++ b/ext/xvid/gstxvidenc.c @@ -44,20 +44,29 @@ GST_PAD_TEMPLATE_FACTORY(sink_template, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW("xvidenc_sink", - "video/raw", - "format", GST_PROPS_LIST( - GST_PROPS_FOURCC(GST_MAKE_FOURCC('R','G','B',' ')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','Y','U','V')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','Y','U')), - GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) - ), - "width", GST_PROPS_INT_RANGE(0, G_MAXINT), - "height", GST_PROPS_INT_RANGE(0, G_MAXINT), - NULL) + gst_caps_new( + "xvidenc_sink", + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_LIST( + GST_PROPS_FOURCC(GST_MAKE_FOURCC('I','4','2','0')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','U','Y','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','1','2')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('Y','V','Y','U')), + GST_PROPS_FOURCC(GST_MAKE_FOURCC('U','Y','V','Y')) + ) + ) + ), + gst_caps_new( + "xvidenc_sink_rgb24_32", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32 + ), + gst_caps_new( + "xvidenc_sink_rgb15_16", + "video/x-raw-rgb", + GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16 + ) ) GST_PAD_TEMPLATE_FACTORY(src_template, @@ -65,8 +74,10 @@ GST_PAD_TEMPLATE_FACTORY(src_template, GST_PAD_SRC, GST_PAD_ALWAYS, GST_CAPS_NEW("xvidenc_src", - "video/xvid", - NULL) + "video/x-xvid", + "width", GST_PROPS_INT_RANGE (0, G_MAXINT), + "height", GST_PROPS_INT_RANGE (0, G_MAXINT), + "framerate", GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT)) ) @@ -202,17 +213,14 @@ static gboolean gst_xvidenc_setup (GstXvidEnc *xvidenc) { XVID_ENC_PARAM xenc; - gdouble fps; int ret; - fps = gst_video_frame_rate(GST_PAD_PEER(xvidenc->sinkpad)); - /* set up xvid codec parameters - grab docs from * xvid.org for more info */ memset(&xenc, 0, sizeof(XVID_ENC_PARAM)); xenc.width = xvidenc->width; xenc.height = xvidenc->height; - xenc.fincr = (int)(fps * 1000); + xenc.fincr = (int)(xvidenc->fps * 1000); xenc.fbase = 1000; xenc.rc_bitrate = xvidenc->bitrate; xenc.rc_reaction_delay_factor = -1; @@ -254,13 +262,6 @@ gst_xvidenc_chain (GstPad *pad, xvidenc = GST_XVIDENC(GST_OBJECT_PARENT(pad)); - if (!xvidenc->handle) { - if (!gst_xvidenc_setup(xvidenc)) { - gst_buffer_unref(buf); - return; - } - } - outbuf = gst_buffer_new_and_alloc(xvidenc->buffer_size); GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf); @@ -326,11 +327,17 @@ gst_xvidenc_connect (GstPad *pad, for (caps = vscaps; caps != NULL; caps = caps->next) { int w,h,d; + float fps; guint32 fourcc; gint xvid_cs; + gst_caps_get_int(caps, "width", &w); gst_caps_get_int(caps, "height", &h); - gst_caps_get_fourcc_int(caps, "format", &fourcc); + gst_caps_get_float(caps, "framerate", &fps); + if (gst_caps_has_property(caps, "format")) + gst_caps_get_fourcc_int(caps, "format", &fourcc); + else + fourcc = GST_MAKE_FOURCC('R','G','B',' '); switch (fourcc) { @@ -373,17 +380,32 @@ gst_xvidenc_connect (GstPad *pad, goto trynext; } - /* grmbl, we only know the peer pad *after* - * linking, so we accept here, get the fps on - * the first cycle and set it all up then */ xvidenc->csp = xvid_cs; xvidenc->width = w; xvidenc->height = h; - return gst_pad_try_set_caps(xvidenc->srcpad, - GST_CAPS_NEW("xvidenc_src_caps", - "video/xvid", - "width", GST_PROPS_INT(w), - "height", GST_PROPS_INT(h))); + xvidenc->fps = fps; + + if (gst_xvidenc_setup(xvidenc)) { + GstPadLinkReturn ret; + GstCaps *new_caps; + + new_caps = GST_CAPS_NEW("xvidenc_src_caps", + "video/x-xvid", + "width", GST_PROPS_INT(w), + "height", GST_PROPS_INT(h), + "framerate", GST_PROPS_FLOAT (fps)); + + ret = gst_pad_try_set_caps(xvidenc->srcpad, new_caps); + + if (ret <= 0) { + if (xvidenc->handle) { + xvid_encore(xvidenc->handle, XVID_ENC_DESTROY, NULL, NULL); + xvidenc->handle = NULL; + } + } + + return ret; + } trynext: continue; diff --git a/ext/xvid/gstxvidenc.h b/ext/xvid/gstxvidenc.h index e14b41332..224487dc4 100644 --- a/ext/xvid/gstxvidenc.h +++ b/ext/xvid/gstxvidenc.h @@ -60,6 +60,7 @@ struct _GstXvidEnc { void *handle; int csp; int width, height; + float fps; }; struct _GstXvidEncClass { diff --git a/gst-libs/gst/audio/audio.h b/gst-libs/gst/audio/audio.h index 2b27d0feb..4bf62d493 100644 --- a/gst-libs/gst/audio/audio.h +++ b/gst-libs/gst/audio/audio.h @@ -52,8 +52,6 @@ #define GST_AUDIO_INT_PAD_TEMPLATE_PROPS \ gst_props_new (\ - "format", GST_PROPS_STRING ("int"),\ - "law", GST_PROPS_INT (0),\ "endianness", GST_PROPS_INT (G_BYTE_ORDER),\ "signed", GST_PROPS_LIST (\ GST_PROPS_BOOLEAN (TRUE),\ @@ -70,8 +68,6 @@ #define GST_AUDIO_INT_MONO_PAD_TEMPLATE_PROPS \ gst_props_new (\ - "format", GST_PROPS_STRING ("int"),\ - "law", GST_PROPS_INT (0),\ "endianness", GST_PROPS_INT (G_BYTE_ORDER),\ "signed", GST_PROPS_LIST (\ GST_PROPS_BOOLEAN (TRUE),\ @@ -88,8 +84,8 @@ #define GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS \ gst_props_new (\ - "format", GST_PROPS_STRING ("float"),\ - "layout", GST_PROPS_STRING ("gfloat"),\ + "depth", GST_PROPS_INT (32),\ + "endianness", GST_PROPS_INT (G_BYTE_ORDER),\ "intercept", GST_PROPS_FLOAT (0.0),\ "slope", GST_PROPS_FLOAT (1.0),\ "rate", GST_PROPS_INT_RANGE (GST_AUDIO_MIN_RATE, \ diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index 6eba0d7b5..11e26c96d 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -20,31 +20,36 @@ #include "video.h" -#define NUM_UNITS 1000000000 - /* This is simply a convenience function, nothing more or less */ -gdouble +gfloat gst_video_frame_rate (GstPad *pad) { - GstFormat dest_format = GST_FORMAT_DEFAULT; - gint64 dest_value = 0; - gdouble fps; - - /* do a convert request on the source pad */ - if (!gst_pad_convert(pad, - GST_FORMAT_TIME, GST_SECOND * NUM_UNITS, - &dest_format, &dest_value)) - { - g_warning("gstvideo: pad %s:%s failed to convert time to unit!\n", - GST_ELEMENT_NAME(gst_pad_get_parent (pad)), GST_PAD_NAME(pad)); + gfloat fps = 0.; + GstCaps *caps; + + /* get pad caps */ + caps = GST_PAD_CAPS (pad); + if (caps == NULL) { + g_warning ("gstvideo: failed to get caps of pad %s:%s", + GST_ELEMENT_NAME (gst_pad_get_parent (pad)), + GST_PAD_NAME(pad)); + return 0.; + } + + if (!gst_caps_has_property_typed (caps, "framerate", + GST_PROPS_FLOAT_TYPE)) { + g_warning ("gstvideo: failed to get framerate property of pad %s:%s", + GST_ELEMENT_NAME (gst_pad_get_parent (pad)), + GST_PAD_NAME (pad)); return 0.; } - fps = ((gdouble) dest_value) / NUM_UNITS; + gst_caps_get_float (caps, "framerate", &fps); - GST_DEBUG ("Framerate request on pad %s:%s - %f fps", - GST_ELEMENT_NAME(gst_pad_get_parent (pad)), GST_PAD_NAME(pad), fps); + GST_DEBUG ("Framerate request on pad %s:%s: %f", + GST_ELEMENT_NAME (gst_pad_get_parent (pad)), + GST_PAD_NAME(pad), fps); return fps; } @@ -56,28 +61,37 @@ gst_video_get_size (GstPad *pad, { GstCaps *caps; - g_return_val_if_fail(pad != NULL, FALSE); + g_return_val_if_fail (pad != NULL, FALSE); - caps = GST_PAD_CAPS(pad); - if (!caps) { - g_warning("gstvideo: failed to get caps of pad %s:%s", - GST_ELEMENT_NAME(gst_pad_get_parent (pad)), GST_PAD_NAME(pad)); + caps = GST_PAD_CAPS (pad); + + if (caps == NULL) { + g_warning ("gstvideo: failed to get caps of pad %s:%s", + GST_ELEMENT_NAME (gst_pad_get_parent (pad)), + GST_PAD_NAME(pad)); return FALSE; } - if (!gst_caps_has_property(caps, "width") || - !gst_caps_has_property(caps, "height")) { - g_warning("gstvideo: resulting caps doesn't have width/height properties"); + + if (!gst_caps_has_property_typed (caps, "width", + GST_PROPS_INT_TYPE) || + !gst_caps_has_property_typed (caps, "height", + GST_PROPS_FLOAT_TYPE)) { + g_warning ("gstvideo: failed to get size properties on pad %s:%s", + GST_ELEMENT_NAME (gst_pad_get_parent (pad)), + GST_PAD_NAME(pad)); return FALSE; } if (width) - gst_caps_get_int(caps, "width", width); + gst_caps_get_int (caps, "width", width); if (height) - gst_caps_get_int(caps, "height", height); + gst_caps_get_int (caps, "height", height); GST_DEBUG ("size request on pad %s:%s: %dx%d", - GST_ELEMENT_NAME(gst_pad_get_parent (pad)), GST_PAD_NAME(pad), - width?*width:0, height?*height:0); + GST_ELEMENT_NAME (gst_pad_get_parent (pad)), + GST_PAD_NAME (pad), + width ? *width : -1, + height ? *height : -1); return TRUE; } diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index 802520dac..9ff57f780 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -23,7 +23,155 @@ #include <gst/gst.h> -gdouble gst_video_frame_rate (GstPad *pad); +#if (G_BYTE_ORDER == G_BIG_ENDIAN) + +#define R_MASK_32 0xff000000 +#define G_MASK_32 0x00ff0000 +#define B_MASK_32 0x0000ff00 + +#define R_MASK_24 0xff0000 +#define G_MASK_24 0x00ff00 +#define B_MASK_24 0x0000ff + +#else + +#define R_MASK_32 0x000000ff +#define G_MASK_32 0x0000ff00 +#define B_MASK_32 0x00ff0000 + +#define R_MASK_24 0x0000ff +#define G_MASK_24 0x00ff00 +#define B_MASK_24 0xff0000 + +#endif + +#define R_MASK_16 0xf800 +#define G_MASK_16 0x07e0 +#define B_MASK_16 0x001f + +#define R_MASK_15 0x8c00 +#define G_MASK_15 0x03e0 +#define B_MASK_15 0x001f + +#define SIZE_RANGE GST_PROPS_INT_RANGE (16, 4096) +#define FPS_RANGE GST_PROPS_FLOAT_RANGE (0, G_MAXFLOAT) + +/* properties for pad templates */ +#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24_32 \ + gst_props_new ( \ + "bpp", GST_PROPS_LIST ( \ + GST_PROPS_INT (24), \ + GST_PROPS_INT (32) \ + ), \ + "depth", GST_PROPS_LIST ( \ + GST_PROPS_INT (24), \ + GST_PROPS_INT (32) \ + ), \ + "endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ + "red_mask", GST_PROPS_LIST ( \ + GST_PROPS_INT (R_MASK_32), \ + GST_PROPS_INT (R_MASK_24) \ + ), \ + "green_mask", GST_PROPS_LIST ( \ + GST_PROPS_INT (G_MASK_32), \ + GST_PROPS_INT (G_MASK_24) \ + ), \ + "blue_mask", GST_PROPS_LIST ( \ + GST_PROPS_INT (B_MASK_32), \ + GST_PROPS_INT (B_MASK_24) \ + ), \ + "width", SIZE_RANGE, \ + "height", SIZE_RANGE, \ + "framerate", FPS_RANGE, \ + NULL) + +#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_32 \ + gst_props_new ( \ + "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", SIZE_RANGE, \ + "height", SIZE_RANGE, \ + "framerate", FPS_RANGE, \ + NULL) + +#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_24 \ + gst_props_new ( \ + "bpp", GST_PROPS_INT (24), \ + "depth", GST_PROPS_INT (24), \ + "endianness", GST_PROPS_INT (G_BIG_ENDIAN), \ + "red_mask", GST_PROPS_INT (R_MASK_24), \ + "green_mask", GST_PROPS_INT (G_MASK_24), \ + "blue_mask", GST_PROPS_INT (B_MASK_24), \ + "width", SIZE_RANGE, \ + "height", SIZE_RANGE, \ + "framerate", FPS_RANGE, \ + NULL) + +#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15_16 \ + gst_props_new ( \ + "bpp", GST_PROPS_INT (16), \ + "depth", GST_PROPS_LIST ( \ + GST_PROPS_INT (15), \ + GST_PROPS_INT (16) \ + ), \ + "endianness", GST_PROPS_INT (G_BYTE_ORDER), \ + "red_mask", GST_PROPS_LIST ( \ + GST_PROPS_INT (R_MASK_15), \ + GST_PROPS_INT (R_MASK_16) \ + ), \ + "green_mask", GST_PROPS_LIST ( \ + GST_PROPS_INT (G_MASK_15), \ + GST_PROPS_INT (G_MASK_16) \ + ), \ + "blue_mask", GST_PROPS_LIST ( \ + GST_PROPS_INT (B_MASK_15), \ + GST_PROPS_INT (B_MASK_16) \ + ), \ + "width", SIZE_RANGE, \ + "height", SIZE_RANGE, \ + "framerate", FPS_RANGE, \ + NULL) + +#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_16 \ + gst_props_new ( \ + "bpp", GST_PROPS_INT (16), \ + "depth", GST_PROPS_INT (16), \ + "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", SIZE_RANGE, \ + "height", SIZE_RANGE, \ + "framerate", FPS_RANGE, \ + NULL) + +#define GST_VIDEO_RGB_PAD_TEMPLATE_PROPS_15 \ + gst_props_new ( \ + "bpp", GST_PROPS_INT (15), \ + "depth", GST_PROPS_INT (15), \ + "endianness", GST_PROPS_INT (G_BYTE_ORDER), \ + "red_mask", GST_PROPS_INT (R_MASK_15), \ + "green_mask", GST_PROPS_INT (G_MASK_15), \ + "blue_mask", GST_PROPS_INT (B_MASK_15), \ + "width", SIZE_RANGE, \ + "height", SIZE_RANGE, \ + "framerate", FPS_RANGE, \ + NULL) + +#define GST_VIDEO_YUV_PAD_TEMPLATE_PROPS(fourcc) \ + gst_props_new (\ + "format", fourcc, \ + "width", SIZE_RANGE, \ + "height", SIZE_RANGE, \ + "framerate", FPS_RANGE, \ + NULL) + +/* functions */ +gfloat gst_video_frame_rate (GstPad *pad); gboolean gst_video_get_size (GstPad *pad, gint *width, gint *height); diff --git a/gst/cdxaparse/gstcdxaparse.c b/gst/cdxaparse/gstcdxaparse.c index 08e6f14ce..1c2141b24 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 97cb6fc05..bc86b8932 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 76cc34b13..3a63eb178 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 728b4556d..7f40e3b07 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 0e57a747f..68af7a288 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 0aee85258..f031bb6e0 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 06aa8f531..fcf2f43f8 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 64e104d67..54eb81d3e 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 0f4fac184..b14a701ee 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 bf9e9c902..bd16c3c57 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 01cea4fe9..9270938b8 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 7e18121a3..4073174c2 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 332a259a9..3a17dbe72 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 31cfcddae..5d06738cc 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 a5d8797cd..d97fce175 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 f929a5d90..7d1edc952 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 75856aaca..fca1e9418 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 dcffbf364..eb8a296f8 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 be1877521..4852db935 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 25ef3dfd7..c88428824 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 d174977ec..ec86c99d9 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 b6761427f..bf042e4c1 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 5c8638900..c51d4fbe6 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 42f9bb337..de91f3ca8 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 93694dfc1..73fc783e1 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 53628471b..6f10391be 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 4c7f9c8e3..99122bcc2 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 d84873bd5..9c413f08f 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 2e0af15f8..a42ad7274 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__ */ diff --git a/sys/Makefile.am b/sys/Makefile.am index e7dc93809..074a5bde2 100644 --- a/sys/Makefile.am +++ b/sys/Makefile.am @@ -34,7 +34,7 @@ else VCD_DIR= endif -if USE_XVIDEO +if USE_XFREE XVIDEO_DIR=xvideo else XVIDEO_DIR= diff --git a/sys/cdrom/gstcdplayer.c b/sys/cdrom/gstcdplayer.c index f36d0bb0d..2efeb992f 100644 --- a/sys/cdrom/gstcdplayer.c +++ b/sys/cdrom/gstcdplayer.c @@ -60,9 +60,10 @@ static guint cdplayer_signals[LAST_SIGNAL] = { 0 }; static GstElementDetails cdplayer_details = { "CD Player", "Generic/Bin", + "LGPL", /* ? */ "Play CD audio through the CD Drive", VERSION, - "Charles Schmidt <cbschmid@uiuc.edu>", + "Charles Schmidt <cbschmid@uiuc.edu>\n" "Wim Taymans <wim.taymans@chello.be>", "(C) 2002", }; diff --git a/sys/dxr3/dxr3audiosink.c b/sys/dxr3/dxr3audiosink.c index fe8853c89..35e9d99cf 100644 --- a/sys/dxr3/dxr3audiosink.c +++ b/sys/dxr3/dxr3audiosink.c @@ -75,9 +75,7 @@ GST_PAD_TEMPLATE_FACTORY (dxr3audiosink_pcm_sink_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "dxr3audiosink_pcm_sink", - "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), @@ -98,8 +96,9 @@ GST_PAD_TEMPLATE_FACTORY (dxr3audiosink_ac3_sink_factory, GST_PAD_ALWAYS, GST_CAPS_NEW ( "dxr3audiosink_ac3_sink", - "audio/a52", + "audio/x-ac3", NULL + /* no parameters needed, we don't need a parsed stream */ ) ) @@ -507,7 +506,7 @@ dxr3audiosink_pcm_sinklink (GstPad *pad, GstCaps *caps) } mimetype = gst_caps_get_mime(caps); - if (strcmp (mimetype, "audio/raw") != 0) { + if (strcmp (mimetype, "audio/x-raw-int") != 0) { return GST_PAD_LINK_REFUSED; } diff --git a/sys/dxr3/dxr3spusink.c b/sys/dxr3/dxr3spusink.c index 04648306c..e9142c3c5 100644 --- a/sys/dxr3/dxr3spusink.c +++ b/sys/dxr3/dxr3spusink.c @@ -68,11 +68,7 @@ GST_PAD_TEMPLATE_FACTORY (dxr3spusink_sink_factory, "sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_CAPS_NEW ( - "dxr3spusink_sink", - "video/mpeg", - NULL - ) + NULL ); diff --git a/sys/dxr3/dxr3videosink.c b/sys/dxr3/dxr3videosink.c index 9c4d8d564..5f8f953d1 100644 --- a/sys/dxr3/dxr3videosink.c +++ b/sys/dxr3/dxr3videosink.c @@ -94,6 +94,8 @@ GST_PAD_TEMPLATE_FACTORY (dxr3videosink_sink_factory, GST_PROPS_INT (2) ), "systemstream", GST_PROPS_BOOLEAN (FALSE) + /* width/height/framerate omitted, we don't + * need a parsed stream */ ) ) diff --git a/sys/qcam/gstqcamsrc.c b/sys/qcam/gstqcamsrc.c index b0edc998b..2c730328d 100644 --- a/sys/qcam/gstqcamsrc.c +++ b/sys/qcam/gstqcamsrc.c @@ -29,6 +29,7 @@ /*#define DEBUG_ENABLED */ #include <gstqcamsrc.h> +#include <gst/video/video.h> #include "qcamip.h" @@ -63,12 +64,11 @@ GST_PAD_TEMPLATE_FACTORY (gst_qcamsrc_src_factory, "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_CAPS_NEW ( + gst_caps_new ( "gstqcam_src", - "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT_RANGE (0, 320), - "height", GST_PROPS_INT_RANGE (0, 240) + "video/x-raw-yuv", + GST_VIDEO_YUV_PAD_TEMPLATE_PROPS ( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420"))) ) ) @@ -252,10 +252,11 @@ gst_qcamsrc_get (GstPad *pad) if (!GST_PAD_CAPS (pad)) { gst_pad_try_set_caps (pad, GST_CAPS_NEW ( "qcam_caps", - "video/raw", + "video/x-raw-yuv", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), "width", GST_PROPS_INT (qcamsrc->qcam->width / scale), - "height", GST_PROPS_INT (qcamsrc->qcam->height / scale) + "height", GST_PROPS_INT (qcamsrc->qcam->height / scale), + "framerate", GST_PROPS_FLOAT (10.) /* bla? */ )); } scan = qc_scan (qcamsrc->qcam); diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 7825956be..b7e5daba2 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -244,12 +244,12 @@ gst_v4l2src_close (GstElement *element, } -static gdouble +static gfloat gst_v4l2src_get_fps (GstV4l2Src *v4l2src) { gint norm; struct v4l2_standard *std; - gdouble fps; + gfloat fps; if (!v4l2src->use_fixed_fps && v4l2src->clock != NULL && @@ -323,6 +323,7 @@ static GstCaps * gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, GstPropsEntry *width, GstPropsEntry *height, + GstPropsEntry *fps, gboolean compressed) { GstCaps *caps = NULL; @@ -331,7 +332,7 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, case V4L2_PIX_FMT_MJPEG: /* Motion-JPEG */ case V4L2_PIX_FMT_JPEG: /* JFIF JPEG */ caps = GST_CAPS_NEW("v4l2src_caps", - "video/jpeg", + "video/x-jpeg", NULL); break; case V4L2_PIX_FMT_RGB332: @@ -346,7 +347,6 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, guint depth=0, bpp=0; gint endianness = 0; guint32 r_mask = 0, b_mask = 0, g_mask = 0; - guint32 fcc = GST_MAKE_FOURCC('R','G','B',' '); switch (fourcc) { case V4L2_PIX_FMT_RGB332: @@ -357,30 +357,64 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, case V4L2_PIX_FMT_RGB555: case V4L2_PIX_FMT_RGB555X: bpp = 16; depth = 15; - endianness = (fourcc == V4L2_PIX_FMT_RGB332) ? - G_LITTLE_ENDIAN : G_BIG_ENDIAN; - r_mask = 0x7c00; g_mask = 0x03e0; b_mask = 0x001f; + endianness = G_BYTE_ORDER; + if ((fourcc == V4L2_PIX_FMT_RGB555 && + G_BYTE_ORDER == G_LITTLE_ENDIAN) || + (fourcc == V4L2_PIX_FMT_RGB555X && + G_BYTE_ORDER == G_BIG_ENDIAN)) { + r_mask = 0x7c00; + g_mask = 0x03e0; + b_mask = 0x001f; + } else { + r_mask = 0x007c; + g_mask = 0xe003; + b_mask = 0x1f00; + } break; case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_RGB565X: bpp = depth = 16; - endianness = (fourcc == V4L2_PIX_FMT_RGB565) ? - G_LITTLE_ENDIAN : G_BIG_ENDIAN; - r_mask = 0xf800; g_mask = 0x07e0; b_mask = 0x001f; + endianness = G_BYTE_ORDER; + if ((fourcc == V4L2_PIX_FMT_RGB565 && + G_BYTE_ORDER == G_LITTLE_ENDIAN) || + (fourcc == V4L2_PIX_FMT_RGB565X && + G_BYTE_ORDER == G_BIG_ENDIAN)) { + r_mask = 0xf800; + g_mask = 0x07e0; + b_mask = 0x001f; + } else { + r_mask = 0x00f8; + g_mask = 0xe007; + b_mask = 0x1f00; + } break; case V4L2_PIX_FMT_RGB24: case V4L2_PIX_FMT_BGR24: bpp = depth = 24; - endianness = (fourcc == V4L2_PIX_FMT_BGR24) ? - G_LITTLE_ENDIAN : G_BIG_ENDIAN; - r_mask = 0xff0000; g_mask = 0x00ff00; b_mask = 0x0000ff; + endianness = G_BIG_ENDIAN; + if (fourcc == V4L2_PIX_FMT_RGB24) { + r_mask = 0xff0000; + g_mask = 0x00ff00; + b_mask = 0x0000ff; + } else { + r_mask = 0x0000ff; + g_mask = 0x00ff00; + b_mask = 0xff0000; + } break; case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_BGR32: bpp = depth = 32; - endianness = (fourcc == V4L2_PIX_FMT_BGR32) ? - G_LITTLE_ENDIAN : G_BIG_ENDIAN; - r_mask = 0x00ff0000; g_mask = 0x0000ff00; b_mask = 0x000000ff; + endianness = G_BIG_ENDIAN; + if (fourcc == V4L2_PIX_FMT_RGB32) { + r_mask = 0xff000000; + g_mask = 0x00ff0000; + b_mask = 0x0000ff00; + } else { + r_mask = 0x000000ff; + g_mask = 0x0000ff00; + b_mask = 0x00ff0000; + } break; default: g_assert_not_reached(); @@ -388,8 +422,7 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, } caps = GST_CAPS_NEW("v4l2src_caps", - "video/raw", - "format", GST_PROPS_FOURCC(fcc), + "video/x-raw-rgb", "bpp", GST_PROPS_INT(bpp), "depth", GST_PROPS_INT(depth), "red_mask", GST_PROPS_INT(r_mask), @@ -428,7 +461,7 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, } caps = GST_CAPS_NEW("v4l2src_caps", - "video/raw", + "video/x-raw-yuv", "format", GST_PROPS_FOURCC(fcc), NULL); break; @@ -456,7 +489,7 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, g_free(string_format); } else { caps = GST_CAPS_NEW("v4l2src_caps", - "video/raw", + "video/x-raw-yuv", "format",GST_PROPS_FOURCC(fourcc), NULL); } @@ -467,16 +500,19 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, caps->properties = gst_props_empty_new(); gst_props_add_entry(caps->properties, width); gst_props_add_entry(caps->properties, height); + gst_props_add_entry(caps->properties, fps); return caps; } -#define gst_v4l2src_v4l2fourcc_to_caps_fixed(f, width, height,c) \ +#define gst_v4l2src_v4l2fourcc_to_caps_fixed(f, width, height, fps, c) \ gst_v4l2src_v4l2fourcc_to_caps(f, \ gst_props_entry_new("width", \ GST_PROPS_INT(width)), \ gst_props_entry_new("height", \ GST_PROPS_INT(height)), \ + gst_props_entry_new("framerate", \ + GST_PROPS_FLOAT(fps)), \ c) #define gst_v4l2src_v4l2fourcc_to_caps_range(f, min_w, max_w, min_h, max_h, c) \ @@ -485,6 +521,8 @@ gst_v4l2src_v4l2fourcc_to_caps (guint32 fourcc, GST_PROPS_INT_RANGE(min_w, max_w)), \ gst_props_entry_new("height", \ GST_PROPS_INT_RANGE(min_h, max_h)), \ + gst_props_entry_new("framerate", \ + GST_PROPS_FLOAT_RANGE(0, G_MAXFLOAT)), \ c) static struct v4l2_fmtdesc * @@ -496,9 +534,12 @@ gst_v4l2_caps_to_v4l2fourcc (GstV4l2Src *v4l2src, struct v4l2_fmtdesc *end_fmt = NULL; const gchar *format = gst_caps_get_mime(caps); - if (!strcmp(format, "video/raw")) { - /* non-compressed */ - gst_caps_get_fourcc_int(caps, "format", &fourcc); + if (!strcmp(format, "video/x-raw-yuv") || + !strcmp(format, "video/x-raw-rgb")) { + if (!strcmp(format, "video/x-raw-rgb")) + fourcc = GST_MAKE_FOURCC('R','G','B',' '); + else + gst_caps_get_fourcc_int(caps, "format", &fourcc); switch (fourcc) { case GST_MAKE_FOURCC('I','4','2','0'): @@ -666,6 +707,7 @@ gst_v4l2src_srcconnect (GstPad *pad, lastcaps = gst_v4l2src_v4l2fourcc_to_caps_fixed(format->pixelformat, v4l2src->format.fmt.pix.width, v4l2src->format.fmt.pix.height, + gst_v4l2src_get_fps(v4l2src), format->flags & V4L2_FMT_FLAG_COMPRESSED); ret_val = gst_pad_try_set_caps(v4l2src->srcpad, |