From 4ec81ff7fa97e6747ecbb195d12596f58a241917 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Fri, 20 Jan 2006 14:17:16 +0000 Subject: [PATCH] ext/ffmpeg/: ffdeinterlace port to 0.10. Original commit message from CVS: reviewed by: Edward Hervey * ext/ffmpeg/Makefile.am: * ext/ffmpeg/gstffmpeg.c: (plugin_init): * ext/ffmpeg/gstffmpegdeinterlace.c: (gst_ffmpegdeinterlace_base_init), (gst_ffmpegdeinterlace_class_init), (gst_ffmpegdeinterlace_sink_setcaps), (gst_ffmpegdeinterlace_init), (gst_ffmpegdeinterlace_chain), (gst_ffmpegdeinterlace_register): ffdeinterlace port to 0.10. Could be made a subclass of GstBaseTransform later on... --- ChangeLog | 14 ++ ext/ffmpeg/Makefile.am | 6 +- ext/ffmpeg/gstffmpeg.c | 2 +- ext/ffmpeg/gstffmpegdeinterlace.c | 351 ++++++++++---------------------------- 4 files changed, 109 insertions(+), 264 deletions(-) diff --git a/ChangeLog b/ChangeLog index 21847a1..a9fd532 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-01-20 Martin Zlomek from Itonis (michael.benes@xeris.cz) + + reviewed by: Edward Hervey + + * ext/ffmpeg/Makefile.am: + * ext/ffmpeg/gstffmpeg.c: (plugin_init): + * ext/ffmpeg/gstffmpegdeinterlace.c: + (gst_ffmpegdeinterlace_base_init), + (gst_ffmpegdeinterlace_class_init), + (gst_ffmpegdeinterlace_sink_setcaps), (gst_ffmpegdeinterlace_init), + (gst_ffmpegdeinterlace_chain), (gst_ffmpegdeinterlace_register): + ffdeinterlace port to 0.10. + Could be made a subclass of GstBaseTransform later on... + 2006-01-20 Michal Benes Reviewed by : Edward Hervey diff --git a/ext/ffmpeg/Makefile.am b/ext/ffmpeg/Makefile.am index 3490e35..a5b53aa 100644 --- a/ext/ffmpeg/Makefile.am +++ b/ext/ffmpeg/Makefile.am @@ -3,12 +3,12 @@ plugin_LTLIBRARIES = libgstffmpeg.la libgstffmpeg_la_SOURCES = gstffmpeg.c \ gstffmpegcodecmap.c \ gstffmpegdec.c \ - gstffmpegenc.c + gstffmpegenc.c \ + gstffmpegdeinterlace.c # gstffmpegdemux.c \ # gstffmpegmux.c \ # gstffmpegprotocol.c \ -# gstffmpegscale.c \ -# gstffmpegdeinterlace.c +# gstffmpegscale.c libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \ -I $(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \ diff --git a/ext/ffmpeg/gstffmpeg.c b/ext/ffmpeg/gstffmpeg.c index bb2ec7c..66bfea8 100644 --- a/ext/ffmpeg/gstffmpeg.c +++ b/ext/ffmpeg/gstffmpeg.c @@ -109,12 +109,12 @@ plugin_init (GstPlugin * plugin) gst_ffmpegenc_register (plugin); gst_ffmpegdec_register (plugin); + gst_ffmpegdeinterlace_register (plugin); #if 0 gst_ffmpegdemux_register (plugin); gst_ffmpegmux_register (plugin); gst_ffmpegcsp_register (plugin); gst_ffmpegscale_register (plugin); - gst_ffmpegdeinterlace_register (plugin); register_protocol (&gstreamer_protocol); #endif diff --git a/ext/ffmpeg/gstffmpegdeinterlace.c b/ext/ffmpeg/gstffmpegdeinterlace.c index ce90e5f..b33a839 100644 --- a/ext/ffmpeg/gstffmpegdeinterlace.c +++ b/ext/ffmpeg/gstffmpegdeinterlace.c @@ -2,6 +2,7 @@ * Copyright (C) <1999> Erik Walthinsen * This file: * Copyright (C) 2005 Luca Ognibene + * Copyright (C) 2006 Martin Zlomek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,348 +21,178 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif -#include #ifdef HAVE_FFMPEG_UNINSTALLED -#include +# include #else -#include +# include #endif +#include #include + #include "gstffmpeg.h" #include "gstffmpegcodecmap.h" -#define GST_TYPE_FFMPEGDEINTERLACE \ - (gst_ffmpegdeinterlace_get_type()) -#define GST_FFMPEGDEINTERLACE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) -#define GST_FFMPEGDEINTERLACE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) -#define GST_IS_FFMPEGDEINTERLACE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEINTERLACE)) -#define GST_IS_FFMPEGDEINTERLACE_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEINTERLACE)) - -typedef struct _GstFFMpegDeinterlace GstFFMpegDeinterlace; -typedef struct _GstFFMpegDeinterlaceClass GstFFMpegDeinterlaceClass; - -struct _GstFFMpegDeinterlace +typedef struct _GstFFMpegDeinterlace { GstElement element; GstPad *sinkpad, *srcpad; gint width, height; + gint to_size; enum PixelFormat pixfmt; AVPicture from_frame, to_frame; - GstCaps *sinkcaps; - - guint to_size; - -}; +} GstFFMpegDeinterlace; -struct _GstFFMpegDeinterlaceClass +typedef struct _GstFFMpegDeinterlaceClass { GstElementClass parent_class; -}; - -/* elementfactory information */ -static GstElementDetails ffmpegdeinterlace_details = { - "FFMPEG Deinterlace element", - "Filter/Converter/Video", - "Deinterlace video", - "Luca Ognibene ", -}; - -/* Signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; +} GstFFMpegDeinterlaceClass; -enum -{ - ARG_0, -}; +#define GST_TYPE_FFMPEGDEINTERLACE \ + (gst_ffmpegdeinterlace_get_type()) +#define GST_FFMPEGDEINTERLACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) +#define GST_FFMPEGDEINTERLACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEINTERLACE,GstFFMpegDeinterlace)) +#define GST_IS_FFMPEGDEINTERLACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEINTERLACE)) +#define GST_IS_FFMPEGDEINTERLACE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEINTERLACE)) -static GstStaticPadTemplate gst_ffmpegdeinterlace_src_template = -GST_STATIC_PAD_TEMPLATE ("src", +static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) ); -static GstStaticPadTemplate gst_ffmpegdeinterlace_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) ); +GST_BOILERPLATE (GstFFMpegDeinterlace, gst_ffmpegdeinterlace, GstElement, + GST_TYPE_ELEMENT); -static GType gst_ffmpegdeinterlace_get_type (void); - -static void gst_ffmpegdeinterlace_base_init (GstFFMpegDeinterlaceClass * klass); -static void gst_ffmpegdeinterlace_class_init (GstFFMpegDeinterlaceClass * klass); -static void gst_ffmpegdeinterlace_init (GstFFMpegDeinterlace * space); - -static void gst_ffmpegdeinterlace_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_ffmpegdeinterlace_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); - -static GstPadLinkReturn -gst_ffmpegdeinterlace_pad_link (GstPad * pad, const GstCaps * caps); +static GstFlowReturn gst_ffmpegdeinterlace_chain (GstPad * pad, + GstBuffer * inbuf); -static void gst_ffmpegdeinterlace_chain (GstPad * pad, GstData * data); -static GstStateChangeReturn gst_ffmpegdeinterlace_change_state (GstElement * element, - GstStateChange transition); - -static GstElementClass *parent_class = NULL; - -/*static guint gst_ffmpegdeinterlace_signals[LAST_SIGNAL] = { 0 }; */ - -static GstCaps * -gst_ffmpegdeinterlace_getcaps (GstPad * pad) +static void +gst_ffmpegdeinterlace_base_init (gpointer g_class) { - GstFFMpegDeinterlace *filter; - GstPad *otherpad; - - filter = GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); - - otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; + static GstElementDetails plugin_details = { + "FFMPEG Deinterlace element", + "Filter/Converter/Video", + "Deinterlace video", + "Luca Ognibene ", + }; + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_factory)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); + gst_element_class_set_details (element_class, &plugin_details); +} - return gst_pad_get_allowed_caps (otherpad); +static void +gst_ffmpegdeinterlace_class_init (GstFFMpegDeinterlaceClass * klass) +{ } -static GstPadLinkReturn -gst_ffmpegdeinterlace_pad_link (GstPad * pad, const GstCaps * caps) +static gboolean +gst_ffmpegdeinterlace_sink_setcaps (GstPad * pad, GstCaps * caps) { - GstStructure *structure; + GstFFMpegDeinterlace *deinterlace = + GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); + GstStructure *structure = gst_caps_get_structure (caps, 0); AVCodecContext *ctx; - GstFFMpegDeinterlace *deinterlace; - GstPad *otherpad; - GstPadLinkReturn ret; - int height, width; - - deinterlace = GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); - otherpad = (pad == deinterlace->srcpad) ? deinterlace->sinkpad : - deinterlace->srcpad; - - structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", &width); - ret &= gst_structure_get_int (structure, "height", &height); + if (!gst_structure_get_int (structure, "width", &deinterlace->width)) + return FALSE; + if (!gst_structure_get_int (structure, "height", &deinterlace->height)) + return FALSE; ctx = avcodec_alloc_context (); - ctx->width = width; - ctx->height = height; + ctx->width = deinterlace->width; + ctx->height = deinterlace->height; ctx->pix_fmt = PIX_FMT_NB; gst_ffmpeg_caps_with_codectype (CODEC_TYPE_VIDEO, caps, ctx); if (ctx->pix_fmt == PIX_FMT_NB) { av_free (ctx); - - /* we disable ourself here */ - return GST_PAD_LINK_REFUSED; + return FALSE; } deinterlace->pixfmt = ctx->pix_fmt; - av_free (ctx); - ret = gst_pad_try_set_caps (otherpad, caps); - if (GST_PAD_LINK_FAILED (ret)) { - return ret; - } - - deinterlace->width = width; - deinterlace->height = height; - deinterlace->to_size = avpicture_get_size (deinterlace->pixfmt, - deinterlace->width, deinterlace->height); - return GST_PAD_LINK_OK; -} - -static GType -gst_ffmpegdeinterlace_get_type (void) -{ - static GType ffmpegdeinterlace_type = 0; - - if (!ffmpegdeinterlace_type) { - static const GTypeInfo ffmpegdeinterlace_info = { - sizeof (GstFFMpegDeinterlaceClass), - (GBaseInitFunc) gst_ffmpegdeinterlace_base_init, - NULL, - (GClassInitFunc) gst_ffmpegdeinterlace_class_init, - NULL, - NULL, - sizeof (GstFFMpegDeinterlace), - 0, - (GInstanceInitFunc) gst_ffmpegdeinterlace_init, - }; - - ffmpegdeinterlace_type = g_type_register_static (GST_TYPE_ELEMENT, - "GstFFMpegDeinterlace", &ffmpegdeinterlace_info, 0); - } - - return ffmpegdeinterlace_type; -} - -static void -gst_ffmpegdeinterlace_base_init (GstFFMpegDeinterlaceClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_details (element_class, &ffmpegdeinterlace_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_ffmpegdeinterlace_src_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_ffmpegdeinterlace_sink_template)); -} - -static void -gst_ffmpegdeinterlace_class_init (GstFFMpegDeinterlaceClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + av_free (ctx); - gobject_class->set_property = gst_ffmpegdeinterlace_set_property; - gobject_class->get_property = gst_ffmpegdeinterlace_get_property; + deinterlace->to_size = + avpicture_get_size (deinterlace->pixfmt, deinterlace->width, + deinterlace->height); - gstelement_class->change_state = gst_ffmpegdeinterlace_change_state; + return gst_pad_set_caps (deinterlace->srcpad, caps); } static void -gst_ffmpegdeinterlace_init (GstFFMpegDeinterlace * deinterlace) +gst_ffmpegdeinterlace_init (GstFFMpegDeinterlace * deinterlace, + GstFFMpegDeinterlaceClass * klass) { - deinterlace->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get - (&gst_ffmpegdeinterlace_sink_template), - "sink"); - gst_pad_set_link_function (deinterlace->sinkpad, gst_ffmpegdeinterlace_pad_link); - gst_pad_set_getcaps_function (deinterlace->sinkpad, gst_ffmpegdeinterlace_getcaps); - gst_pad_set_chain_function (deinterlace->sinkpad, gst_ffmpegdeinterlace_chain); + deinterlace->sinkpad = + gst_pad_new_from_static_template (&sink_factory, "sink"); + gst_pad_set_setcaps_function (deinterlace->sinkpad, + gst_ffmpegdeinterlace_sink_setcaps); + gst_pad_set_chain_function (deinterlace->sinkpad, + gst_ffmpegdeinterlace_chain); gst_element_add_pad (GST_ELEMENT (deinterlace), deinterlace->sinkpad); - deinterlace->srcpad = gst_pad_new_from_template (gst_static_pad_template_get - (&gst_ffmpegdeinterlace_src_template), - "src"); + deinterlace->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); gst_element_add_pad (GST_ELEMENT (deinterlace), deinterlace->srcpad); - gst_pad_set_link_function (deinterlace->srcpad, gst_ffmpegdeinterlace_pad_link); - gst_pad_set_getcaps_function (deinterlace->srcpad, gst_ffmpegdeinterlace_getcaps); deinterlace->pixfmt = PIX_FMT_NB; } -static void -gst_ffmpegdeinterlace_chain (GstPad * pad, GstData * data) +static GstFlowReturn +gst_ffmpegdeinterlace_chain (GstPad * pad, GstBuffer * inbuf) { - GstBuffer *inbuf = GST_BUFFER (data); - GstFFMpegDeinterlace *deinterlace; + GstFFMpegDeinterlace *deinterlace = + GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); GstBuffer *outbuf = NULL; + GstFlowReturn result; - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (inbuf != NULL); - - deinterlace = GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); - - g_return_if_fail (deinterlace != NULL); - g_return_if_fail (GST_IS_FFMPEGDEINTERLACE (deinterlace)); - - if (!GST_PAD_IS_USABLE (deinterlace->srcpad)) { - gst_buffer_unref (inbuf); - return; - } - - outbuf = gst_pad_alloc_buffer_and_set_caps (deinterlace->srcpad, - GST_BUFFER_OFFSET_NONE, deinterlace->to_size); - - gst_ffmpeg_avpicture_fill (&deinterlace->from_frame, - GST_BUFFER_DATA (inbuf), - deinterlace->pixfmt, - deinterlace->width, deinterlace->height); - - gst_ffmpeg_avpicture_fill (&deinterlace->to_frame, - GST_BUFFER_DATA (outbuf), - deinterlace->pixfmt, - deinterlace->width, deinterlace->height); - - avpicture_deinterlace (&deinterlace->to_frame, &deinterlace->from_frame, - deinterlace->pixfmt, deinterlace->width, deinterlace->height); - - gst_buffer_stamp (outbuf, (const GstBuffer *) inbuf); - - gst_buffer_unref (inbuf); - gst_pad_push (deinterlace->srcpad, GST_DATA (outbuf)); - -} - -static GstStateChangeReturn -gst_ffmpegdeinterlace_change_state (GstElement * element, GstStateChange transition) -{ - GstFFMpegDeinterlace *deinterlace; - - deinterlace = GST_FFMPEGDEINTERLACE (element); - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - break; - } - - if (parent_class->change_state) - return parent_class->change_state (element, transition); + result = + gst_pad_alloc_buffer (deinterlace->srcpad, GST_BUFFER_OFFSET_NONE, + deinterlace->to_size, GST_PAD_CAPS (deinterlace->srcpad), &outbuf); + if (result == GST_FLOW_OK) { + gst_ffmpeg_avpicture_fill (&deinterlace->from_frame, + GST_BUFFER_DATA (inbuf), deinterlace->pixfmt, deinterlace->width, + deinterlace->height); - return GST_STATE_CHANGE_SUCCESS; -} + gst_ffmpeg_avpicture_fill (&deinterlace->to_frame, GST_BUFFER_DATA (outbuf), + deinterlace->pixfmt, deinterlace->width, deinterlace->height); -static void -gst_ffmpegdeinterlace_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstFFMpegDeinterlace *deinterlace; + avpicture_deinterlace (&deinterlace->to_frame, &deinterlace->from_frame, + deinterlace->pixfmt, deinterlace->width, deinterlace->height); - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_FFMPEGDEINTERLACE (object)); - deinterlace = GST_FFMPEGDEINTERLACE (object); + gst_buffer_stamp (outbuf, inbuf); - switch (prop_id) { - default: - break; + result = gst_pad_push (deinterlace->srcpad, outbuf); } -} -static void -gst_ffmpegdeinterlace_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstFFMpegDeinterlace *deinterlace; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_FFMPEGDEINTERLACE (object)); - deinterlace = GST_FFMPEGDEINTERLACE (object); + gst_buffer_unref (inbuf); - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + return result; } gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin) { - return gst_element_register (plugin, "ffdeinterlace", GST_RANK_NONE, GST_TYPE_FFMPEGDEINTERLACE); } -- 2.7.4