From: Benjamin O. <co...@us...> - 2003-12-17 05:22:46
|
CVS Root: /cvsroot/gstreamer Module: gst-plugins Changes by: company Date: Tue Dec 16 2003 21:22:45 PST Branch: CAPS Log message: port to new caps branch. Includes complete rework of colorspace caps nego. (untested unfortunately) Modified files: ext/ffmpeg : gstffmpegcodecmap.c gstffmpegcodecmap.h gstffmpegcolorspace.c gstffmpegdec.c gstffmpegdemux.c gstffmpegenc.c gstffmpegmux.c Links: http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegcodecmap.c.diff?r1=1.29&r2=1.29.2.1 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegcodecmap.h.diff?r1=1.5&r2=1.5.8.1 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegcolorspace.c.diff?r1=1.5&r2=1.5.4.1 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegdec.c.diff?r1=1.34&r2=1.34.2.1 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegdemux.c.diff?r1=1.15&r2=1.15.4.1 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegenc.c.diff?r1=1.31&r2=1.31.4.1 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegmux.c.diff?r1=1.16&r2=1.16.4.1 ====Begin Diffs==== Index: gstffmpegcodecmap.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegcodecmap.c,v retrieving revision 1.29 retrieving revision 1.29.2.1 diff -u -d -r1.29 -r1.29.2.1 --- gstffmpegcodecmap.c 28 Nov 2003 20:06:18 -0000 1.29 +++ gstffmpegcodecmap.c 17 Dec 2003 05:22:33 -0000 1.29.2.1 @@ -36,39 +36,33 @@ * See below for why we use this. */ -#define GST_FF_VID_CAPS_NEW(name, mimetype, props...) \ - (context != NULL) ? \ - GST_CAPS_NEW (name, \ - mimetype, \ - "width", GST_PROPS_INT (context->width), \ - "height", GST_PROPS_INT (context->height),\ - "framerate", GST_PROPS_FLOAT ( \ - 1.*context->frame_rate/ \ [...1546 lines suppressed...] + } else if (!strcmp (layout, "microsoft")) { + id = CODEC_ID_ADPCM_MS; + } else if (!strcmp (layout, "wav")) { + id = CODEC_ID_ADPCM_IMA_WAV; + } else if (!strcmp (layout, "4xm")) { + id = CODEC_ID_ADPCM_4XM; } if (id != CODEC_ID_NONE) { @@ -1513,8 +1349,8 @@ } if (id != CODEC_ID_NONE) { - char *str = g_strdup_printf("The id=%d belongs to this caps", id); - gst_caps_debug(caps, str); + char *str = gst_caps2_to_string (caps); + GST_DEBUG ("The id=%d belongs to the caps %s", id, str); g_free(str); } Index: gstffmpegcodecmap.h =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegcodecmap.h,v retrieving revision 1.5 retrieving revision 1.5.8.1 diff -u -d -r1.5 -r1.5.8.1 --- gstffmpegcodecmap.h 17 Jun 2003 11:44:11 -0000 1.5 +++ gstffmpegcodecmap.h 17 Dec 2003 05:22:33 -0000 1.5.8.1 @@ -31,7 +31,7 @@ * a certain CodecID for a pad with compressed data. */ -GstCaps * +GstCaps2 * gst_ffmpeg_codecid_to_caps (enum CodecID codec_id, AVCodecContext *context); @@ -39,7 +39,7 @@ * a certain CodecType for a pad with uncompressed data. */ -GstCaps * +GstCaps2 * gst_ffmpeg_codectype_to_caps (enum CodecType codec_type, AVCodecContext *context); @@ -49,7 +49,7 @@ */ enum CodecID -gst_ffmpeg_caps_to_codecid (GstCaps *caps, +gst_ffmpeg_caps_to_codecid (const GstCaps2 *caps, AVCodecContext *context); /* caps_to_codectype () transforms a GstCaps that belongs to @@ -58,7 +58,7 @@ void gst_ffmpeg_caps_to_codectype (enum CodecType type, - GstCaps *caps, + const GstCaps2 *caps, AVCodecContext *context); /* _formatid_to_caps () is meant for muxers/demuxers, it @@ -67,7 +67,7 @@ * caps belonging to that mux-format */ -GstCaps * +GstCaps2 * gst_ffmpeg_formatid_to_caps (const gchar *format_name); #endif /* __GST_FFMPEG_CODECMAP_H__ */ Index: gstffmpegcolorspace.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegcolorspace.c,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -u -d -r1.5 -r1.5.4.1 --- gstffmpegcolorspace.c 16 Nov 2003 22:01:29 -0000 1.5 +++ gstffmpegcolorspace.c 17 Dec 2003 05:22:33 -0000 1.5.4.1 @@ -32,35 +32,38 @@ #include "gstffmpegcodecmap.h" -#define GST_TYPE_FFMPEGCSP \ +GST_DEBUG_CATEGORY_STATIC (debug_ffmpeg_csp); +#define GST_CAT_DEFAULT debug_ffmpeg_csp + +#define GST_TYPE_FFMPEG_CSP \ (gst_ffmpegcsp_get_type()) -#define GST_FFMPEGCSP(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGCSP,GstFFMpegCsp)) -#define GST_FFMPEGCSP_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGCSP,GstFFMpegCsp)) -#define GST_IS_FFMPEGCSP(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGCSP)) -#define GST_IS_FFMPEGCSP_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGCSP)) +#define GST_FFMPEG_CSP(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEG_CSP,GstFFMpegCsp)) +#define GST_FFMPEG_CSP_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEG_CSP,GstFFMpegCsp)) +#define GST_IS_FFMPEG_CSP(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEG_CSP)) +#define GST_IS_FFMPEG_CSP_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEG_CSP)) typedef struct _GstFFMpegCsp GstFFMpegCsp; typedef struct _GstFFMpegCspClass GstFFMpegCspClass; struct _GstFFMpegCsp { - GstElement element; - - GstPad *sinkpad, *srcpad; + GstElement element; - gint width, height; - gfloat fps; - enum PixelFormat - from_pixfmt, - to_pixfmt; - AVFrame *from_frame, - *to_frame; - GstCaps *sinkcaps; + GstPad * sinkpad; + GstPad * srcpad; + gboolean need_caps_nego; - GstBufferPool *pool; + gint width; + gint height; + gdouble fps; + + enum PixelFormat from_pixfmt; + enum PixelFormat to_pixfmt; + AVFrame * from_frame; + AVFrame * to_frame; }; struct _GstFFMpegCspClass { @@ -88,176 +91,91 @@ static GType gst_ffmpegcsp_get_type (void); -static void gst_ffmpegcsp_base_init (GstFFMpegCspClass *klass); -static void gst_ffmpegcsp_class_init (GstFFMpegCspClass *klass); -static void gst_ffmpegcsp_init (GstFFMpegCsp *space); - -static void gst_ffmpegcsp_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gst_ffmpegcsp_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); +static void gst_ffmpegcsp_base_init (gpointer g_class); +static void gst_ffmpegcsp_class_init (gpointer g_class, gpointer class_data); +static void gst_ffmpegcsp_init (GTypeInstance *instance, gpointer g_class); static GstPadLinkReturn - gst_ffmpegcsp_sinkconnect (GstPad *pad, - GstCaps *caps); -static GstPadLinkReturn - gst_ffmpegcsp_srcconnect (GstPad *pad, - GstCaps *caps); + gst_ffmpegcsp_connect (GstPad *pad, + const GstCaps2 *caps); static GstPadLinkReturn - gst_ffmpegcsp_srcconnect_func (GstPad *pad, - GstCaps *caps, - gboolean newcaps); + gst_ffmpegcsp_try_connect (GstPad *pad, + AVCodecContext *ctx, + double fps); -static void gst_ffmpegcsp_chain (GstPad *pad, - GstData *data); +static void gst_ffmpegcsp_chain (GstPad *pad, + GstData *data); static GstElementStateReturn - gst_ffmpegcsp_change_state (GstElement *element); + gst_ffmpegcsp_change_state (GstElement *element); -static GstPadTemplate *srctempl, *sinktempl; static GstElementClass *parent_class = NULL; /*static guint gst_ffmpegcsp_signals[LAST_SIGNAL] = { 0 }; */ -static GstBufferPool * -ffmpegcsp_get_bufferpool (GstPad *pad) -{ - GstFFMpegCsp *space; - - space = GST_FFMPEGCSP (gst_pad_get_parent (pad)); - - if (space->from_pixfmt == space->to_pixfmt && - space->from_pixfmt != PIX_FMT_NB) { - return gst_pad_get_bufferpool (space->srcpad); - } - - return NULL; -} - -static GstCaps * -gst_ffmpegcsp_getcaps (GstPad *pad, - GstCaps *caps) -{ - GstFFMpegCsp *space; - GstCaps *result; - GstCaps *peercaps; - GstCaps *ourcaps; - - space = GST_FFMPEGCSP (gst_pad_get_parent (pad)); - - /* we can do everything our peer can... */ - peercaps = gst_caps_copy (gst_pad_get_allowed_caps (space->srcpad)); - - /* and our own template of course */ - ourcaps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); - - /* merge them together, we prefer the peercaps first */ - result = gst_caps_prepend (ourcaps, peercaps); - - return result; -} - +/* does caps nego on a pad */ static GstPadLinkReturn -gst_ffmpegcsp_srcconnect_func (GstPad *pad, - GstCaps *caps, - gboolean newcaps) +gst_ffmpegcsp_try_connect (GstPad *pad, AVCodecContext *ctx, double fps) { - AVCodecContext *ctx; + gint i, ret; GstFFMpegCsp *space; - GstCaps *peercaps; - GstCaps *ourcaps; + GstCaps2 *caps; + gboolean try_all = (ctx->pix_fmt != PIX_FMT_NB); - space = GST_FFMPEGCSP (gst_pad_get_parent (pad)); + space = GST_FFMPEG_CSP (gst_pad_get_parent (pad)); - /* we cannot operate if we didn't get src caps */ - if (!(ourcaps = space->sinkcaps)) { - if (newcaps) { - gst_pad_recalc_allowed_caps (space->sinkpad); - } + /* loop over all possibilities and select the first one we can convert and + * is accepted by the peer */ + caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, ctx); + for (i = 0; i < gst_caps2_get_n_structures (caps); i++) { + GstStructure *structure = gst_caps2_get_nth_cap (caps, i); + GstCaps2 *setcaps; - return GST_PAD_LINK_DELAYED; - } + if (fps > 0) + gst_structure_set (structure, "framerate", G_TYPE_DOUBLE, fps, NULL); - /* first see if we can do the format natively by filtering the peer caps - * with our incomming caps */ - if ((peercaps = gst_caps_intersect (caps, ourcaps)) != NULL) { - /* see if the peer likes it too, it should as the caps say so.. */ - if (gst_pad_try_set_caps (space->srcpad, peercaps) > 0) { - space->from_pixfmt = space->to_pixfmt = -1; - return GST_PAD_LINK_DONE; + setcaps = gst_caps2_new_full (gst_structure_copy (structure), NULL); + + ret = gst_pad_try_set_caps (pad, setcaps); + gst_caps2_free (setcaps); + if (ret >= 0) { + if (ctx->pix_fmt == PIX_FMT_NB) + gst_ffmpeg_caps_to_codectype (CODEC_TYPE_VIDEO, caps, ctx); + gst_caps2_free (caps); + + return ret; } } - /* then see what the peer has that matches the size */ - peercaps = gst_caps_intersect (caps, - gst_caps_append ( - GST_CAPS_NEW ( - "ffmpegcsp_filter", - "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 ( - "ffmpegcsp_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); - - /* loop over all possibilities and select the first one we can convert and - * is accepted by the peer */ - ctx = avcodec_alloc_context (); - while (peercaps) { - ctx->width = space->width; - ctx->height = space->height; + if (try_all) { ctx->pix_fmt = PIX_FMT_NB; - gst_ffmpeg_caps_to_codectype (CODEC_TYPE_VIDEO, peercaps, ctx); - if (ctx->pix_fmt != PIX_FMT_NB) { - GstCaps *one = gst_caps_copy_1 (peercaps); - if (gst_pad_try_set_caps (space->srcpad, one) > 0) { - space->to_pixfmt = ctx->pix_fmt; - gst_caps_unref (one); - av_free (ctx); - if (space->from_frame) - av_free (space->from_frame); - if (space->to_frame) - av_free (space->to_frame); - space->from_frame = avcodec_alloc_frame (); - space->to_frame = avcodec_alloc_frame (); - return GST_PAD_LINK_DONE; - } - gst_caps_unref (one); - } - peercaps = peercaps->next; + return gst_ffmpegcsp_try_connect (pad, ctx, fps); + } else { + return GST_PAD_LINK_REFUSED; } - av_free (ctx); - - /* we disable ourself here */ - space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB; - - return GST_PAD_LINK_REFUSED; } static GstPadLinkReturn -gst_ffmpegcsp_sinkconnect (GstPad *pad, - GstCaps *caps) +gst_ffmpegcsp_connect (GstPad *pad, const GstCaps2 *caps) { AVCodecContext *ctx; GstFFMpegCsp *space; - GstPad *peer; + gdouble fps; + enum PixelFormat pixfmt; + GstPad *other; + enum PixelFormat *format, *other_format; - space = GST_FFMPEGCSP (gst_pad_get_parent (pad)); + space = GST_FFMPEG_CSP (gst_pad_get_parent (pad)); - if (!GST_CAPS_IS_FIXED (caps)) { - return GST_PAD_LINK_DELAYED; + if (space->sinkpad == pad) { + other = space->srcpad; + format = &space->from_pixfmt; + other_format = &space->to_pixfmt; + } else if (space->srcpad == pad) { + other = space->sinkpad; + format = &space->to_pixfmt; + other_format = &space->from_pixfmt; + } else { + g_assert_not_reached (); } - ctx = avcodec_alloc_context (); ctx->width = 0; ctx->height = 0; @@ -265,42 +183,40 @@ gst_ffmpeg_caps_to_codectype (CODEC_TYPE_VIDEO, caps, ctx); if (!ctx->width || !ctx->height || ctx->pix_fmt == PIX_FMT_NB) { + av_free (ctx); return GST_PAD_LINK_REFUSED; } - gst_caps_get_float (caps, "framerate", &space->fps); + if (!gst_structure_get_double (gst_caps2_get_nth_cap (caps, 0), + "framerate", &fps)) + fps = 0; + + pixfmt = ctx->pix_fmt; + if (*other_format == PIX_FMT_NB || + space->width != ctx->width || + space->height != ctx->height || + space->fps != fps) { + GST_DEBUG_OBJECT (space, "Need caps nego on pad %s for size %dx%d", + GST_PAD_NAME (other), ctx->width, ctx->height); + /* ctx->pix_fmt is set to preferred format */ + if (gst_ffmpegcsp_try_connect (space->sinkpad, ctx, fps) <= 0) { + av_free (ctx); + return GST_PAD_LINK_REFUSED; + } + *other_format = ctx->pix_fmt; + } space->width = ctx->width; space->height = ctx->height; - space->from_pixfmt = ctx->pix_fmt; + space->fps = fps; + *format = pixfmt; av_free (ctx); - GST_INFO ( "size: %dx%d", space->width, space->height); - - space->sinkcaps = caps; - - if ((peer = gst_pad_get_peer (pad)) != NULL) { - GstPadLinkReturn ret; - ret = gst_ffmpegcsp_srcconnect_func (pad, - gst_pad_get_allowed_caps (space->srcpad), - FALSE); - if (ret <= 0) { - space->sinkcaps = NULL; - return ret; - } - - return GST_PAD_LINK_DONE; - } + GST_INFO_OBJECT (space, "new size: %dx%d (fps: %g)", + space->width, space->height, space->fps); return GST_PAD_LINK_OK; } -static GstPadLinkReturn -gst_ffmpegcsp_srcconnect (GstPad *pad, - GstCaps *caps) -{ - return gst_ffmpegcsp_srcconnect_func (pad, caps, TRUE); -} - static GType gst_ffmpegcsp_get_type (void) { @@ -309,66 +225,79 @@ if (!ffmpegcsp_type) { static const GTypeInfo ffmpegcsp_info = { sizeof (GstFFMpegCspClass), - (GBaseInitFunc) gst_ffmpegcsp_base_init, + gst_ffmpegcsp_base_init, NULL, - (GClassInitFunc) gst_ffmpegcsp_class_init, + gst_ffmpegcsp_class_init, NULL, NULL, sizeof (GstFFMpegCsp), 0, - (GInstanceInitFunc) gst_ffmpegcsp_init, + gst_ffmpegcsp_init, }; ffmpegcsp_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFFMpegColorspace", &ffmpegcsp_info, 0); + + GST_DEBUG_CATEGORY_INIT (debug_ffmpeg_csp, "ffcolorspace", 0, "FFMpeg colorspace converter"); } return ffmpegcsp_type; } static void -gst_ffmpegcsp_base_init (GstFFMpegCspClass *klass) +gst_ffmpegcsp_base_init (gpointer g_class) { - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstCaps2 *caps, *capscopy; + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); + + /* template caps */ + caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, NULL); + capscopy = gst_caps2_copy (caps); + + /* build templates */ + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + caps)); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + capscopy)); - gst_element_class_add_pad_template (element_class, srctempl); - gst_element_class_add_pad_template (element_class, sinktempl); gst_element_class_set_details (element_class, &ffmpegcsp_details); } static void -gst_ffmpegcsp_class_init (GstFFMpegCspClass *klass) +gst_ffmpegcsp_class_init (gpointer g_class, gpointer class_data) { - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass*) klass; - gstelement_class = (GstElementClass*) klass; - - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gobject_class->set_property = gst_ffmpegcsp_set_property; - gobject_class->get_property = gst_ffmpegcsp_get_property; + parent_class = g_type_class_peek_parent (g_class); gstelement_class->change_state = gst_ffmpegcsp_change_state; } static void -gst_ffmpegcsp_init (GstFFMpegCsp *space) +gst_ffmpegcsp_init (GTypeInstance *instance, gpointer g_class) { - space->sinkpad = gst_pad_new_from_template (sinktempl, "sink"); - gst_pad_set_link_function (space->sinkpad, gst_ffmpegcsp_sinkconnect); - gst_pad_set_getcaps_function (space->sinkpad, gst_ffmpegcsp_getcaps); - gst_pad_set_bufferpool_function (space->sinkpad, ffmpegcsp_get_bufferpool); + GstFFMpegCsp *space = GST_FFMPEG_CSP (instance); + + space->sinkpad = gst_pad_new_from_template ( + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (space), "sink"), + "sink"); + gst_pad_set_link_function (space->sinkpad, gst_ffmpegcsp_connect); gst_pad_set_chain_function (space->sinkpad,gst_ffmpegcsp_chain); gst_element_add_pad (GST_ELEMENT(space), space->sinkpad); - space->srcpad = gst_pad_new_from_template (srctempl, "src"); + space->srcpad = gst_pad_new_from_template ( + gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (space), "src"), + "src"); gst_element_add_pad (GST_ELEMENT (space), space->srcpad); - gst_pad_set_link_function (space->srcpad, gst_ffmpegcsp_srcconnect); + gst_pad_set_link_function (space->srcpad, gst_ffmpegcsp_connect); - space->pool = NULL; space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB; space->from_frame = space->to_frame = NULL; } @@ -377,18 +306,18 @@ gst_ffmpegcsp_chain (GstPad *pad, GstData *data) { - GstBuffer *inbuf = GST_BUFFER (data); GstFFMpegCsp *space; + GstBuffer *inbuf = GST_BUFFER (data); GstBuffer *outbuf = NULL; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (inbuf != NULL); - space = GST_FFMPEGCSP (gst_pad_get_parent (pad)); + space = GST_FFMPEG_CSP (gst_pad_get_parent (pad)); g_return_if_fail (space != NULL); - g_return_if_fail (GST_IS_FFMPEGCSP (space)); + g_return_if_fail (GST_IS_FFMPEG_CSP (space)); if (space->from_pixfmt == PIX_FMT_NB || space->to_pixfmt == PIX_FMT_NB) { @@ -399,16 +328,11 @@ if (space->from_pixfmt == space->to_pixfmt) { outbuf = inbuf; } else { - if (space->pool) { - outbuf = gst_buffer_new_from_pool (space->pool, 0, 0); - } - - if (!outbuf) { - guint size = avpicture_get_size (space->to_pixfmt, - space->width, - space->height); - outbuf = gst_buffer_new_and_alloc (size); - } + guint size = avpicture_get_size (space->to_pixfmt, + space->width, + space->height); + /* use bufferpools here */ + outbuf = gst_buffer_new_and_alloc (size); /* convert */ avpicture_fill ((AVPicture *) space->from_frame, GST_BUFFER_DATA (inbuf), @@ -419,8 +343,7 @@ (AVPicture *) space->from_frame, space->from_pixfmt, space->width, space->height); - GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf); - GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf); + gst_buffer_stamp (outbuf, inbuf); gst_buffer_unref (inbuf); } @@ -433,14 +356,12 @@ { GstFFMpegCsp *space; - space = GST_FFMPEGCSP (element); + space = GST_FFMPEG_CSP (element); switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_PAUSED_TO_PLAYING: - space->pool = gst_pad_get_bufferpool (space->srcpad); + case GST_STATE_READY_TO_PAUSED: + space->need_caps_nego = TRUE; break; - case GST_STATE_PLAYING_TO_PAUSED: - space->pool = NULL; case GST_STATE_PAUSED_TO_READY: if (space->from_frame) av_free (space->from_frame); @@ -457,62 +378,9 @@ return GST_STATE_SUCCESS; } -static void -gst_ffmpegcsp_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GstFFMpegCsp *space; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_FFMPEGCSP (object)); - space = GST_FFMPEGCSP (object); - - switch (prop_id) { - default: - break; - } -} - -static void -gst_ffmpegcsp_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GstFFMpegCsp *space; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_FFMPEGCSP (object)); - space = GST_FFMPEGCSP (object); - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - gboolean gst_ffmpegcsp_register (GstPlugin *plugin) { - GstCaps *caps; - - /* template caps */ - caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, NULL); - - /* build templates */ - srctempl = gst_pad_template_new ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - caps, NULL); - gst_caps_ref (caps); /* FIXME: pad_template_new refs the caps, doesn't it? */ - sinktempl = gst_pad_template_new ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - caps, NULL); - return gst_element_register (plugin, "ffcolorspace", - GST_RANK_NONE, GST_TYPE_FFMPEGCSP); + GST_RANK_NONE, GST_TYPE_FFMPEG_CSP); } Index: gstffmpegdec.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegdec.c,v retrieving revision 1.34 retrieving revision 1.34.2.1 diff -u -d -r1.34 -r1.34.2.1 --- gstffmpegdec.c 25 Nov 2003 02:18:12 -0000 1.34 +++ gstffmpegdec.c 17 Dec 2003 05:22:33 -0000 1.34.2.1 @@ -59,7 +59,7 @@ struct _GstFFMpegDecClassParams { AVCodec *in_plugin; - GstCaps *srccaps, *sinkcaps; + GstCaps2 *srccaps, *sinkcaps; }; #define GST_TYPE_FFMPEGDEC \ @@ -92,7 +92,7 @@ static void gst_ffmpegdec_dispose (GObject *object); static GstPadLinkReturn gst_ffmpegdec_connect (GstPad *pad, - GstCaps *caps); + const GstCaps2 *caps); static void gst_ffmpegdec_chain (GstPad *pad, GstData *data); @@ -141,9 +141,9 @@ /* pad templates */ sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, - GST_PAD_ALWAYS, params->sinkcaps, NULL); + GST_PAD_ALWAYS, params->sinkcaps); srctempl = gst_pad_template_new ("src", GST_PAD_SRC, - GST_PAD_ALWAYS, params->srccaps, NULL); + GST_PAD_ALWAYS, params->srccaps); gst_element_class_add_pad_template (element_class, srctempl); gst_element_class_add_pad_template (element_class, sinktempl); @@ -206,15 +206,11 @@ static GstPadLinkReturn gst_ffmpegdec_connect (GstPad *pad, - GstCaps *caps) + const GstCaps2 *caps) { GstFFMpegDec *ffmpegdec = (GstFFMpegDec *)(gst_pad_get_parent (pad)); GstFFMpegDecClass *oclass = (GstFFMpegDecClass*)(G_OBJECT_GET_CLASS (ffmpegdec)); - /* we want fixed caps */ - if (!GST_CAPS_IS_FIXED (caps)) - return GST_PAD_LINK_DELAYED; - /* close old session */ if (ffmpegdec->opened) { avcodec_close (ffmpegdec->context); @@ -407,7 +403,7 @@ if (have_data) { if (!GST_PAD_CAPS (ffmpegdec->srcpad)) { - GstCaps *caps; + GstCaps2 *caps; caps = gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type, ffmpegdec->context); if (caps == NULL || @@ -475,7 +471,7 @@ while (in_plugin) { GstFFMpegDecClassParams *params; - GstCaps *srccaps, *sinkcaps; + GstCaps2 *srccaps, *sinkcaps; gchar *type_name; /* no quasi-codecs, please */ Index: gstffmpegdemux.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegdemux.c,v retrieving revision 1.15 retrieving revision 1.15.4.1 diff -u -d -r1.15 -r1.15.4.1 --- gstffmpegdemux.c 2 Nov 2003 19:07:41 -0000 1.15 +++ gstffmpegdemux.c 17 Dec 2003 05:22:33 -0000 1.15.4.1 @@ -51,7 +51,7 @@ typedef struct _GstFFMpegDemuxClassParams { AVInputFormat *in_plugin; - GstCaps *sinkcaps, *videosrccaps, *audiosrccaps; + GstCaps2 *sinkcaps, *videosrccaps, *audiosrccaps; } GstFFMpegDemuxClassParams; typedef struct _GstFFMpegDemuxClass GstFFMpegDemuxClass; @@ -133,15 +133,15 @@ sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - params->sinkcaps, NULL); + params->sinkcaps); videosrctempl = gst_pad_template_new ("video_%02d", GST_PAD_SRC, GST_PAD_SOMETIMES, - params->videosrccaps, NULL); + params->videosrccaps); audiosrctempl = gst_pad_template_new ("audio_%02d", GST_PAD_SRC, GST_PAD_SOMETIMES, - params->audiosrccaps, NULL); + params->audiosrccaps); gst_element_class_add_pad_template (element_class, videosrctempl); gst_element_class_add_pad_template (element_class, audiosrctempl); @@ -217,12 +217,8 @@ res = in_plugin->read_probe (&probe_data); res = res * GST_TYPE_FIND_MAXIMUM / AVPROBE_SCORE_MAX; - if (res > 0) { - GstCaps *caps = params->sinkcaps; - /* make sure we still hold a refcount to this caps */ - gst_caps_ref (caps); - gst_type_find_suggest (tf, res, caps); - } + if (res > 0) + gst_type_find_suggest (tf, res, params->sinkcaps); } } @@ -291,7 +287,7 @@ /* create the pad/stream if we didn't do so already */ if (st->codec_info_state == 0) { GstPadTemplate *templ = NULL; - GstCaps *caps; + GstCaps2 *caps; gchar *padname; gint num; @@ -386,6 +382,11 @@ gboolean gst_ffmpegdemux_register (GstPlugin *plugin) { + GType type; + AVInputFormat *in_plugin; + GstFFMpegDemuxClassParams *params; + AVCodec *in_codec; + gchar **extensions; GTypeInfo typeinfo = { sizeof(GstFFMpegDemuxClass), (GBaseInitFunc)gst_ffmpegdemux_base_init, @@ -397,11 +398,7 @@ 0, (GInstanceInitFunc)gst_ffmpegdemux_init, }; - GType type; - AVInputFormat *in_plugin; - GstFFMpegDemuxClassParams *params; - AVCodec *in_codec; - gchar **extensions; + GstCaps2 *any_caps = gst_caps2_new_any (); in_plugin = first_iformat; @@ -410,7 +407,7 @@ while (in_plugin) { gchar *type_name, *typefind_name; gchar *p; - GstCaps *sinkcaps, *audiosrccaps, *videosrccaps; + GstCaps2 *sinkcaps, *audiosrccaps, *videosrccaps; /* Try to find the caps that belongs here */ sinkcaps = gst_ffmpeg_formatid_to_caps (in_plugin->name); @@ -424,19 +421,19 @@ videosrccaps = NULL; for (in_codec = first_avcodec; in_codec != NULL; in_codec = in_codec->next) { - GstCaps *temp = gst_ffmpeg_codecid_to_caps (in_codec->id, NULL); + GstCaps2 *temp = gst_ffmpeg_codecid_to_caps (in_codec->id, NULL); if (!temp) { continue; } switch (in_codec->type) { case CODEC_TYPE_VIDEO: - videosrccaps = gst_caps_append (videosrccaps, temp); + gst_caps2_append (videosrccaps, temp); break; case CODEC_TYPE_AUDIO: - audiosrccaps = gst_caps_append (audiosrccaps, temp); + gst_caps2_append (audiosrccaps, temp); break; default: - gst_caps_unref (temp); + gst_caps2_free (temp); break; } } @@ -480,13 +477,14 @@ if (!gst_element_register (plugin, type_name, GST_RANK_MARGINAL, type) || !gst_type_find_register (plugin, typefind_name, GST_RANK_MARGINAL, gst_ffmpegdemux_type_find, - extensions, GST_CAPS_ANY, params)) + extensions, any_caps, params)) return FALSE; g_strfreev (extensions); next: in_plugin = in_plugin->next; } + gst_caps2_free (any_caps); g_hash_table_remove (global_plugins, GINT_TO_POINTER (0)); return TRUE; Index: gstffmpegenc.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegenc.c,v retrieving revision 1.31 retrieving revision 1.31.4.1 diff -u -d -r1.31 -r1.31.4.1 --- gstffmpegenc.c 16 Nov 2003 22:01:30 -0000 1.31 +++ gstffmpegenc.c 17 Dec 2003 05:22:33 -0000 1.31.4.1 @@ -64,7 +64,7 @@ typedef struct { AVCodec *in_plugin; - GstCaps *srccaps, *sinkcaps; + GstCaps2 *srccaps, *sinkcaps; } GstFFMpegEncClassParams; #define GST_TYPE_FFMPEGENC \ @@ -123,7 +123,7 @@ static void gst_ffmpegenc_dispose (GObject *object); static GstPadLinkReturn - gst_ffmpegenc_connect (GstPad *pad, GstCaps *caps); + gst_ffmpegenc_connect (GstPad *pad, const GstCaps2 *caps); static void gst_ffmpegenc_chain_video (GstPad *pad, GstData *_data); static void gst_ffmpegenc_chain_audio (GstPad *pad, GstData *_data); @@ -175,9 +175,9 @@ /* pad templates */ sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, - GST_PAD_ALWAYS, params->sinkcaps, NULL); + GST_PAD_ALWAYS, params->sinkcaps); srctempl = gst_pad_template_new ("src", GST_PAD_SRC, - GST_PAD_ALWAYS, params->srccaps, NULL); + GST_PAD_ALWAYS, params->srccaps); gst_element_class_add_pad_template (element_class, srctempl); gst_element_class_add_pad_template (element_class, sinktempl); @@ -282,15 +282,13 @@ static GstPadLinkReturn gst_ffmpegenc_connect (GstPad *pad, - GstCaps *caps) + const GstCaps2 *caps) { - GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) gst_pad_get_parent (pad); - GstFFMpegEncClass *oclass = (GstFFMpegEncClass*)(G_OBJECT_GET_CLASS(ffmpegenc)); - GstCaps *ret_caps; + GstCaps2 *other_caps; GstPadLinkReturn ret; - - if (!GST_CAPS_IS_FIXED (caps)) - return GST_PAD_LINK_DELAYED; + enum PixelFormat pix_fmt; + GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) gst_pad_get_parent (pad); + GstFFMpegEncClass *oclass = (GstFFMpegEncClass *) G_OBJECT_GET_CLASS(ffmpegenc); /* close old session */ if (ffmpegenc->opened) { @@ -315,47 +313,37 @@ /* no edges */ ffmpegenc->context->flags |= CODEC_FLAG_EMU_EDGE; - for (ret_caps = caps; ret_caps != NULL; ret_caps = ret_caps->next) { - enum PixelFormat pix_fmt; - - /* fetch pix_fmt and so on */ - gst_ffmpeg_caps_to_codectype (oclass->in_plugin->type, - caps, ffmpegenc->context); - - pix_fmt = ffmpegenc->context->pix_fmt; - - /* open codec */ - if (avcodec_open (ffmpegenc->context, oclass->in_plugin) < 0) { - GST_DEBUG ("ffenc_%s: Failed to open FFMPEG codec", - oclass->in_plugin->name); - continue; - } + /* fetch pix_fmt and so on */ + gst_ffmpeg_caps_to_codectype (oclass->in_plugin->type, + caps, ffmpegenc->context); - /* is the colourspace correct? */ - if (pix_fmt != ffmpegenc->context->pix_fmt) { - avcodec_close (ffmpegenc->context); - GST_DEBUG ("ffenc_%s: AV wants different colourspace (%d given, %d wanted)", - oclass->in_plugin->name, pix_fmt, ffmpegenc->context->pix_fmt); - continue; - } + pix_fmt = ffmpegenc->context->pix_fmt; - break; + /* open codec */ + if (avcodec_open (ffmpegenc->context, oclass->in_plugin) < 0) { + GST_DEBUG ("ffenc_%s: Failed to open FFMPEG codec", + oclass->in_plugin->name); + return GST_PAD_LINK_REFUSED; } - if (ret_caps == NULL) { + /* is the colourspace correct? */ + if (pix_fmt != ffmpegenc->context->pix_fmt) { + avcodec_close (ffmpegenc->context); + GST_DEBUG ("ffenc_%s: AV wants different colourspace (%d given, %d wanted)", + oclass->in_plugin->name, pix_fmt, ffmpegenc->context->pix_fmt); return GST_PAD_LINK_REFUSED; } /* try to set this caps on the other side */ - ret_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id, + other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id, ffmpegenc->context); - if (!ret_caps) { + if (!other_caps) { avcodec_close (ffmpegenc->context); GST_DEBUG ("Unsupported codec - no caps found"); return GST_PAD_LINK_REFUSED; } - if ((ret = gst_pad_try_set_caps (ffmpegenc->srcpad, ret_caps)) <= 0) { + if ((ret = gst_pad_try_set_caps (ffmpegenc->srcpad, other_caps)) <= 0) { avcodec_close (ffmpegenc->context); GST_DEBUG ("Failed to set caps on next element for ffmpeg encoder (%s)", oclass->in_plugin->name); @@ -606,7 +594,7 @@ while (in_plugin) { gchar *type_name; - GstCaps *srccaps, *sinkcaps; + GstCaps2 *srccaps, *sinkcaps; GstFFMpegEncClassParams *params; /* no quasi codecs, please */ Index: gstffmpegmux.c =================================================================== RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegmux.c,v retrieving revision 1.16 retrieving revision 1.16.4.1 diff -u -d -r1.16 -r1.16.4.1 --- gstffmpegmux.c 2 Nov 2003 19:07:41 -0000 1.16 +++ gstffmpegmux.c 17 Dec 2003 05:22:33 -0000 1.16.4.1 @@ -51,7 +51,7 @@ typedef struct _GstFFMpegMuxClassParams { AVOutputFormat *in_plugin; - GstCaps *srccaps, *videosinkcaps, *audiosinkcaps; + GstCaps2 *srccaps, *videosinkcaps, *audiosinkcaps; } GstFFMpegMuxClassParams; typedef struct _GstFFMpegMuxClass GstFFMpegMuxClass; @@ -96,7 +96,7 @@ static GstPadLinkReturn gst_ffmpegmux_connect (GstPad *pad, - GstCaps *caps); + const GstCaps2 *caps); static GstPad * gst_ffmpegmux_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *name); @@ -138,15 +138,15 @@ /* pad templates */ srctempl = gst_pad_template_new ("sink", GST_PAD_SRC, GST_PAD_ALWAYS, - params->srccaps, NULL); + params->srccaps); audiosinktempl = gst_pad_template_new ("audio_%d", GST_PAD_SINK, GST_PAD_REQUEST, - params->audiosinkcaps, NULL); + params->audiosinkcaps); videosinktempl = gst_pad_template_new ("video_%d", GST_PAD_SINK, GST_PAD_REQUEST, - params->videosinkcaps, NULL); + params->videosinkcaps); gst_element_class_add_pad_template (element_class, srctempl); gst_element_class_add_pad_template (element_class, videosinktempl); @@ -272,7 +272,7 @@ static GstPadLinkReturn gst_ffmpegmux_connect (GstPad *pad, - GstCaps *caps) + const GstCaps2 *caps) { GstFFMpegMux *ffmpegmux = (GstFFMpegMux *)(gst_pad_get_parent (pad)); gint i; @@ -281,9 +281,6 @@ g_return_val_if_fail (ffmpegmux->opened == FALSE, GST_PAD_LINK_REFUSED); - if (!GST_CAPS_IS_FIXED (caps)) - return GST_PAD_LINK_DELAYED; - for (i = 0; i < ffmpegmux->context->nb_streams; i++) { if (pad == ffmpegmux->sinkpads[i]) { break; @@ -297,12 +294,10 @@ /* for the format-specific guesses, we'll go to * our famous codec mapper */ - for ( ; caps != NULL; caps = caps->next) { - if (gst_ffmpeg_caps_to_codecid (caps, - &st->codec) != CODEC_ID_NONE) { - ffmpegmux->eos[i] = FALSE; - return GST_PAD_LINK_OK; - } + if (gst_ffmpeg_caps_to_codecid (caps, + &st->codec) != CODEC_ID_NONE) { + ffmpegmux->eos[i] = FALSE; + return GST_PAD_LINK_OK; } return GST_PAD_LINK_REFUSED; @@ -463,7 +458,7 @@ while (in_plugin) { gchar *type_name; gchar *p; - GstCaps *srccaps, *audiosinkcaps, *videosinkcaps; + GstCaps2 *srccaps, *audiosinkcaps, *videosinkcaps; /* Try to find the caps that belongs here */ srccaps = gst_ffmpeg_formatid_to_caps (in_plugin->name); @@ -477,19 +472,19 @@ videosinkcaps = NULL; for (in_codec = first_avcodec; in_codec != NULL; in_codec = in_codec->next) { - GstCaps *temp = gst_ffmpeg_codecid_to_caps (in_codec->id, NULL); + GstCaps2 *temp = gst_ffmpeg_codecid_to_caps (in_codec->id, NULL); if (!temp) { continue; } switch (in_codec->type) { case CODEC_TYPE_VIDEO: - videosinkcaps = gst_caps_append (videosinkcaps, temp); + gst_caps2_append (videosinkcaps, temp); break; case CODEC_TYPE_AUDIO: - audiosinkcaps = gst_caps_append (audiosinkcaps, temp); + gst_caps2_append (audiosinkcaps, temp); break; default: - gst_caps_unref (temp); + gst_caps2_free (temp); break; } } |