ext/: ffmpeg's libpostproc wrapper plugins
authorEdward Hervey <bilboed@bilboed.com>
Mon, 20 Jun 2005 13:07:52 +0000 (13:07 +0000)
committerEdward Hervey <bilboed@bilboed.com>
Mon, 20 Jun 2005 13:07:52 +0000 (13:07 +0000)
Original commit message from CVS:
* ext/Makefile.am: (SUBDIRS):
* ext/libpostproc:
* ext/libpostproc/Makefile.am:
* ext/libpostproc/gstpostproc.c:
* ext/libpostproc/gstpostproc.h:
ffmpeg's libpostproc wrapper plugins
* configure.ac:
added --enable-pp to ffmpeg configure arguments

ChangeLog
common
configure.ac
ext/Makefile.am
ext/libpostproc/Makefile.am [new file with mode: 0644]
ext/libpostproc/gstpostproc.c [new file with mode: 0644]
ext/libpostproc/gstpostproc.h [new file with mode: 0644]

index 5ed6c77..3b670a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2005-06-20  Edward Hervey  <edward@fluendo.com>
+
+       * ext/Makefile.am: (SUBDIRS):
+       * ext/libpostproc:
+       * ext/libpostproc/Makefile.am:
+       * ext/libpostproc/gstpostproc.c:
+       * ext/libpostproc/gstpostproc.h:
+       ffmpeg's libpostproc wrapper plugins
+
+       * configure.ac: 
+       added --enable-pp to ffmpeg configure arguments
+
 2005-06-11  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
        * configure.ac:
diff --git a/common b/common
index 495d6e3..d6e46b2 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 495d6e30b3e513aebbc98467707c609c49ea654d
+Subproject commit d6e46b214fac0ecb46010ff522af2f7653e1c18e
index 9a908c3..285ea9b 100644 (file)
@@ -86,7 +86,7 @@ dnl ###########################
 
 AC_DEFINE_UNQUOTED(HAVE_FFMPEG_UNINSTALLED, 1,
                    [Defined if building against uninstalled FFmpeg source])
-ac_configure_args="$ac_configure_args --disable-v4l --disable-audio-oss --disable-dv1394 --disable-vhook --disable-ffmpeg --disable-ffserver"
+ac_configure_args="$ac_configure_args --disable-v4l --disable-audio-oss --disable-dv1394 --disable-vhook --disable-ffmpeg --disable-ffserver --enable-pp"
 AC_CONFIG_SUBDIRS(gst-libs/ext/ffmpeg)
 
 AC_CONFIG_FILES(
@@ -94,6 +94,7 @@ Makefile
 gst-ffmpeg.spec
 ext/Makefile
 ext/ffmpeg/Makefile
+ext/libpostproc/Makefile
 gst-libs/Makefile
 gst-libs/ext/Makefile
 )
index 2e709be..0b91646 100644 (file)
@@ -1 +1 @@
-SUBDIRS = ffmpeg
+SUBDIRS = ffmpeg libpostproc
diff --git a/ext/libpostproc/Makefile.am b/ext/libpostproc/Makefile.am
new file mode 100644 (file)
index 0000000..98577a2
--- /dev/null
@@ -0,0 +1,17 @@
+
+plugin_LTLIBRARIES = libgstpostproc.la
+
+libgstpostproc_la_SOURCES = gstpostproc.c
+
+libgstpostproc_la_CFLAGS = $(GST_CFLAGS) \
+       -I $(top_srcdir)/gst-libs/ext/ffmpeg/libavformat \
+       -I $(top_srcdir)/gst-libs/ext/ffmpeg/libavcodec
+libgstpostproc_la_LIBADD = \
+       $(top_builddir)/gst-libs/ext/ffmpeg/libavformat/libavformat.la \
+       $(top_builddir)/gst-libs/ext/ffmpeg/libavcodec/libavcodec.la
+#      $(top_builddir)/gst-libs/ext/ffmpeg/libavcodec/libpostproc/libffpostproc.la
+
+libgstpostproc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+
+noinst_HEADERS = \
+       gstpostproc.h
\ No newline at end of file
diff --git a/ext/libpostproc/gstpostproc.c b/ext/libpostproc/gstpostproc.c
new file mode 100644 (file)
index 0000000..be34068
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+    Copyright (C) 2005 Edward Hervey (edward@fluendo.com)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/gstcpu.h>
+#include <gst/video/video.h>
+#ifdef HAVE_FFMPEG_UNINSTALLED
+#include <avcodec.h>
+#include <libpostproc/postprocess.h>
+#else
+#include <ffmpeg/avcodec.h>
+#include <ffmpeg/libpostproc/postprocess.h>
+#endif
+
+#include "gstpostproc.h"
+
+typedef struct _PostProcDetails PostProcDetails;
+
+struct _PostProcDetails {
+  char *shortname;
+  char *longname;
+  char *description;
+};
+
+static PostProcDetails filterdetails[] = {
+  {"hb", "hdeblock",           "horizontal deblocking filter"},
+  {"vb", "vdeblock",           "vertical deblocking filter"},
+  {"h1", "x1hdeblock",         "experimental horizontal deblocking filter 1"},
+  {"v1", "x1vdeblock",         "experimental vertical deblocking filter 1"},
+  {"ha", "ahdeblock",          "another horizontal deblocking filter"},
+  {"va", "avdeblock",          "another vertical deblocking filter"},
+  {"dr", "dering",             "deringing filter"},
+  {"al", "autolevels",         "automatic brightness/contrast filter"},
+  {"lb", "linblenddeint",      "linear blend interpolater"},
+  {"li", "linipoldeint",       "linear interpolation deinterlacer"},
+  {"ci", "cubicipoldeint",     "cubic interpolation deinterlacer"},
+  {"md", "mediandeint",                "median deinterlacer"},
+  {"fd", "ffmpegdeint",                "ffmpeg deinterlacer"},
+  {"l5", "lowpass5",           "FIR lowpass deinterlacer"},
+  {"tn", "tmpnoise",           "temporal noise reducer"},
+  {"fq", "forcequant",         "force quantizer"},
+  {"de", "default",            "default filters"},
+  {NULL, NULL,                 NULL}
+};
+
+typedef struct _GstPostProc GstPostProc;
+
+struct _GstPostProc {
+  GstElement   element;
+
+  GstPad       *sinkpad, *srcpad;
+  guint                quality;
+  gint         width, height;
+
+  gint         ystride, ustride, vstride;
+  gint         ysize, usize, vsize;
+
+  pp_mode_t    *mode;
+  pp_context_t *context;
+};
+
+typedef struct _GstPostProcClass GstPostProcClass;
+
+struct _GstPostProcClass {
+  GstElementClass      parent_class;
+
+  gint         filterid;
+};
+
+enum {
+  ARG_0,
+  ARG_QUALITY
+};
+
+/* hashtable, key = gtype, value = filterdetails index */
+static GHashTable      *global_plugins;
+
+/* TODO : add support for the other format supported by libpostproc */
+
+static GstStaticPadTemplate gst_postproc_src_template = 
+GST_STATIC_PAD_TEMPLATE ("src",
+                        GST_PAD_SRC,
+                        GST_PAD_ALWAYS,
+                        GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV("I420"))
+                        );
+                        
+static GstStaticPadTemplate gst_postproc_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+                        GST_PAD_SINK,
+                        GST_PAD_ALWAYS,
+                        GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV("I420"))
+                        );
+                        
+GST_DEBUG_CATEGORY (postproc);
+#define GST_CAT_DEFAULT postproc
+
+static void    gst_postproc_class_init (GstPostProcClass * klass);
+static void    gst_postproc_base_init (GstPostProcClass * klass);
+static void    gst_postproc_init (GstPostProc * pproc);
+static void    gst_postproc_dispose (GObject * object);
+
+static GstPadLinkReturn        gst_postproc_link (GstPad  * pad, const GstCaps * caps);
+
+static void    gst_postproc_chain (GstPad * pad, GstData * data);
+
+static GstElementStateReturn   gst_postproc_change_state (GstElement * element);
+
+static void    gst_postproc_set_property ( GObject * object, guint prop_id,
+                                           const GValue * value,
+                                           GParamSpec *pspec );
+static void    gst_postproc_get_property ( GObject * object, guint prop_id,
+                                           GValue * value, GParamSpec *pspec );
+
+static GstElementClass *parent_class = NULL;
+
+#ifndef GST_DISABLE_GST_DEBUG
+static void
+gst_ffmpeg_log_callback (void * ptr, int level, const char * fmt, va_list vl)
+{
+  GstDebugLevel gst_level;
+
+  switch (level) {
+    case AV_LOG_QUIET:
+      gst_level = GST_LEVEL_NONE;
+      break;
+    case AV_LOG_ERROR:
+      gst_level = GST_LEVEL_ERROR;
+      break;
+    case AV_LOG_INFO:
+      gst_level = GST_LEVEL_INFO;
+      break;
+    case AV_LOG_DEBUG:
+      gst_level = GST_LEVEL_DEBUG;
+      break;
+    default:
+      gst_level = GST_LEVEL_INFO;
+      break;
+  }
+
+  gst_debug_log_valist (postproc, gst_level, "", "", 0, NULL, fmt, vl);
+}
+#endif
+
+#define ROUND_UP_2(x)  (((x)+1)&~1)
+#define ROUND_UP_4(x)  (((x)+3)&~3)
+#define ROUND_UP_8(x)  (((x)+7)&~7)
+
+static void
+change_context ( GstPostProc * postproc , gint width, gint height )
+{
+  GstCPUFlags  flags;
+  int          ppflags;
+  /*
+    TODO : We need to find out what CPU flags we have in order to set
+    MMX/MMX2/3DNOW optimizations
+  */
+
+  GST_DEBUG ("change_context, width:%d, height:%d",
+            width, height);
+
+  if ((width != postproc->width) && (height != postproc->height)) {
+    if (postproc->context)
+      pp_free_context (postproc->context);
+    flags = gst_cpu_get_flags();
+    ppflags = (flags & GST_CPU_FLAG_MMX ? PP_CPU_CAPS_MMX : 0)
+      | (flags & GST_CPU_FLAG_MMXEXT ? PP_CPU_CAPS_MMX2 : 0)
+      | (flags & GST_CPU_FLAG_3DNOW ? PP_CPU_CAPS_3DNOW : 0);
+    postproc->context = pp_get_context (width, height, PP_FORMAT_420 | ppflags);
+    postproc->width = width;
+    postproc->height = height;
+    postproc->ystride = ROUND_UP_4 (width);
+    postproc->ustride = ROUND_UP_8 (width) / 2;
+    postproc->vstride = ROUND_UP_8 (postproc->ystride) / 2;
+    postproc->ysize = postproc->ystride * ROUND_UP_2 (height);
+    postproc->usize = postproc->ustride * ROUND_UP_2 (height) / 2;
+    postproc->vsize = postproc->vstride * ROUND_UP_2 (height) / 2;
+    GST_DEBUG ("new strides are (YUV) : %d %d %d",
+              postproc->ystride, postproc->ustride, postproc->vstride);
+  }
+}
+
+static void
+change_mode ( GstPostProc * postproc )
+{
+  GstPostProcClass * klass = (GstPostProcClass *) G_OBJECT_GET_CLASS (G_OBJECT (postproc));
+
+  if (postproc->mode)
+    pp_free_mode (postproc->mode);
+  postproc->mode = pp_get_mode_by_name_and_quality (filterdetails[klass->filterid].shortname,
+                                                   postproc->quality);
+}
+
+static void
+gst_postproc_base_init ( GstPostProcClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstElementDetails details;
+  gint ppidx;
+  
+  ppidx = GPOINTER_TO_INT (g_hash_table_lookup (global_plugins,
+        GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class))));
+
+  details.longname = g_strdup_printf ("LibPostProc %s filter", filterdetails[ppidx].longname);
+  details.klass = "Filter/Video";
+  details.description = g_strdup_printf ("LibPostProc %s", filterdetails[ppidx].description);
+  details.author = "Edward Hervey <edward@fluendo.com>";
+  gst_element_class_set_details (element_class, &details);
+  g_free(details.longname);
+  g_free(details.description);
+
+  gst_element_class_add_pad_template (element_class, 
+                                     gst_static_pad_template_get (&gst_postproc_src_template));
+  gst_element_class_add_pad_template (element_class, 
+                                     gst_static_pad_template_get (&gst_postproc_sink_template));
+
+  klass->filterid = ppidx;
+}
+
+static void
+gst_postproc_class_init (GstPostProcClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  g_object_class_install_property (gobject_class, ARG_QUALITY,
+      g_param_spec_uint ("quality", "Quality",
+                        "Quality level of filter (6:best)",
+                        0, 6, 6, G_PARAM_READWRITE));
+
+  gobject_class->dispose = gst_postproc_dispose;
+  gobject_class->set_property = gst_postproc_set_property;
+  gobject_class->get_property = gst_postproc_get_property;
+  gstelement_class->change_state = gst_postproc_change_state;
+}
+
+static void
+gst_postproc_init (GstPostProc * postproc)
+{
+  GST_FLAG_SET (postproc, GST_ELEMENT_WORK_IN_PLACE);
+
+  postproc->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get
+                                                (&gst_postproc_sink_template),
+                                                "sink");
+  gst_pad_set_link_function (postproc->sinkpad, gst_postproc_link);
+  gst_pad_set_chain_function (postproc->sinkpad, gst_postproc_chain);
+  gst_element_add_pad (GST_ELEMENT (postproc), postproc->sinkpad);
+
+  postproc->srcpad = gst_pad_new_from_template (gst_static_pad_template_get
+                                               (&gst_postproc_src_template),
+                                               "src");
+  gst_element_add_pad (GST_ELEMENT (postproc), postproc->srcpad);
+
+  postproc->quality = 6;
+  postproc->mode = NULL;
+  change_mode (postproc);
+  postproc->context = NULL;
+  postproc->width = 0;
+  postproc->height = 0;
+  postproc->ystride = 0;
+  postproc->ustride = 0;
+  postproc->vstride = 0;
+  postproc->ysize = 0;
+  postproc->usize = 0;
+  postproc->vsize = 0;
+}
+
+static void
+gst_postproc_dispose (GObject * object)
+{
+  GstPostProc * postproc = (GstPostProc *) object;
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+
+  if (postproc->mode)
+    pp_free_mode(postproc->mode);
+  if (postproc->context)
+    pp_free_context(postproc->context);
+}
+
+static GstPadLinkReturn
+gst_postproc_link (GstPad * pad, const GstCaps * caps)
+{
+  GstPostProc  *postproc;
+  GstStructure *structure;
+  GstPad       *otherpad;
+  gboolean     res;
+  GstPadLinkReturn     ret;
+  gint         width, height;
+  /* create/replace pp_context here */
+
+  postproc = (GstPostProc *) gst_pad_get_parent (pad);
+  otherpad = (pad == postproc->sinkpad) ? postproc->srcpad : postproc->sinkpad;
+
+  structure = gst_caps_get_structure (caps, 0);
+  res = gst_structure_get_int (structure, "width", &width);
+  res &= gst_structure_get_int (structure, "height", &height);
+
+  if (!res)
+    return GST_PAD_LINK_REFUSED;
+
+  ret = gst_pad_try_set_caps (otherpad, caps);
+
+  if (GST_PAD_LINK_FAILED (ret))
+    return ret;
+
+  change_context (postproc, width, height);
+
+  return GST_PAD_LINK_OK;
+}
+
+static void
+gst_postproc_chain (GstPad * pad, GstData * data)
+{
+  GstPostProc  *postproc;
+  GstBuffer    *in, *out;
+  int          stride[3];
+  unsigned char * inplane[3];
+  unsigned char        * outplane[3];
+  gint         pixdif, i;
+
+  GST_DEBUG("chaining");
+
+  /* postprocess the buffer !*/
+  postproc = (GstPostProc *) gst_pad_get_parent (pad);
+
+  g_return_if_fail(GST_IS_BUFFER (data));
+  g_return_if_fail(postproc->mode != NULL);
+  g_return_if_fail(postproc->context != NULL);
+
+  in = GST_BUFFER (data);
+  out = gst_buffer_copy_on_write (in);
+
+  stride[0] = postproc->ystride;
+  stride[1] = postproc->ustride;
+  stride[2] = postproc->vstride;
+/*   inplane[0] = GST_BUFFER_DATA(in); */
+/*   inplane[1] = inplane[0] + postproc->ysize; */
+/*   inplane[2] = inplane[1] + postproc->usize; */
+  outplane[0] = GST_BUFFER_DATA(out);
+  outplane[1] = outplane[0] + postproc->ysize;
+  outplane[2] = outplane[1] + postproc->usize;
+
+  GST_DEBUG ("calling pp_postprocess, width:%d, height:%d",
+            postproc->width, postproc->height);
+
+  pp_postprocess (outplane, stride,
+                 outplane, stride,
+                 postproc->width,
+                 postproc->height,
+                 "", 0,
+                 postproc->mode, postproc->context, 1);
+
+  gst_buffer_stamp (out, in);
+
+  gst_pad_push (postproc->srcpad, GST_DATA (out));
+  /*
+    void  pp_postprocess(uint8_t * src[3], int srcStride[3],
+       uint8_t * dst[3], int dstStride[3],
+       int horizontalSize, int verticalSize,
+       QP_STORE_T *QP_store,  int QP_stride,
+       pp_mode_t *mode, pp_context_t *ppContext, int pict_type);
+
+       src is the src buffer data
+       srcStride is ->ystride, ->ustride, ->vstride
+       dst same as src
+       dstStride same as srcStride
+       horizontalSize and VerticalsSize are obvious
+       QP_store can be null and qp_stride too
+       mode = mode
+       context = context
+       pict_type = 0
+  */
+
+}
+
+static GstElementStateReturn
+gst_postproc_change_state (GstElement * element)
+{
+  GstPostProc  *postproc = (GstPostProc *) element;
+  /* don't go to play if we don't have mode and context */
+
+  switch (GST_STATE_TRANSITION (element)) {
+  case GST_STATE_PAUSED_TO_PLAYING:
+    if ((!postproc->mode) && (!postproc->context))
+      return GST_STATE_FAILURE;
+  }
+
+  if (parent_class->change_state)
+    return parent_class->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
+static void
+gst_postproc_set_property ( GObject * object, guint prop_id,
+                           const GValue * value,
+                           GParamSpec *pspec )
+{
+  GstPostProc  *postproc = (GstPostProc *) object;
+  gint quality;
+
+  switch (prop_id) {
+  case ARG_QUALITY:
+    quality = g_value_get_uint (value);
+    if (quality != postproc->quality) {
+      postproc->quality = quality;
+      change_mode (postproc);
+    }
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+  }
+}
+
+static void
+gst_postproc_get_property ( GObject * object, guint prop_id,
+                           GValue * value, GParamSpec *pspec )
+{
+  GstPostProc  *postproc = (GstPostProc *) object;
+
+  switch (prop_id) {
+  case ARG_QUALITY:
+    g_value_set_uint (value, postproc->quality);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+gboolean
+gst_postproc_register(GstPlugin * plugin)
+{
+  GTypeInfo    typeinfo = {
+    sizeof (GstPostProcClass),
+    (GBaseInitFunc) gst_postproc_base_init,
+    NULL,
+    (GClassInitFunc) gst_postproc_class_init,
+    NULL,
+    NULL,
+    sizeof (GstPostProc),
+    0,
+    (GInstanceInitFunc) gst_postproc_init,
+  };
+  GType type;
+  int  i;
+
+  global_plugins = g_hash_table_new (NULL, NULL);
+  for (i = 0; filterdetails[i].shortname; i++) {
+    gchar      *type_name;
+
+    /* create type_name */
+    type_name = g_strdup_printf("postproc_%s", filterdetails[i].longname);
+    if (g_type_from_name (type_name)) {
+      g_free (type_name);
+      continue;
+    }
+
+    /* create gtype */
+    type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
+
+    /* register element */
+    if (!gst_element_register (plugin, type_name, GST_RANK_PRIMARY, type)) {
+      g_free(type_name);
+      return FALSE;
+    }
+
+    g_free(type_name);
+    g_hash_table_insert (global_plugins,
+                        GINT_TO_POINTER (type),
+                        GINT_TO_POINTER (i));
+  }
+  g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
+  return TRUE;
+}
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+  GST_DEBUG_CATEGORY_INIT (postproc, "postproc", 0, "video postprocessing elements");
+#ifndef GST_DISABLE_GST_DEBUG
+  av_log_set_callback (gst_ffmpeg_log_callback);
+#endif
+
+  /* Register the filters */
+  gst_postproc_register( plugin );
+
+  /* Now we can return the pointer to the newly created Plugin object. */
+  return TRUE;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+    GST_VERSION_MINOR,
+    "postproc",
+    "postprocessing elements",
+    plugin_init,
+    FFMPEG_VERSION, "GPL", "FFMpeg", "http://ffmpeg.sourceforge.net/")
+
+
diff --git a/ext/libpostproc/gstpostproc.h b/ext/libpostproc/gstpostproc.h
new file mode 100644 (file)
index 0000000..ed3cfe2
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+    Copyright (C) 2005 Edward Hervey (edward@fluendo.com)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __GST_POSTPROC_H__
+#define __GST_POSTPROC_H__
+
+#ifdef HAVE_FFMPEG_UNINSTALLED
+#include <avcodec.h>
+#include <avformat.h>
+#else
+#include <ffmpeg/avcodec.h>
+#include <ffmpeg/avformat.h>
+#endif
+
+#include <gst/gst.h>
+
+GST_DEBUG_CATEGORY_EXTERN (postproc);
+#define GST_CAT_DEFAULT postproc
+
+G_BEGIN_DECLS
+
+extern gboolean gst_postproc_register (GstPlugin * plugin);
+
+G_END_DECLS
+
+#endif