diff options
| -rw-r--r-- | ChangeLog | 12 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | gst/cutter/Makefile.am | 5 | ||||
| -rw-r--r-- | gst/cutter/gstcutter.c | 267 | ||||
| -rw-r--r-- | gst/level/gstlevel.c | 4 | 
5 files changed, 134 insertions, 156 deletions
@@ -1,3 +1,15 @@ +2005-11-21  Thomas Vander Stichele  <thomas at apestaart dot org> + +	* configure.ac: +	* gst/cutter/Makefile.am: +	* gst/cutter/gstcutter.c: (gst_cutter_class_init), +	(gst_cutter_init), (gst_cutter_message_new), (gst_cutter_chain), +	(gst_cutter_set_property), (gst_cutter_get_property), +	(plugin_init), (gst_cutter_get_caps): +	  port cutter +	* gst/level/gstlevel.c: +	  fix up plugin details +  2005-11-21  Tim-Philipp Müller  <tim at centricular dot net>  	* ext/dv/gstdvdemux.c: (gst_dvdemux_handle_sink_event): diff --git a/configure.ac b/configure.ac index 21bf5711..ad0b4087 100644 --- a/configure.ac +++ b/configure.ac @@ -77,6 +77,7 @@ GST_PLUGINS_ALL="\  		auparse \  		autodetect \  		avi \ +		cutter \  		debug \  		effectv \  		flx \ @@ -526,6 +527,7 @@ gst/alpha/Makefile  gst/auparse/Makefile  gst/autodetect/Makefile  gst/avi/Makefile +gst/cutter/Makefile  gst/debug/Makefile  gst/effectv/Makefile  gst/goom/Makefile diff --git a/gst/cutter/Makefile.am b/gst/cutter/Makefile.am index e88ef155..0d93b29d 100644 --- a/gst/cutter/Makefile.am +++ b/gst/cutter/Makefile.am @@ -1,9 +1,8 @@ -  plugin_LTLIBRARIES = libgstcutter.la  libgstcutter_la_SOURCES = gstcutter.c -libgstcutter_la_CFLAGS = $(GST_CFLAGS) -libgstcutter_la_LIBADD = $(GST_LIBS) +libgstcutter_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) +libgstcutter_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(GST_BASE_LIBS)  libgstcutter_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)  noinst_HEADERS = gstcutter.h filter.func diff --git a/gst/cutter/gstcutter.c b/gst/cutter/gstcutter.c index 05ae543d..78f35a82 100644 --- a/gst/cutter/gstcutter.c +++ b/gst/cutter/gstcutter.c @@ -1,5 +1,7 @@  /* GStreamer   * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * Copyright (C) 2002,2003,2005 + *           Thomas Vander Stichele <thomas at apestaart dot org>   *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Library General Public @@ -25,7 +27,14 @@  #include "gstcutter.h"  #include "math.h" -/* elementfactory information */ +GST_DEBUG_CATEGORY (cutter_debug); +#define GST_CAT_DEFAULT cutter_debug + + +#define CUTTER_DEFAULT_THRESHOLD_LEVEL    0.1 +#define CUTTER_DEFAULT_THRESHOLD_LENGTH  (500 * GST_MSECOND) +#define CUTTER_DEFAULT_PRE_LENGTH        (200 * GST_MSECOND) +  static GstElementDetails cutter_details = {    "Cutter",    "Filter/Editor/Audio", @@ -33,26 +42,6 @@ static GstElementDetails cutter_details = {    "Thomas <thomas@apestaart.org>",  }; - -/* Filter signals and args */ -enum -{ -  /* FILL ME */ -  CUT_START, -  CUT_STOP, -  LAST_SIGNAL -}; - -enum -{ -  ARG_0, -  ARG_THRESHOLD, -  ARG_THRESHOLD_DB, -  ARG_RUN_LENGTH, -  ARG_PRE_LENGTH, -  ARG_LEAKY -}; -  static GstStaticPadTemplate cutter_src_factory = GST_STATIC_PAD_TEMPLATE ("src",      GST_PAD_SRC,      GST_PAD_ALWAYS, @@ -68,46 +57,29 @@ static GstStaticPadTemplate cutter_sink_factory =          GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS)      ); -static void gst_cutter_base_init (gpointer g_class); -static void gst_cutter_class_init (GstCutterClass * klass); -static void gst_cutter_init (GstCutter * filter); +enum +{ +  PROP_0, +  PROP_THRESHOLD, +  PROP_THRESHOLD_DB, +  PROP_RUN_LENGTH, +  PROP_PRE_LENGTH, +  PROP_LEAKY +}; + +GST_BOILERPLATE (GstCutter, gst_cutter, GstElement, GST_TYPE_ELEMENT);  static void gst_cutter_set_property (GObject * object, guint prop_id,      const GValue * value, GParamSpec * pspec);  static void gst_cutter_get_property (GObject * object, guint prop_id,      GValue * value, GParamSpec * pspec); -static void gst_cutter_chain (GstPad * pad, GstData * _data); +static GstFlowReturn gst_cutter_chain (GstPad * pad, GstBuffer * buffer);  static double inline gst_cutter_16bit_ms (gint16 * data, guint numsamples);  static double inline gst_cutter_8bit_ms (gint8 * data, guint numsamples);  void gst_cutter_get_caps (GstPad * pad, GstCutter * filter); -static GstElementClass *parent_class = NULL; -static guint gst_cutter_signals[LAST_SIGNAL] = { 0 }; - - -GType -gst_cutter_get_type (void) -{ -  static GType cutter_type = 0; - -  if (!cutter_type) { -    static const GTypeInfo cutter_info = { -      sizeof (GstCutterClass), -      gst_cutter_base_init, -      NULL, -      (GClassInitFunc) gst_cutter_class_init, NULL, NULL, -      sizeof (GstCutter), 0, -      (GInstanceInitFunc) gst_cutter_init, -    }; - -    cutter_type = g_type_register_static (GST_TYPE_ELEMENT, "GstCutter", -        &cutter_info, 0); -  } -  return cutter_type; -} -  static void  gst_cutter_base_init (gpointer g_class)  { @@ -120,20 +92,6 @@ gst_cutter_base_init (gpointer g_class)    gst_element_class_set_details (element_class, &cutter_details);  } -static GstPadLinkReturn -gst_cutter_link (GstPad * pad, const GstCaps * caps) -{ -  GstCutter *filter; -  GstPad *otherpad; - -  filter = GST_CUTTER (gst_pad_get_parent (pad)); -  g_return_val_if_fail (filter != NULL, GST_PAD_LINK_REFUSED); -  g_return_val_if_fail (GST_IS_CUTTER (filter), GST_PAD_LINK_REFUSED); -  otherpad = (pad == filter->srcpad ? filter->sinkpad : filter->srcpad); - -  return gst_pad_try_set_caps (otherpad, caps); -} -  static void  gst_cutter_class_init (GstCutterClass * klass)  { @@ -143,46 +101,35 @@ gst_cutter_class_init (GstCutterClass * klass)    gobject_class = (GObjectClass *) klass;    gstelement_class = (GstElementClass *) klass; -  parent_class = g_type_class_ref (GST_TYPE_ELEMENT); +  gobject_class->set_property = gst_cutter_set_property; +  gobject_class->get_property = gst_cutter_get_property; -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_THRESHOLD, +  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_THRESHOLD,        g_param_spec_double ("threshold", "Threshold",            "Volume threshold before trigger",            -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_THRESHOLD_DB, -      g_param_spec_double ("threshold_dB", "Threshold (dB)", +  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_THRESHOLD_DB, +      g_param_spec_double ("threshold-dB", "Threshold (dB)",            "Volume threshold before trigger (in dB)",            -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_RUN_LENGTH, -      g_param_spec_double ("runlength", "Runlength", -          "Length of drop below threshold before cut_stop (seconds)", -          0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PRE_LENGTH, -      g_param_spec_double ("prelength", "prelength", -          "Length of pre-recording buffer (seconds)", -          0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LEAKY, +  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_RUN_LENGTH, +      g_param_spec_uint64 ("run-length", "Run length", +          "Length of drop below threshold before cut_stop (in nanoseconds)", +          0, G_MAXUINT64, 0, G_PARAM_READWRITE)); +  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PRE_LENGTH, +      g_param_spec_uint64 ("pre-length", "Pre-recording buffer length", +          "Length of pre-recording buffer (in nanoseconds)", +          0, G_MAXUINT64, 0, G_PARAM_READWRITE)); +  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LEAKY,        g_param_spec_boolean ("leaky", "Leaky",            "do we leak buffers when below threshold ?",            FALSE, G_PARAM_READWRITE)); -  gst_cutter_signals[CUT_START] = -      g_signal_new ("cut-start", G_TYPE_FROM_CLASS (klass), -      G_SIGNAL_RUN_FIRST, -      G_STRUCT_OFFSET (GstCutterClass, cut_start), NULL, NULL, -      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -  gst_cutter_signals[CUT_STOP] = -      g_signal_new ("cut-stop", G_TYPE_FROM_CLASS (klass), -      G_SIGNAL_RUN_FIRST, -      G_STRUCT_OFFSET (GstCutterClass, cut_stop), NULL, NULL, -      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - -  gobject_class->set_property = gst_cutter_set_property; -  gobject_class->get_property = gst_cutter_get_property; +  GST_DEBUG_CATEGORY_INIT (cutter_debug, "cutter", 0, "Audio cutting");  }  static void -gst_cutter_init (GstCutter * filter) +gst_cutter_init (GstCutter * filter, GstCutterClass * g_class)  {    filter->sinkpad =        gst_pad_new_from_template (gst_static_pad_template_get @@ -191,28 +138,42 @@ gst_cutter_init (GstCutter * filter)        gst_pad_new_from_template (gst_static_pad_template_get        (&cutter_src_factory), "src"); -  filter->threshold_level = 0.1; -  filter->threshold_length = 0.5; -  filter->silent_run_length = 0.0; +  filter->threshold_level = CUTTER_DEFAULT_THRESHOLD_LEVEL; +  filter->threshold_length = CUTTER_DEFAULT_THRESHOLD_LENGTH; +  filter->silent_run_length = 0 * GST_SECOND;    filter->silent = TRUE; -  filter->pre_length = 0.2; -  filter->pre_run_length = 0.0; +  filter->pre_length = CUTTER_DEFAULT_PRE_LENGTH; +  filter->pre_run_length = 0 * GST_SECOND;    filter->pre_buffer = NULL;    filter->leaky = FALSE;    gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);    gst_pad_set_chain_function (filter->sinkpad, gst_cutter_chain); -  gst_pad_set_link_function (filter->sinkpad, gst_cutter_link); +  gst_pad_use_fixed_caps (filter->sinkpad);    gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); -  /*gst_pad_set_link_function (filter->srcpad, gst_cutter_link); */ +  gst_pad_use_fixed_caps (filter->srcpad);  } -static void -gst_cutter_chain (GstPad * pad, GstData * _data) +static GstMessage * +gst_cutter_message_new (GstCutter * c, gboolean above, GstClockTime timestamp) +{ +  GstStructure *s; +  GValue v = { 0, }; + +  g_value_init (&v, GST_TYPE_LIST); + +  s = gst_structure_new ("cutter", +      "above", G_TYPE_BOOLEAN, above, +      "timestamp", GST_TYPE_CLOCK_TIME, timestamp, NULL); + +  return gst_message_new_element (GST_OBJECT (c), s); +} + +static GstFlowReturn +gst_cutter_chain (GstPad * pad, GstBuffer * buf)  { -  GstBuffer *buf = GST_BUFFER (_data);    GstCutter *filter;    gint16 *in_data;    double RMS = 0.0;             /* RMS of signal in buffer */ @@ -220,22 +181,25 @@ gst_cutter_chain (GstPad * pad, GstData * _data)    static gboolean silent_prev = FALSE;  /* previous value of silent */    GstBuffer *prebuf;            /* pointer to a prebuffer element */ -  g_return_if_fail (pad != NULL); -  g_return_if_fail (GST_IS_PAD (pad)); -  g_return_if_fail (buf != NULL); +  g_return_val_if_fail (pad != NULL, GST_FLOW_ERROR); +  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); +  g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);    filter = GST_CUTTER (GST_OBJECT_PARENT (pad)); -  g_return_if_fail (filter != NULL); -  g_return_if_fail (GST_IS_CUTTER (filter)); +  g_return_val_if_fail (filter != NULL, GST_FLOW_ERROR); +  g_return_val_if_fail (GST_IS_CUTTER (filter), GST_FLOW_ERROR); -  if (gst_audio_is_buffer_framed (pad, buf) == FALSE) +  if (gst_audio_is_buffer_framed (pad, buf) == FALSE) {      g_warning ("audio buffer is not framed !\n"); +    return GST_FLOW_ERROR; +  }    if (!filter->have_caps)      gst_cutter_get_caps (pad, filter);    in_data = (gint16 *) GST_BUFFER_DATA (buf); -  GST_DEBUG ("length of prerec buffer: %.3f sec", filter->pre_run_length); +  GST_LOG_OBJECT (filter, "length of prerec buffer: %" GST_TIME_FORMAT, +      GST_TIME_ARGS (filter->pre_run_length));    /* calculate mean square value on buffer */    switch (filter->width) { @@ -247,8 +211,7 @@ gst_cutter_chain (GstPad * pad, GstData * _data)        break;      default:        /* this shouldn't happen */ -      g_print ("WARNING: no mean square function for width %d\n", -          filter->width); +      g_warning ("no mean square function for width %d\n", filter->width);        break;    } @@ -258,12 +221,13 @@ gst_cutter_chain (GstPad * pad, GstData * _data)    /* if RMS below threshold, add buffer length to silent run length count     * if not, reset     */ -  GST_DEBUG ("buffer stats: ms %f, RMS %f, audio length %f", -      ms, RMS, gst_audio_length (filter->srcpad, buf)); +  GST_LOG_OBJECT (filter, "buffer stats: ms %f, RMS %f, audio length %f", +      ms, RMS, gst_audio_duration_from_pad_buffer (filter->sinkpad, buf));    if (RMS < filter->threshold_level) -    filter->silent_run_length += gst_audio_length (filter->srcpad, buf); +    filter->silent_run_length += +        gst_audio_duration_from_pad_buffer (filter->sinkpad, buf);    else { -    filter->silent_run_length = 0.0; +    filter->silent_run_length = 0 * GST_SECOND;      filter->silent = FALSE;    } @@ -276,23 +240,28 @@ gst_cutter_chain (GstPad * pad, GstData * _data)     */    if (filter->silent != silent_prev) {      if (filter->silent) { -/*      g_print ("DEBUG: cutter: cut to here, turning off out\n"); */ -      g_signal_emit (G_OBJECT (filter), gst_cutter_signals[CUT_STOP], 0); +      GstMessage *m = +          gst_cutter_message_new (filter, FALSE, GST_BUFFER_TIMESTAMP (buf)); +      GST_DEBUG_OBJECT (filter, "signaling CUT_STOP"); +      gst_element_post_message (GST_ELEMENT (filter), m);      } else {        gint count = 0; +      GstMessage *m = +          gst_cutter_message_new (filter, TRUE, GST_BUFFER_TIMESTAMP (buf)); -/*      g_print ("DEBUG: cutter: start from here, turning on out\n"); */ +      GST_DEBUG_OBJECT (filter, "signaling CUT_START"); +      gst_element_post_message (GST_ELEMENT (filter), m);        /* first of all, flush current buffer */ -      g_signal_emit (G_OBJECT (filter), gst_cutter_signals[CUT_START], 0); -      GST_DEBUG ("flushing buffer of length %.3f", filter->pre_run_length); +      GST_DEBUG_OBJECT (filter, "flushing buffer of length %" GST_TIME_FORMAT, +          GST_TIME_ARGS (filter->pre_run_length));        while (filter->pre_buffer) {          prebuf = (g_list_first (filter->pre_buffer))->data;          filter->pre_buffer = g_list_remove (filter->pre_buffer, prebuf); -        gst_pad_push (filter->srcpad, GST_DATA (prebuf)); +        gst_pad_push (filter->srcpad, prebuf);          ++count;        } -      GST_DEBUG ("flushed %d buffers", count); -      filter->pre_run_length = 0.0; +      GST_DEBUG_OBJECT (filter, "flushed %d buffers", count); +      filter->pre_run_length = 0 * GST_SECOND;      }    }    /* now check if we have to send the new buffer to the internal buffer cache @@ -306,20 +275,22 @@ gst_cutter_chain (GstPad * pad, GstData * _data)         gst_buffer_ref (buf);       */      filter->pre_buffer = g_list_append (filter->pre_buffer, buf); -    filter->pre_run_length += gst_audio_length (filter->srcpad, buf); +    filter->pre_run_length += +        gst_audio_duration_from_pad_buffer (filter->sinkpad, buf);      while (filter->pre_run_length > filter->pre_length) {        prebuf = (g_list_first (filter->pre_buffer))->data;        g_assert (GST_IS_BUFFER (prebuf));        filter->pre_buffer = g_list_remove (filter->pre_buffer, prebuf); -      filter->pre_run_length -= gst_audio_length (filter->srcpad, prebuf); +      filter->pre_run_length -= +          gst_audio_duration_from_pad_buffer (filter->sinkpad, prebuf);        /* only pass buffers if we don't leak */        if (!filter->leaky) -        gst_pad_push (filter->srcpad, GST_DATA (prebuf)); -      /* we unref it after getting it out of the pre_buffer */ -      gst_buffer_unref (prebuf); +        gst_pad_push (filter->srcpad, prebuf);      }    } else -    gst_pad_push (filter->srcpad, GST_DATA (buf)); +    gst_pad_push (filter->srcpad, buf); + +  return GST_FLOW_OK;  }  static double inline @@ -337,12 +308,12 @@ gst_cutter_16bit_ms (gint16 * data, guint num_samples)    filter = GST_CUTTER (object);    switch (prop_id) { -    case ARG_THRESHOLD: +    case PROP_THRESHOLD:        /* set the level */        filter->threshold_level = g_value_get_double (value);        GST_DEBUG ("DEBUG: set threshold level to %f", filter->threshold_level);        break; -    case ARG_THRESHOLD_DB: +    case PROP_THRESHOLD_DB:        /* set the level given in dB         * value in dB = 20 * log (value)         * values in dB < 0 result in values between 0 and 1 @@ -350,15 +321,15 @@ gst_cutter_16bit_ms (gint16 * data, guint num_samples)        filter->threshold_level = pow (10, g_value_get_double (value) / 20);        GST_DEBUG ("DEBUG: set threshold level to %f", filter->threshold_level);        break; -    case ARG_RUN_LENGTH: +    case PROP_RUN_LENGTH:        /* set the minimum length of the silent run required */ -      filter->threshold_length = g_value_get_double (value); +      filter->threshold_length = g_value_get_uint64 (value);        break; -    case ARG_PRE_LENGTH: +    case PROP_PRE_LENGTH:        /* set the length of the pre-record block */ -      filter->pre_length = g_value_get_double (value); +      filter->pre_length = g_value_get_uint64 (value);        break; -    case ARG_LEAKY: +    case PROP_LEAKY:        /* set if the pre-record buffer is leaky or not */        filter->leaky = g_value_get_boolean (value);        break; @@ -378,19 +349,19 @@ gst_cutter_get_property (GObject * object, guint prop_id,    filter = GST_CUTTER (object);    switch (prop_id) { -    case ARG_RUN_LENGTH: -      g_value_set_double (value, filter->threshold_length); +    case PROP_RUN_LENGTH: +      g_value_set_uint64 (value, filter->threshold_length);        break; -    case ARG_THRESHOLD: +    case PROP_THRESHOLD:        g_value_set_double (value, filter->threshold_level);        break; -    case ARG_THRESHOLD_DB: +    case PROP_THRESHOLD_DB:        g_value_set_double (value, 20 * log (filter->threshold_level));        break; -    case ARG_PRE_LENGTH: -      g_value_set_double (value, filter->pre_length); +    case PROP_PRE_LENGTH: +      g_value_set_uint64 (value, filter->pre_length);        break; -    case ARG_LEAKY: +    case PROP_LEAKY:        g_value_set_boolean (value, filter->leaky);        break;      default: @@ -402,10 +373,6 @@ gst_cutter_get_property (GObject * object, guint prop_id,  static gboolean  plugin_init (GstPlugin * plugin)  { -  /* load audio support library */ -  if (!gst_library_load ("gstaudio")) -    return FALSE; -    if (!gst_element_register (plugin, "cutter", GST_RANK_NONE, GST_TYPE_CUTTER))      return FALSE; @@ -416,9 +383,11 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,      GST_VERSION_MINOR,      "cutter",      "Audio Cutter to split audio into non-silent bits", -    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) +    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); + -     void gst_cutter_get_caps (GstPad * pad, GstCutter * filter) +void +gst_cutter_get_caps (GstPad * pad, GstCutter * filter)  {    const GstCaps *caps = NULL;    GstStructure *structure; @@ -426,8 +395,6 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,    caps = GST_PAD_CAPS (pad);    /* FIXME : Please change this to a better warning method ! */    g_assert (caps != NULL); -  if (caps == NULL) -    printf ("WARNING: get_caps: Could not get caps of pad !\n");    structure = gst_caps_get_structure (caps, 0);    gst_structure_get_int (structure, "width", &filter->width);    filter->max_sample = gst_audio_highest_sample_value (pad); diff --git a/gst/level/gstlevel.c b/gst/level/gstlevel.c index acd60679..b613a645 100644 --- a/gst/level/gstlevel.c +++ b/gst/level/gstlevel.c @@ -90,7 +90,7 @@ static GstElementDetails level_details = {    "Level",    "Filter/Analyzer/Audio",    "RMS/Peak/Decaying Peak Level messager for audio/raw", -  "Thomas <thomas@apestaart.org>" +  "Thomas Vander Stichele <thomas at apestaart dot org>"  };  static GstStaticPadTemplate sink_template_factory = @@ -117,7 +117,6 @@ GST_STATIC_PAD_TEMPLATE ("src",          "depth = (int) { 8, 16 }, " "signed = (boolean) true")      ); -  enum  {    PROP_0, @@ -127,7 +126,6 @@ enum    PROP_PEAK_FALLOFF  }; -  GST_BOILERPLATE (GstLevel, gst_level, GstBaseTransform,      GST_TYPE_BASE_TRANSFORM);  | 
