[gst-plugins-farsight/master] Remove dtmf plugins, they've been moved to -bad
Olivier Crête
olivier.crete at collabora.co.uk
Thu Feb 26 10:01:27 PST 2009
---
configure.ac | 3 -
gst/dtmf/Makefile.am | 16 -
gst/dtmf/gstdtmf.c | 31 --
gst/dtmf/gstdtmfsrc.c | 955 -------------------------------------
gst/dtmf/gstdtmfsrc.h | 97 ----
gst/dtmf/gstrtpdtmfcommon.h | 22 -
gst/dtmf/gstrtpdtmfdepay.c | 495 -------------------
gst/dtmf/gstrtpdtmfdepay.h | 69 ---
gst/dtmf/gstrtpdtmfsrc.c | 1106 -------------------------------------------
gst/dtmf/gstrtpdtmfsrc.h | 111 -----
10 files changed, 0 insertions(+), 2905 deletions(-)
delete mode 100644 gst/dtmf/Makefile.am
delete mode 100644 gst/dtmf/gstdtmf.c
delete mode 100644 gst/dtmf/gstdtmfsrc.c
delete mode 100644 gst/dtmf/gstdtmfsrc.h
delete mode 100644 gst/dtmf/gstrtpdtmfcommon.h
delete mode 100644 gst/dtmf/gstrtpdtmfdepay.c
delete mode 100644 gst/dtmf/gstrtpdtmfdepay.h
delete mode 100644 gst/dtmf/gstrtpdtmfsrc.c
delete mode 100644 gst/dtmf/gstrtpdtmfsrc.h
diff --git a/configure.ac b/configure.ac
index 1e48830..c7b5307 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,7 +128,6 @@ rtpmux \
rtpdemux \
rtpjitterbuffer \
network-simulator \
-dtmf \
siren \
rtppayloads \
valve \
@@ -337,7 +336,6 @@ AC_SUBST(HAVE_JINGLEP2P)
AM_CONDITIONAL(USE_JINGLEP2P, test x$USE_JINGLEP2P = xyes)
if test "x$HAVE_GST_13" != "xyes" ; then
- GST_PLUGINS_SELECTED="${GST_PLUGINS_SELECTED/dtmf/}"
GST_PLUGINS_SELECTED="${GST_PLUGINS_SELECTED/valve/}"
AC_MSG_NOTICE([DTMF and Valve plugins not compiled because you dont have gstreamer >= 0.10.13])
fi
@@ -352,7 +350,6 @@ ext/jasper/Makefile \
ext/ice/Makefile \
ext/gconf/Makefile \
gst/Makefile \
-gst/dtmf/Makefile \
gst/siren/Makefile \
gst/rtppayloads/Makefile \
gst/rtpmux/Makefile \
diff --git a/gst/dtmf/Makefile.am b/gst/dtmf/Makefile.am
deleted file mode 100644
index c96a3a4..0000000
--- a/gst/dtmf/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-plugin_LTLIBRARIES = libgstdtmf.la
-
-libgstdtmf_la_SOURCES = gstdtmfsrc.c \
- gstrtpdtmfsrc.c \
- gstrtpdtmfdepay.c \
- gstdtmf.c
-
-noinst_HEADERS = gstdtmfsrc.h \
- gstrtpdtmfsrc.h \
- gstrtpdtmfdepay.h \
- gstrtpdtmfcommon.h
-
-libgstdtmf_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(ERROR_CFLAGS) -DEXTERN_BUF -DRTP_SUPPORT
-libgstdtmf_la_LIBADD = $(GST_LIBS_LIBS) -lm
-libgstdtmf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstrtp- at GST_MAJORMINOR@
-
diff --git a/gst/dtmf/gstdtmf.c b/gst/dtmf/gstdtmf.c
deleted file mode 100644
index 86bbafa..0000000
--- a/gst/dtmf/gstdtmf.c
+++ /dev/null
@@ -1,31 +0,0 @@
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstdtmfsrc.h"
-#include "gstrtpdtmfsrc.h"
-#include "gstrtpdtmfdepay.h"
-
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
- if (!gst_dtmf_src_plugin_init (plugin))
- return FALSE;
-
- if (!gst_rtp_dtmf_src_plugin_init (plugin))
- return FALSE;
-
-
- if (!gst_rtp_dtmf_depay_plugin_init (plugin))
- return FALSE;
-
- return TRUE;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- "dtmf",
- "DTMF plugins",
- plugin_init, "0.1" , "LGPL", "DTMF", "");
diff --git a/gst/dtmf/gstdtmfsrc.c b/gst/dtmf/gstdtmfsrc.c
deleted file mode 100644
index 4b2f9a2..0000000
--- a/gst/dtmf/gstdtmfsrc.c
+++ /dev/null
@@ -1,955 +0,0 @@
-/* GStreamer DTMF source
- *
- * gstdtmfsrc.c:
- *
- * Copyright (C) <2007> Collabora.
- * Contact: Youness Alaoui <youness.alaoui at collabora.co.uk>
- * Copyright (C) <2007> Nokia Corporation.
- * Contact: Zeeshan Ali <zeeshan.ali at nokia.com>
- * Copyright (C) 1999,2000 Erik Walthinsen <omega at cse.ogi.edu>
- * 2000,2005 Wim Taymans <wim at fluendo.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-dtmfsrc
- * @short_description: Generates DTMF packets
- *
- * <refsect2>
- *
- * <para>
- * The DTMFSrc element generates DTMF (ITU-T Q.23 Specification) tone packets on request
- * from application. The application communicates the beginning and end of a
- * DTMF event using custom upstream gstreamer events. To report a DTMF event, an
- * application must send an event of type GST_EVENT_CUSTOM_UPSTREAM, having a
- * structure of name "dtmf-event" with fields set according to the following
- * table:
- * </para>
- *
- * <para>
- * <informaltable>
- * <tgroup cols='4'>
- * <colspec colname='Name' />
- * <colspec colname='Type' />
- * <colspec colname='Possible values' />
- * <colspec colname='Purpose' />
- *
- * <thead>
- * <row>
- * <entry>Name</entry>
- * <entry>GType</entry>
- * <entry>Possible values</entry>
- * <entry>Purpose</entry>
- * </row>
- * </thead>
- *
- * <tbody>
- * <row>
- * <entry>type</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>0-1</entry>
- * <entry>The application uses this field to specify which of the two methods
- * specified in RFC 2833 to use. The value should be 0 for tones and 1 for
- * named events. Tones are specified by their frequencies and events are specied
- * by their number. This element can only take events as input. Do not confuse
- * with "method" which specified the output.
- * </entry>
- * </row>
- * <row>
- * <entry>number</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>0-16</entry>
- * <entry>The event number.</entry>
- * </row>
- * <row>
- * <entry>volume</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>0-36</entry>
- * <entry>This field describes the power level of the tone, expressed in dBm0
- * after dropping the sign. Power levels range from 0 to -63 dBm0. The range of
- * valid DTMF is from 0 to -36 dBm0. Can be omitted if start is set to FALSE.
- * </entry>
- * </row>
- * <row>
- * <entry>start</entry>
- * <entry>G_TYPE_BOOLEAN</entry>
- * <entry>True or False</entry>
- * <entry>Whether the event is starting or ending.</entry>
- * </row>
- * <row>
- * <entry>method</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>2</entry>
- * <entry>The method used for sending event, this element will react if this
- * field is absent or 2.
- * </entry>
- * </row>
- * </tbody>
- * </tgroup>
- * </informaltable>
- * </para>
- *
- * <para>For example, the following code informs the pipeline (and in turn, the
- * DTMFSrc element inside the pipeline) about the start of a DTMF named
- * event '1' of volume -25 dBm0:
- * </para>
- *
- * <para>
- * <programlisting>
- * structure = gst_structure_new ("dtmf-event",
- * "type", G_TYPE_INT, 1,
- * "number", G_TYPE_INT, 1,
- * "volume", G_TYPE_INT, 25,
- * "start", G_TYPE_BOOLEAN, TRUE, NULL);
- *
- * event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, structure);
- * gst_element_send_event (pipeline, event);
- * </programlisting>
- * </para>
- *
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include <glib.h>
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846 /* pi */
-#endif
-
-
-#include "gstdtmfsrc.h"
-
-#define GST_TONE_DTMF_TYPE_EVENT 1
-#define DEFAULT_PACKET_INTERVAL 50 /* ms */
-#define MIN_PACKET_INTERVAL 10 /* ms */
-#define MAX_PACKET_INTERVAL 50 /* ms */
-#define DEFAULT_SAMPLE_RATE 8000
-#define SAMPLE_SIZE 16
-#define CHANNELS 1
-#define MIN_EVENT 0
-#define MAX_EVENT 16
-#define MIN_VOLUME 0
-#define MAX_VOLUME 36
-#define MIN_INTER_DIGIT_INTERVAL 100
-#define MIN_PULSE_DURATION 250
-#define MIN_DUTY_CYCLE (MIN_INTER_DIGIT_INTERVAL + MIN_PULSE_DURATION)
-
-
-typedef struct st_dtmf_key {
- char *event_name;
- int event_encoding;
- float low_frequency;
- float high_frequency;
-} DTMF_KEY;
-
-static const DTMF_KEY DTMF_KEYS[] = {
- {"DTMF_KEY_EVENT_0", 0, 941, 1336},
- {"DTMF_KEY_EVENT_1", 1, 697, 1209},
- {"DTMF_KEY_EVENT_2", 2, 697, 1336},
- {"DTMF_KEY_EVENT_3", 3, 697, 1477},
- {"DTMF_KEY_EVENT_4", 4, 770, 1209},
- {"DTMF_KEY_EVENT_5", 5, 770, 1336},
- {"DTMF_KEY_EVENT_6", 6, 770, 1477},
- {"DTMF_KEY_EVENT_7", 7, 852, 1209},
- {"DTMF_KEY_EVENT_8", 8, 852, 1336},
- {"DTMF_KEY_EVENT_9", 9, 852, 1477},
- {"DTMF_KEY_EVENT_S", 10, 941, 1209},
- {"DTMF_KEY_EVENT_P", 11, 941, 1477},
- {"DTMF_KEY_EVENT_A", 12, 697, 1633},
- {"DTMF_KEY_EVENT_B", 13, 770, 1633},
- {"DTMF_KEY_EVENT_C", 14, 852, 1633},
- {"DTMF_KEY_EVENT_D", 15, 941, 1633},
-};
-
-#define MAX_DTMF_EVENTS 16
-
-enum {
-DTMF_KEY_EVENT_1 = 1,
-DTMF_KEY_EVENT_2 = 2,
-DTMF_KEY_EVENT_3 = 3,
-DTMF_KEY_EVENT_4 = 4,
-DTMF_KEY_EVENT_5 = 5,
-DTMF_KEY_EVENT_6 = 6,
-DTMF_KEY_EVENT_7 = 7,
-DTMF_KEY_EVENT_8 = 8,
-DTMF_KEY_EVENT_9 = 9,
-DTMF_KEY_EVENT_0 = 0,
-DTMF_KEY_EVENT_STAR = 10,
-DTMF_KEY_EVENT_POUND = 11,
-DTMF_KEY_EVENT_A = 12,
-DTMF_KEY_EVENT_B = 13,
-DTMF_KEY_EVENT_C = 14,
-DTMF_KEY_EVENT_D = 15,
-};
-
-/* elementfactory information */
-static const GstElementDetails gst_dtmf_src_details =
-GST_ELEMENT_DETAILS ("DTMF tone generator",
- "Source/Audio",
- "Generates DTMF tones",
- "Youness Alaoui <youness.alaoui at collabora.co.uk>");
-
-GST_DEBUG_CATEGORY_STATIC (gst_dtmf_src_debug);
-#define GST_CAT_DEFAULT gst_dtmf_src_debug
-
-enum
-{
- PROP_0,
- PROP_INTERVAL,
-};
-
-static GstStaticPadTemplate gst_dtmf_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
- "signed = (bool) true, "
- "rate = (int) 8000, "
- "channels = (int) 1")
- );
-
-GST_BOILERPLATE (GstDTMFSrc, gst_dtmf_src, GstBaseSrc, GST_TYPE_BASE_SRC);
-
-static void gst_dtmf_src_finalize (GObject * object);
-
-static void gst_dtmf_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_dtmf_src_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static gboolean gst_dtmf_src_handle_event (GstBaseSrc *src, GstEvent * event);
-static GstStateChangeReturn gst_dtmf_src_change_state (GstElement * element,
- GstStateChange transition);
-static GstFlowReturn gst_dtmf_src_create (GstBaseSrc * basesrc,
- guint64 offset, guint length, GstBuffer ** buffer);
-static void gst_dtmf_src_add_start_event (GstDTMFSrc *dtmfsrc,
- gint event_number, gint event_volume);
-static void gst_dtmf_src_add_stop_event (GstDTMFSrc *dtmfsrc);
-
-static gboolean gst_dtmf_src_unlock (GstBaseSrc *src);
-
-static gboolean gst_dtmf_src_unlock_stop (GstBaseSrc *src);
-static gboolean gst_dtmf_src_negotiate (GstBaseSrc * basesrc);
-
-static void
-gst_dtmf_src_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- GST_DEBUG_CATEGORY_INIT (gst_dtmf_src_debug,
- "dtmfsrc", 0, "dtmfsrc element");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_dtmf_src_template));
-
- gst_element_class_set_details (element_class, &gst_dtmf_src_details);
-}
-
-static void
-gst_dtmf_src_class_init (GstDTMFSrcClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseSrcClass *gstbasesrc_class;
- GstElementClass *gstelement_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
- gstelement_class = GST_ELEMENT_CLASS (klass);
-
-
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_dtmf_src_finalize);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_get_property);
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INTERVAL,
- g_param_spec_uint ("interval", "Interval between tone packets",
- "Interval in ms between two tone packets", MIN_PACKET_INTERVAL,
- MAX_PACKET_INTERVAL, DEFAULT_PACKET_INTERVAL, G_PARAM_READWRITE));
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_change_state);
- gstbasesrc_class->unlock =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_unlock);
- gstbasesrc_class->unlock_stop =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_unlock_stop);
-
- gstbasesrc_class->event =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_handle_event);
- gstbasesrc_class->create =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_create);
- gstbasesrc_class->negotiate =
- GST_DEBUG_FUNCPTR (gst_dtmf_src_negotiate);
-}
-
-
-static void
-gst_dtmf_src_init (GstDTMFSrc * dtmfsrc, GstDTMFSrcClass *g_class)
-{
- /* we operate in time */
- gst_base_src_set_format (GST_BASE_SRC (dtmfsrc), GST_FORMAT_TIME);
- gst_base_src_set_live (GST_BASE_SRC (dtmfsrc), TRUE);
-
- dtmfsrc->interval = DEFAULT_PACKET_INTERVAL;
-
- dtmfsrc->event_queue = g_async_queue_new ();
- dtmfsrc->last_event = NULL;
-
- dtmfsrc->sample_rate = DEFAULT_SAMPLE_RATE;
-
- GST_DEBUG_OBJECT (dtmfsrc, "init done");
-}
-
-static void
-gst_dtmf_src_finalize (GObject * object)
-{
- GstDTMFSrc *dtmfsrc;
-
- dtmfsrc = GST_DTMF_SRC (object);
-
- if (dtmfsrc->event_queue) {
- g_async_queue_unref (dtmfsrc->event_queue);
- dtmfsrc->event_queue = NULL;
- }
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static gboolean
-gst_dtmf_src_handle_dtmf_event (GstDTMFSrc *dtmfsrc,
- const GstStructure * event_structure)
-{
- gint event_type;
- gboolean start;
- gint method;
-
- if (!gst_structure_get_int (event_structure, "type", &event_type) ||
- !gst_structure_get_boolean (event_structure, "start", &start) ||
- (start == TRUE && event_type != GST_TONE_DTMF_TYPE_EVENT))
- goto failure;
-
- if (gst_structure_get_int (event_structure, "method", &method)) {
- if (method != 2) {
- goto failure;
- }
- }
-
- if (start) {
- gint event_number;
- gint event_volume;
-
- if (!gst_structure_get_int (event_structure, "number", &event_number) ||
- !gst_structure_get_int (event_structure, "volume", &event_volume))
- goto failure;
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d",
- event_number, event_volume);
- gst_dtmf_src_add_start_event (dtmfsrc, event_number, event_volume);
- }
-
- else {
- GST_DEBUG_OBJECT (dtmfsrc, "Received stop event");
- gst_dtmf_src_add_stop_event (dtmfsrc);
- }
-
- return TRUE;
-failure:
- return FALSE;
-}
-
-static gboolean
-gst_dtmf_src_handle_custom_upstream (GstDTMFSrc *dtmfsrc,
- GstEvent * event)
-{
- gboolean result = FALSE;
- const GstStructure *structure;
- GstState state;
- GstStateChangeReturn ret;
-
- ret = gst_element_get_state (GST_ELEMENT (dtmfsrc), &state, NULL, 0);
- if (ret != GST_STATE_CHANGE_SUCCESS || state != GST_STATE_PLAYING) {
- GST_DEBUG_OBJECT (dtmfsrc, "Received event while not in PLAYING state");
- goto ret;
- }
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received event is of our interest");
- structure = gst_event_get_structure (event);
- if (structure && gst_structure_has_name (structure, "dtmf-event"))
- result = gst_dtmf_src_handle_dtmf_event (dtmfsrc, structure);
-
-ret:
- return result;
-}
-
-static gboolean
-gst_dtmf_src_handle_event (GstBaseSrc * src, GstEvent * event)
-{
- GstDTMFSrc *dtmfsrc;
- gboolean result = FALSE;
-
- dtmfsrc = GST_DTMF_SRC (src);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received an event on the src pad");
- if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UPSTREAM) {
- result = gst_dtmf_src_handle_custom_upstream (dtmfsrc, event);
- }
-
- return result;
-}
-
-static void
-gst_dtmf_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstDTMFSrc *dtmfsrc;
-
- dtmfsrc = GST_DTMF_SRC (object);
-
- switch (prop_id) {
- case PROP_INTERVAL:
- dtmfsrc->interval = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_dtmf_src_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstDTMFSrc *dtmfsrc;
-
- dtmfsrc = GST_DTMF_SRC (object);
-
- switch (prop_id) {
- case PROP_INTERVAL:
- g_value_set_uint (value, dtmfsrc->interval);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_dtmf_src_set_stream_lock (GstDTMFSrc *dtmfsrc, gboolean lock)
-{
- GstPad *srcpad = GST_BASE_SRC_PAD (dtmfsrc);
- GstEvent *event;
- GstStructure *structure;
-
- structure = gst_structure_new ("stream-lock",
- "lock", G_TYPE_BOOLEAN, lock, NULL);
-
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, structure);
- if (!gst_pad_push_event (srcpad, event)) {
- GST_WARNING_OBJECT (dtmfsrc, "stream-lock event not handled");
- }
-}
-
-static void
-gst_dtmf_prepare_timestamps (GstDTMFSrc *dtmfsrc)
-{
- GstClock *clock;
- GstClockTime base_time;
-
- base_time = gst_element_get_base_time (GST_ELEMENT (dtmfsrc));
-
- clock = gst_element_get_clock (GST_ELEMENT (dtmfsrc));
- if (clock != NULL) {
-#ifdef MAEMO_BROKEN
- dtmfsrc->timestamp = gst_clock_get_time (clock);
-#else
- dtmfsrc->timestamp = gst_clock_get_time (clock) - base_time;
-#endif
- gst_object_unref (clock);
- } else {
- gchar *dtmf_name = gst_element_get_name (dtmfsrc);
- GST_ERROR_OBJECT (dtmfsrc, "No clock set for element %s", dtmf_name);
- dtmfsrc->timestamp = GST_CLOCK_TIME_NONE;
- g_free (dtmf_name);
- }
-}
-
-static void
-gst_dtmf_src_add_start_event (GstDTMFSrc *dtmfsrc, gint event_number,
- gint event_volume)
-{
-
- GstDTMFSrcEvent * event = g_malloc (sizeof(GstDTMFSrcEvent));
- event->event_type = DTMF_EVENT_TYPE_START;
- event->sample = 0;
- event->event_number = CLAMP (event_number, MIN_EVENT, MAX_EVENT);
- event->volume = CLAMP (event_volume, MIN_VOLUME, MAX_VOLUME);
-
- g_async_queue_push (dtmfsrc->event_queue, event);
-}
-
-static void
-gst_dtmf_src_add_stop_event (GstDTMFSrc *dtmfsrc)
-{
-
- GstDTMFSrcEvent * event = g_malloc (sizeof(GstDTMFSrcEvent));
- event->event_type = DTMF_EVENT_TYPE_STOP;
- event->sample = 0;
- event->event_number = 0;
- event->volume = 0;
-
- g_async_queue_push (dtmfsrc->event_queue, event);
-}
-
-static void
-gst_dtmf_src_generate_silence(GstBuffer * buffer, float duration,
- gint sample_rate)
-{
- gint buf_size;
-
- /* Create a buffer with data set to 0 */
- buf_size = ((duration/1000)*sample_rate*SAMPLE_SIZE*CHANNELS)/8;
- GST_BUFFER_SIZE (buffer) = buf_size;
- GST_BUFFER_MALLOCDATA (buffer) = g_malloc0(buf_size);
- GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
-
-}
-
-static void
-gst_dtmf_src_generate_tone(GstDTMFSrcEvent *event, DTMF_KEY key, float duration,
- GstBuffer * buffer, gint sample_rate)
-{
- gint16 *p;
- gint tone_size;
- double i = 0;
- double amplitude, f1, f2;
- double volume_factor;
-
- /* Create a buffer for the tone */
- tone_size = ((duration/1000)*sample_rate*SAMPLE_SIZE*CHANNELS)/8;
- GST_BUFFER_SIZE (buffer) = tone_size;
- GST_BUFFER_MALLOCDATA (buffer) = g_malloc(tone_size);
- GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
-
- p = (gint16 *) GST_BUFFER_MALLOCDATA (buffer);
-
- volume_factor = pow (10, (-event->volume) / 20);
-
- /*
- * For each sample point we calculate 'x' as the
- * the amplitude value.
- */
- for (i = 0; i < (tone_size / (SAMPLE_SIZE/8)); i++) {
- /*
- * We add the fundamental frequencies together.
- */
- f1 = sin(2 * M_PI * key.low_frequency * (event->sample / sample_rate));
- f2 = sin(2 * M_PI * key.high_frequency * (event->sample / sample_rate));
-
- amplitude = (f1 + f2) / 2;
-
- /* Adjust the volume */
- amplitude *= volume_factor;
-
- /* Make the [-1:1] interval into a [-32767:32767] interval */
- amplitude *= 32767;
-
- /* Store it in the data buffer */
- *(p++) = (gint16) amplitude;
-
- (event->sample)++;
- }
-}
-
-
-
-static GstBuffer *
-gst_dtmf_src_create_next_tone_packet (GstDTMFSrc *dtmfsrc,
- GstDTMFSrcEvent *event)
-{
- GstBuffer *buf = NULL;
- gboolean send_silence = FALSE;
- GstPad *srcpad = GST_BASE_SRC_PAD (dtmfsrc);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Creating buffer for tone %s",
- DTMF_KEYS[event->event_number].event_name);
-
- /* create buffer to hold the tone */
- buf = gst_buffer_new ();
-
- if (event->packet_count * dtmfsrc->interval < MIN_INTER_DIGIT_INTERVAL) {
- send_silence = TRUE;
- }
-
- if (send_silence) {
- GST_DEBUG_OBJECT (dtmfsrc, "Generating silence");
- gst_dtmf_src_generate_silence (buf, dtmfsrc->interval,
- dtmfsrc->sample_rate);
- } else {
- GST_DEBUG_OBJECT (dtmfsrc, "Generating tone");
- gst_dtmf_src_generate_tone(event, DTMF_KEYS[event->event_number],
- dtmfsrc->interval, buf, dtmfsrc->sample_rate);
- }
- event->packet_count++;
-
-
- /* timestamp and duration of GstBuffer */
- GST_BUFFER_DURATION (buf) = dtmfsrc->interval * GST_MSECOND;
- GST_BUFFER_TIMESTAMP (buf) = dtmfsrc->timestamp;
- dtmfsrc->timestamp += GST_BUFFER_DURATION (buf);
-
- /* Set caps on the buffer before pushing it */
- gst_buffer_set_caps (buf, GST_PAD_CAPS (srcpad));
-
- return buf;
-}
-
-static GstFlowReturn
-gst_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset,
- guint length, GstBuffer ** buffer)
-{
- GstBuffer *buf = NULL;
- GstDTMFSrcEvent *event;
- GstDTMFSrc * dtmfsrc;
- GstClock *clock;
- GstClockID *clockid;
- GstClockReturn clockret;
-
- dtmfsrc = GST_DTMF_SRC (basesrc);
-
- do {
-
- if (dtmfsrc->last_event == NULL) {
- GST_DEBUG_OBJECT (dtmfsrc, "popping");
- event = g_async_queue_pop (dtmfsrc->event_queue);
-
- GST_DEBUG_OBJECT (dtmfsrc, "popped %d", event->event_type);
-
- switch (event->event_type) {
- case DTMF_EVENT_TYPE_STOP:
- GST_WARNING_OBJECT (dtmfsrc,
- "Received a DTMF stop event when already stopped");
- break;
- case DTMF_EVENT_TYPE_START:
- gst_dtmf_prepare_timestamps (dtmfsrc);
-
- /* Don't forget to get exclusive access to the stream */
- gst_dtmf_src_set_stream_lock (dtmfsrc, TRUE);
-
- event->packet_count = 0;
- dtmfsrc->last_event = event;
- event = NULL;
- break;
- case DTMF_EVENT_TYPE_PAUSE_TASK:
- /*
- * We're pushing it back because it has to stay in there until
- * the task is really paused (and the queue will then be flushed)
- */
- GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
- GST_OBJECT_LOCK (dtmfsrc);
- if (dtmfsrc->paused) {
- g_async_queue_push (dtmfsrc->event_queue, event);
- goto paused_locked;
- }
- GST_OBJECT_UNLOCK (dtmfsrc);
- break;
- }
- if (event)
- g_free (event);
- } else if (dtmfsrc->last_event->packet_count * dtmfsrc->interval >=
- MIN_DUTY_CYCLE) {
- event = g_async_queue_try_pop (dtmfsrc->event_queue);
-
- if (event != NULL) {
-
- switch (event->event_type) {
- case DTMF_EVENT_TYPE_START:
- GST_WARNING_OBJECT (dtmfsrc,
- "Received two consecutive DTMF start events");
- break;
- case DTMF_EVENT_TYPE_STOP:
- gst_dtmf_src_set_stream_lock (dtmfsrc, FALSE);
-
- g_free (dtmfsrc->last_event);
- dtmfsrc->last_event = NULL;
- break;
- case DTMF_EVENT_TYPE_PAUSE_TASK:
- /*
- * We're pushing it back because it has to stay in there until
- * the task is really paused (and the queue will then be flushed)
- */
- GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
-
- GST_OBJECT_LOCK (dtmfsrc);
- if (dtmfsrc->paused) {
- g_async_queue_push (dtmfsrc->event_queue, event);
- goto paused_locked;
- }
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- break;
- }
- g_free (event);
- }
- }
- } while (dtmfsrc->last_event == NULL);
-
- GST_DEBUG_OBJECT (dtmfsrc, "end event check, now wait for the proper time");
-
- clock = gst_element_get_clock (GST_ELEMENT (basesrc));
-
-#ifdef MAEMO_BROKEN
- clockid = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp);
-#else
- clockid = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp +
- gst_element_get_base_time (GST_ELEMENT (dtmfsrc)));
-#endif
- gst_object_unref (clock);
-
- GST_OBJECT_LOCK (dtmfsrc);
- if (!dtmfsrc->paused) {
- dtmfsrc->clockid = clockid;
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- clockret = gst_clock_id_wait (clockid, NULL);
-
- GST_OBJECT_LOCK (dtmfsrc);
- if (dtmfsrc->paused)
- clockret = GST_CLOCK_UNSCHEDULED;
- } else {
- clockret = GST_CLOCK_UNSCHEDULED;
- }
- gst_clock_id_unref (clockid);
- dtmfsrc->clockid = NULL;
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- if (clockret == GST_CLOCK_UNSCHEDULED) {
- goto paused;
- }
-
- buf = gst_dtmf_src_create_next_tone_packet (dtmfsrc, dtmfsrc->last_event);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Created buffer of size %d", GST_BUFFER_SIZE (buf));
- *buffer = buf;
-
- GST_DEBUG_OBJECT (dtmfsrc, "returning a buffer");
- return GST_FLOW_OK;
-
- paused_locked:
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- paused:
-
- if (dtmfsrc->last_event) {
- GST_DEBUG_OBJECT (dtmfsrc, "Stopping current event");
- /* Don't forget to release the stream lock */
- gst_dtmf_src_set_stream_lock (dtmfsrc, FALSE);
- g_free (dtmfsrc->last_event);
- dtmfsrc->last_event = NULL;
- }
-
- return GST_FLOW_WRONG_STATE;
-
-}
-
-static gboolean
-gst_dtmf_src_unlock (GstBaseSrc *src) {
- GstDTMFSrc *dtmfsrc = GST_DTMF_SRC (src);
- GstDTMFSrcEvent *event = NULL;
-
- GST_DEBUG_OBJECT (dtmfsrc, "Called unlock");
-
- GST_OBJECT_LOCK (dtmfsrc);
- dtmfsrc->paused = TRUE;
- if (dtmfsrc->clockid) {
- gst_clock_id_unschedule (dtmfsrc->clockid);
- }
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Pushing the PAUSE_TASK event on unlock request");
- event = g_malloc (sizeof(GstDTMFSrcEvent));
- event->event_type = DTMF_EVENT_TYPE_PAUSE_TASK;
- g_async_queue_push (dtmfsrc->event_queue, event);
-
- return TRUE;
-}
-
-
-static gboolean
-gst_dtmf_src_unlock_stop (GstBaseSrc *src) {
- GstDTMFSrc *dtmfsrc = GST_DTMF_SRC (src);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Unlock stopped");
-
- GST_OBJECT_LOCK (dtmfsrc);
- dtmfsrc->paused = FALSE;
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- return TRUE;
-}
-
-
-static gboolean
-gst_dtmf_src_negotiate (GstBaseSrc * basesrc)
-{
- GstCaps *srccaps, *peercaps;
- GstDTMFSrc *dtmfsrc = GST_DTMF_SRC (basesrc);
- gboolean ret = FALSE;
-
- srccaps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE,
- "channels", G_TYPE_INT, 1,
- NULL);
-
- peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
-
- if (peercaps == NULL) {
- /* no peer caps, just add the other properties */
- gst_caps_set_simple (srccaps,
- "rate", G_TYPE_INT, dtmfsrc->sample_rate,
- NULL);
- } else {
- GstStructure *s;
- gint sample_rate;
- GstCaps *temp = NULL;
-
- /* peer provides caps we can use to fixate, intersect. This always returns a
- * writable caps. */
- temp = gst_caps_intersect (srccaps, peercaps);
- gst_caps_unref (srccaps);
- gst_caps_unref (peercaps);
-
- if (!temp) {
- GST_DEBUG_OBJECT (dtmfsrc, "Could not get intersection with peer caps");
- return FALSE;
- }
-
- if (gst_caps_is_empty (temp)) {
- GST_DEBUG_OBJECT (dtmfsrc, "Intersection with peer caps is empty");
- gst_caps_unref (temp);
- return FALSE;
- }
-
- /* now fixate, start by taking the first caps */
- gst_caps_truncate (temp);
- srccaps = temp;
-
- /* get first structure */
- s = gst_caps_get_structure (srccaps, 0);
-
- if (gst_structure_get_int (s, "rate", &sample_rate))
- {
- dtmfsrc->sample_rate = sample_rate;
- GST_LOG_OBJECT (dtmfsrc, "using rate from caps %d",
- dtmfsrc->sample_rate);
- } else {
- GST_LOG_OBJECT (dtmfsrc, "using existing rate %d",
- dtmfsrc->sample_rate);
- }
- gst_structure_set (s, "rate", G_TYPE_INT, dtmfsrc->sample_rate,
- NULL);
- }
-
- ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), srccaps);
-
- gst_caps_unref (srccaps);
-
- return ret;
-}
-
-static GstStateChangeReturn
-gst_dtmf_src_change_state (GstElement * element, GstStateChange transition)
-{
- GstDTMFSrc *dtmfsrc;
- GstStateChangeReturn result;
- gboolean no_preroll = FALSE;
- GstDTMFSrcEvent *event = NULL;
-
- dtmfsrc = GST_DTMF_SRC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- /* Flushing the event queue */
- event = g_async_queue_try_pop (dtmfsrc->event_queue);
-
- while (event != NULL) {
- g_free (event);
- event = g_async_queue_try_pop (dtmfsrc->event_queue);
- }
- no_preroll = TRUE;
- break;
- default:
- break;
- }
-
- if ((result =
- GST_ELEMENT_CLASS (parent_class)->change_state (element,
- transition)) == GST_STATE_CHANGE_FAILURE)
- goto failure;
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- no_preroll = TRUE;
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- GST_DEBUG_OBJECT (dtmfsrc, "Flushing event queue");
- /* Flushing the event queue */
- event = g_async_queue_try_pop (dtmfsrc->event_queue);
-
- while (event != NULL) {
- g_free (event);
- event = g_async_queue_try_pop (dtmfsrc->event_queue);
- }
-
- break;
- default:
- break;
- }
-
- if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
- result = GST_STATE_CHANGE_NO_PREROLL;
-
- return result;
-
- /* ERRORS */
-failure:
- {
- GST_ERROR_OBJECT (dtmfsrc, "parent failed state change");
- return result;
- }
-}
-
-gboolean
-gst_dtmf_src_plugin_init (GstPlugin * plugin)
-{
- return gst_element_register (plugin, "dtmfsrc",
- GST_RANK_NONE, GST_TYPE_DTMF_SRC);
-}
-
diff --git a/gst/dtmf/gstdtmfsrc.h b/gst/dtmf/gstdtmfsrc.h
deleted file mode 100644
index fdf6f50..0000000
--- a/gst/dtmf/gstdtmfsrc.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* GStreamer DTMF source
- *
- * gstdtmfsrc.h:
- *
- * Copyright (C) <2007> Collabora.
- * Contact: Youness Alaoui <youness.alaoui at collabora.co.uk>
- * Copyright (C) <2007> Nokia Corporation.
- * Contact: Zeeshan Ali <zeeshan.ali at nokia.com>
- * Copyright (C) <2005> Wim Taymans <wim at fluendo.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_DTMF_SRC_H__
-#define __GST_DTMF_SRC_H__
-
-#include <gst/gst.h>
-#include <gst/gstbuffer.h>
-#include <gst/base/gstbasesrc.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_DTMF_SRC (gst_dtmf_src_get_type())
-#define GST_DTMF_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DTMF_SRC,GstDTMFSrc))
-#define GST_DTMF_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DTMF_SRC,GstDTMFSrcClass))
-#define GST_DTMF_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DTMF_SRC, GstDTMFSrcClass))
-#define GST_IS_DTMF_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DTMF_SRC))
-#define GST_IS_DTMF_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DTMF_SRC))
-#define GST_DTMF_SRC_CAST(obj) ((GstDTMFSrc *)(obj))
-
-typedef struct _GstDTMFSrc GstDTMFSrc;
-typedef struct _GstDTMFSrcClass GstDTMFSrcClass;
-
-/**
- * GstDTMFSrc:
- * @element: the parent element.
- *
- * The opaque #GstDTMFSrc data structure.
- */
-
-enum _GstDTMFEventType {
- DTMF_EVENT_TYPE_START,
- DTMF_EVENT_TYPE_STOP,
- DTMF_EVENT_TYPE_PAUSE_TASK
-};
-
-typedef enum _GstDTMFEventType GstDTMFEventType;
-
-struct _GstDTMFSrcEvent {
- GstDTMFEventType event_type;
- double sample;
- guint16 event_number;
- guint16 volume;
- guint32 packet_count;
-};
-
-typedef struct _GstDTMFSrcEvent GstDTMFSrcEvent;
-
-struct _GstDTMFSrc {
- GstBaseSrc parent;
- GAsyncQueue* event_queue;
- GstDTMFSrcEvent* last_event;
-
- guint16 interval;
- GstClockTime timestamp;
-
- gboolean paused;
- GstClockID clockid;
-
- gint sample_rate;
-};
-
-
-struct _GstDTMFSrcClass {
- GstBaseSrcClass parent_class;
-};
-
-GType gst_dtmf_src_get_type (void);
-
-gboolean gst_dtmf_src_plugin_init (GstPlugin * plugin);
-
-G_END_DECLS
-
-#endif /* __GST_DTMF_SRC_H__ */
diff --git a/gst/dtmf/gstrtpdtmfcommon.h b/gst/dtmf/gstrtpdtmfcommon.h
deleted file mode 100644
index 097afa9..0000000
--- a/gst/dtmf/gstrtpdtmfcommon.h
+++ /dev/null
@@ -1,22 +0,0 @@
-
-#ifndef __GST_RTP_DTMF_COMMON_H__
-#define __GST_RTP_DTMF_COMMON_H__
-
-
-typedef struct {
- unsigned event:8; /* Current DTMF event */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- unsigned volume:6; /* power level of the tone, in dBm0 */
- unsigned r:1; /* Reserved-bit */
- unsigned e:1; /* End-bit */
-#elif G_BYTE_ORDER == G_BIG_ENDIAN
- unsigned e:1; /* End-bit */
- unsigned r:1; /* Reserved-bit */
- unsigned volume:6; /* power level of the tone, in dBm0 */
-#else
-#error "G_BYTE_ORDER should be big or little endian."
-#endif
- unsigned duration:16; /* Duration of digit, in timestamp units */
-} GstRTPDTMFPayload;
-
-#endif /* __GST_RTP_DTMF_COMMON_H__ */
diff --git a/gst/dtmf/gstrtpdtmfdepay.c b/gst/dtmf/gstrtpdtmfdepay.c
deleted file mode 100644
index 2032189..0000000
--- a/gst/dtmf/gstrtpdtmfdepay.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/* GstRtpDtmfDepay
- *
- * Copyright (C) 2008 Collabora Limited
- * Copyright (C) 2008 Nokia Corporation
- * Contact: Youness Alaoui <youness.alaoui at collabora.co.uk>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; 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 <string.h>
-#include <math.h>
-
-#include <gst/rtp/gstrtpbuffer.h>
-#include "gstrtpdtmfdepay.h"
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846 /* pi */
-#endif
-
-
-#define DEFAULT_PACKET_INTERVAL 50 /* ms */
-#define MIN_PACKET_INTERVAL 10 /* ms */
-#define MAX_PACKET_INTERVAL 50 /* ms */
-#define SAMPLE_RATE 8000
-#define SAMPLE_SIZE 16
-#define CHANNELS 1
-#define MIN_EVENT 0
-#define MAX_EVENT 16
-#define MIN_VOLUME 0
-#define MAX_VOLUME 36
-#define MIN_INTER_DIGIT_INTERVAL 100
-#define MIN_PULSE_DURATION 250
-#define MIN_DUTY_CYCLE (MIN_INTER_DIGIT_INTERVAL + MIN_PULSE_DURATION)
-
-#define MIN_UNIT_TIME 0
-#define MAX_UNIT_TIME 1000
-#define DEFAULT_UNIT_TIME 0
-
-#define DEFAULT_MAX_DURATION 0
-
-typedef struct st_dtmf_key {
- char *event_name;
- int event_encoding;
- float low_frequency;
- float high_frequency;
-} DTMF_KEY;
-
-static const DTMF_KEY DTMF_KEYS[] = {
- {"DTMF_KEY_EVENT_0", 0, 941, 1336},
- {"DTMF_KEY_EVENT_1", 1, 697, 1209},
- {"DTMF_KEY_EVENT_2", 2, 697, 1336},
- {"DTMF_KEY_EVENT_3", 3, 697, 1477},
- {"DTMF_KEY_EVENT_4", 4, 770, 1209},
- {"DTMF_KEY_EVENT_5", 5, 770, 1336},
- {"DTMF_KEY_EVENT_6", 6, 770, 1477},
- {"DTMF_KEY_EVENT_7", 7, 852, 1209},
- {"DTMF_KEY_EVENT_8", 8, 852, 1336},
- {"DTMF_KEY_EVENT_9", 9, 852, 1477},
- {"DTMF_KEY_EVENT_S", 10, 941, 1209},
- {"DTMF_KEY_EVENT_P", 11, 941, 1477},
- {"DTMF_KEY_EVENT_A", 12, 697, 1633},
- {"DTMF_KEY_EVENT_B", 13, 770, 1633},
- {"DTMF_KEY_EVENT_C", 14, 852, 1633},
- {"DTMF_KEY_EVENT_D", 15, 941, 1633},
-};
-
-#define MAX_DTMF_EVENTS 16
-
-enum {
-DTMF_KEY_EVENT_1 = 1,
-DTMF_KEY_EVENT_2 = 2,
-DTMF_KEY_EVENT_3 = 3,
-DTMF_KEY_EVENT_4 = 4,
-DTMF_KEY_EVENT_5 = 5,
-DTMF_KEY_EVENT_6 = 6,
-DTMF_KEY_EVENT_7 = 7,
-DTMF_KEY_EVENT_8 = 8,
-DTMF_KEY_EVENT_9 = 9,
-DTMF_KEY_EVENT_0 = 0,
-DTMF_KEY_EVENT_STAR = 10,
-DTMF_KEY_EVENT_POUND = 11,
-DTMF_KEY_EVENT_A = 12,
-DTMF_KEY_EVENT_B = 13,
-DTMF_KEY_EVENT_C = 14,
-DTMF_KEY_EVENT_D = 15,
-};
-
-/* elementfactory information */
-static const GstElementDetails gst_rtp_dtmfdepay_details =
-GST_ELEMENT_DETAILS ("RTP DTMF packet depayloader",
- "Codec/Depayloader/Network",
- "Generates DTMF Sound from telephone-event RTP packets",
- "Youness Alaoui <youness.alaoui at collabora.co.uk>");
-
-GST_DEBUG_CATEGORY_STATIC (gst_rtp_dtmf_depay_debug);
-#define GST_CAT_DEFAULT gst_rtp_dtmf_depay_debug
-
-enum
-{
-
-
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_UNIT_TIME,
- PROP_MAX_DURATION
-};
-
-enum
-{
- ARG_0
-};
-
-static GstStaticPadTemplate gst_rtp_dtmf_depay_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
- "signed = (boolean) true, "
- "rate = (int) [0, MAX], "
- "channels = (int) 1")
- );
-
-static GstStaticPadTemplate gst_rtp_dtmf_depay_sink_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp, "
- "media = (string) \"audio\", "
- "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
- "clock-rate = (int) [ 0, MAX ], "
- "encoding-name = (string) \"TELEPHONE-EVENT\"")
- );
-
-GST_BOILERPLATE (GstRtpDTMFDepay, gst_rtp_dtmf_depay, GstBaseRTPDepayload,
- GST_TYPE_BASE_RTP_DEPAYLOAD);
-
-static void gst_rtp_dtmf_depay_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtp_dtmf_depay_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static GstBuffer *gst_rtp_dtmf_depay_process (GstBaseRTPDepayload * depayload,
- GstBuffer * buf);
-gboolean gst_rtp_dtmf_depay_setcaps (GstBaseRTPDepayload * filter,
- GstCaps * caps);
-
-static void
-gst_rtp_dtmf_depay_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_dtmf_depay_src_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_dtmf_depay_sink_template));
-
-
- GST_DEBUG_CATEGORY_INIT (gst_rtp_dtmf_depay_debug,
- "rtpdtmfdepay", 0, "rtpdtmfdepay element");
- gst_element_class_set_details (element_class, &gst_rtp_dtmfdepay_details);
-}
-
-static void
-gst_rtp_dtmf_depay_class_init (GstRtpDTMFDepayClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
- GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
- gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_get_property);
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_UNIT_TIME,
- g_param_spec_uint ("unit-time", "Duration unittime",
- "The smallest unit (ms) the duration must be a multiple of (0 disables it)", MIN_UNIT_TIME,
- MAX_UNIT_TIME, DEFAULT_UNIT_TIME, G_PARAM_READWRITE));
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_DURATION,
- g_param_spec_uint ("max-duration", "Maximum duration",
- "The maxumimum duration (ms) of the outgoing soundpacket. "
- "(0 = no limit)", 0, G_MAXUINT, DEFAULT_MAX_DURATION,
- G_PARAM_READWRITE));
-
- gstbasertpdepayload_class->process =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_process);
- gstbasertpdepayload_class->set_caps =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_setcaps);
-
-}
-
-static void
-gst_rtp_dtmf_depay_init (GstRtpDTMFDepay * rtpdtmfdepay,
- GstRtpDTMFDepayClass * klass)
-{
- rtpdtmfdepay->unit_time = DEFAULT_UNIT_TIME;
-}
-
-static void
-gst_rtp_dtmf_depay_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpDTMFDepay * rtpdtmfdepay;
-
- rtpdtmfdepay = GST_RTP_DTMF_DEPAY (object);
-
- switch (prop_id) {
- case PROP_UNIT_TIME:
- rtpdtmfdepay->unit_time = g_value_get_uint (value);
- break;
- case PROP_MAX_DURATION:
- rtpdtmfdepay->max_duration = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtp_dtmf_depay_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GstRtpDTMFDepay * rtpdtmfdepay;
-
- rtpdtmfdepay = GST_RTP_DTMF_DEPAY (object);
-
- switch (prop_id) {
- case PROP_UNIT_TIME:
- g_value_set_uint (value, rtpdtmfdepay->unit_time);
- break;
- case PROP_MAX_DURATION:
- g_value_set_uint (value, rtpdtmfdepay->max_duration);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-gboolean
-gst_rtp_dtmf_depay_setcaps (GstBaseRTPDepayload * filter, GstCaps * caps)
-{
- GstCaps *srccaps;
- GstStructure *structure = gst_caps_get_structure (caps, 0);
- gint clock_rate = 8000; /* default */
-
- gst_structure_get_int (structure, "clock-rate", &clock_rate);
- filter->clock_rate = clock_rate;
-
- srccaps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "signed", G_TYPE_BOOLEAN, TRUE,
- "channels", G_TYPE_INT, 1,
- "rate", G_TYPE_INT, clock_rate, NULL);
- gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (filter), srccaps);
- gst_caps_unref (srccaps);
-
- return TRUE;
-}
-
-static void
-gst_dtmf_src_generate_tone(GstRtpDTMFDepay *rtpdtmfdepay,
- GstRTPDTMFPayload payload, GstBuffer * buffer)
-{
- gint16 *p;
- gint tone_size;
- double i = 0;
- double amplitude, f1, f2;
- double volume_factor;
- DTMF_KEY key = DTMF_KEYS[payload.event];
- guint32 clock_rate = 8000 /* default */;
- GstBaseRTPDepayload * depayload = GST_BASE_RTP_DEPAYLOAD (rtpdtmfdepay);
- gint volume;
-
- clock_rate = depayload->clock_rate;
-
- /* Create a buffer for the tone */
- tone_size = (payload.duration*SAMPLE_SIZE*CHANNELS)/8;
- GST_BUFFER_SIZE (buffer) = tone_size;
- GST_BUFFER_MALLOCDATA (buffer) = g_malloc(tone_size);
- GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
- GST_BUFFER_DURATION (buffer) = payload.duration * GST_SECOND / clock_rate;
- volume = payload.volume;
-
- p = (gint16 *) GST_BUFFER_MALLOCDATA (buffer);
-
- volume_factor = pow (10, (-volume) / 20);
-
- /*
- * For each sample point we calculate 'x' as the
- * the amplitude value.
- */
- for (i = 0; i < (tone_size / (SAMPLE_SIZE/8)); i++) {
- /*
- * We add the fundamental frequencies together.
- */
- f1 = sin(2 * M_PI * key.low_frequency * (rtpdtmfdepay->sample / clock_rate));
- f2 = sin(2 * M_PI * key.high_frequency * (rtpdtmfdepay->sample / clock_rate));
-
- amplitude = (f1 + f2) / 2;
-
- /* Adjust the volume */
- amplitude *= volume_factor;
-
- /* Make the [-1:1] interval into a [-32767:32767] interval */
- amplitude *= 32767;
-
- /* Store it in the data buffer */
- *(p++) = (gint16) amplitude;
-
- (rtpdtmfdepay->sample)++;
- }
-}
-
-
-static GstBuffer *
-gst_rtp_dtmf_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
-{
-
- GstRtpDTMFDepay *rtpdtmfdepay = NULL;
- GstBuffer *outbuf = NULL;
- gint payload_len;
- guint8 *payload = NULL;
- guint32 timestamp;
- GstRTPDTMFPayload dtmf_payload;
- gboolean marker;
- GstStructure *structure = NULL;
- GstMessage *dtmf_message = NULL;
-
- rtpdtmfdepay = GST_RTP_DTMF_DEPAY (depayload);
-
- if (!gst_rtp_buffer_validate (buf))
- goto bad_packet;
-
- payload_len = gst_rtp_buffer_get_payload_len (buf);
- payload = gst_rtp_buffer_get_payload (buf);
-
- if (payload_len != sizeof(GstRTPDTMFPayload) )
- goto bad_packet;
-
- memcpy (&dtmf_payload, payload, sizeof (GstRTPDTMFPayload));
-
- if (dtmf_payload.event > MAX_EVENT)
- goto bad_packet;
-
-
- marker = gst_rtp_buffer_get_marker (buf);
-
- timestamp = gst_rtp_buffer_get_timestamp (buf);
-
- dtmf_payload.duration = g_ntohs (dtmf_payload.duration);
-
- /* clip to whole units of unit_time */
- if (rtpdtmfdepay->unit_time)
- {
- guint unit_time_clock =
- (rtpdtmfdepay->unit_time * depayload->clock_rate) / 1000;
- if (dtmf_payload.duration % unit_time_clock)
- {
- /* Make sure we don't overflow the duration */
- if (dtmf_payload.duration < G_MAXUINT16 - unit_time_clock)
- dtmf_payload.duration += unit_time_clock -
- (dtmf_payload.duration % unit_time_clock);
- else
- dtmf_payload.duration -= dtmf_payload.duration % unit_time_clock;
- }
- }
-
- /* clip to max duration */
- if (rtpdtmfdepay->max_duration)
- {
- guint max_duration_clock =
- (rtpdtmfdepay->max_duration * depayload->clock_rate) / 1000;
-
- if (max_duration_clock < G_MAXUINT16 &&
- dtmf_payload.duration > max_duration_clock)
- dtmf_payload.duration = max_duration_clock;
- }
-
- GST_DEBUG_OBJECT (depayload, "Received new RTP DTMF packet : "
- "marker=%d - timestamp=%u - event=%d - duration=%d",
- marker, timestamp, dtmf_payload.event, dtmf_payload.duration);
-
- GST_DEBUG_OBJECT (depayload, "Previous information : timestamp=%u - duration=%d",
- rtpdtmfdepay->previous_ts, rtpdtmfdepay->previous_duration);
-
- /* First packet */
- if (marker || rtpdtmfdepay->previous_ts != timestamp) {
- rtpdtmfdepay->sample = 0;
- rtpdtmfdepay->previous_ts = timestamp;
- rtpdtmfdepay->previous_duration = dtmf_payload.duration;
- rtpdtmfdepay->first_gst_ts = GST_BUFFER_TIMESTAMP (buf);
-
- structure = gst_structure_new ("dtmf-event",
- "number", G_TYPE_INT, dtmf_payload.event,
- "volume", G_TYPE_INT, dtmf_payload.volume,
- "type", G_TYPE_INT, 1,
- "method", G_TYPE_INT, 1,
- NULL);
- if (structure) {
- dtmf_message = gst_message_new_element (GST_OBJECT (depayload), structure);
- if (dtmf_message) {
- if (!gst_element_post_message (GST_ELEMENT (depayload), dtmf_message)) {
- GST_ERROR_OBJECT (depayload, "Unable to send dtmf-event message to bus");
- }
- } else {
- GST_ERROR_OBJECT (depayload, "Unable to create dtmf-event message");
- }
- } else {
- GST_ERROR_OBJECT (depayload, "Unable to create dtmf-event structure");
- }
- } else {
- guint16 duration = dtmf_payload.duration;
- dtmf_payload.duration -= rtpdtmfdepay->previous_duration;
- /* If late buffer, ignore */
- if (duration > rtpdtmfdepay->previous_duration)
- rtpdtmfdepay->previous_duration = duration;
- }
-
- GST_DEBUG_OBJECT (depayload, "new previous duration : %d - new duration : %d"
- " - diff : %d - clock rate : %d - timestamp : %llu",
- rtpdtmfdepay->previous_duration, dtmf_payload.duration,
- (rtpdtmfdepay->previous_duration - dtmf_payload.duration),
- depayload->clock_rate, GST_BUFFER_TIMESTAMP (buf));
-
- /* If late or duplicate packet (like the redundant end packet). Ignore */
- if (dtmf_payload.duration > 0) {
- outbuf = gst_buffer_new ();
- gst_dtmf_src_generate_tone(rtpdtmfdepay, dtmf_payload, outbuf);
-
-
- GST_BUFFER_TIMESTAMP (outbuf) = rtpdtmfdepay->first_gst_ts +
- (rtpdtmfdepay->previous_duration - dtmf_payload.duration) *
- GST_SECOND / depayload->clock_rate;
- GST_BUFFER_OFFSET (outbuf) =
- (rtpdtmfdepay->previous_duration - dtmf_payload.duration) *
- GST_SECOND / depayload->clock_rate;
- GST_BUFFER_OFFSET_END (outbuf) = rtpdtmfdepay->previous_duration *
- GST_SECOND / depayload->clock_rate;
-
- GST_DEBUG_OBJECT (depayload, "timestamp : %llu - time %" GST_TIME_FORMAT,
- GST_BUFFER_TIMESTAMP (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
-
- }
-
- return outbuf;
-
-
-bad_packet:
- GST_ELEMENT_WARNING (rtpdtmfdepay, STREAM, DECODE,
- ("Packet did not validate"), (NULL));
- return NULL;
-}
-
-gboolean
-gst_rtp_dtmf_depay_plugin_init (GstPlugin * plugin)
-{
- return gst_element_register (plugin, "rtpdtmfdepay",
- GST_RANK_MARGINAL, GST_TYPE_RTP_DTMF_DEPAY);
-}
-
diff --git a/gst/dtmf/gstrtpdtmfdepay.h b/gst/dtmf/gstrtpdtmfdepay.h
deleted file mode 100644
index 4fb31a0..0000000
--- a/gst/dtmf/gstrtpdtmfdepay.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* GstRtpDtmfDepay
- *
- * Copyright (C) 2008 Collabora Limited
- * Copyright (C) 2008 Nokia Corporation
- * Contact: Youness Alaoui <youness.alaoui at collabora.co.uk>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_RTP_DTMF_DEPAY_H__
-#define __GST_RTP_DTMF_DEPAY_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
-#include <gst/rtp/gstbasertpdepayload.h>
-
-#include "gstrtpdtmfcommon.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_RTP_DTMF_DEPAY \
- (gst_rtp_dtmf_depay_get_type())
-#define GST_RTP_DTMF_DEPAY(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_DTMF_DEPAY,GstRtpDTMFDepay))
-#define GST_RTP_DTMF_DEPAY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_DTMF_DEPAY,GstRtpDTMFDepayClass))
-#define GST_IS_RTP_DTMF_DEPAY(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_DTMF_DEPAY))
-#define GST_IS_RTP_DTMF_DEPAY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_DTMF_DEPAY))
-
-
-typedef struct _GstRtpDTMFDepay GstRtpDTMFDepay;
-typedef struct _GstRtpDTMFDepayClass GstRtpDTMFDepayClass;
-
-struct _GstRtpDTMFDepay
-{
- GstBaseRTPDepayload depayload;
- double sample;
- guint32 previous_ts;
- guint16 previous_duration;
- GstClockTime first_gst_ts;
- guint unit_time;
- guint max_duration;
-};
-
-struct _GstRtpDTMFDepayClass
-{
- GstBaseRTPDepayloadClass parent_class;
-};
-
-gboolean gst_rtp_dtmf_depay_plugin_init (GstPlugin * plugin);
-
-G_END_DECLS
-
-#endif /* __GST_RTP_DTMF_DEPAY_H__ */
diff --git a/gst/dtmf/gstrtpdtmfsrc.c b/gst/dtmf/gstrtpdtmfsrc.c
deleted file mode 100644
index 588cda4..0000000
--- a/gst/dtmf/gstrtpdtmfsrc.c
+++ /dev/null
@@ -1,1106 +0,0 @@
-/* GStreamer RTP DTMF source
- *
- * gstrtpdtmfsrc.c:
- *
- * Copyright (C) <2007> Nokia Corporation.
- * Contact: Zeeshan Ali <zeeshan.ali at nokia.com>
- * Copyright (C) 1999,2000 Erik Walthinsen <omega at cse.ogi.edu>
- * 2000,2005 Wim Taymans <wim at fluendo.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:element-rtpdtmfsrc
- * @short_description: Generates RTP DTMF packets
- *
- * <refsect2>
- *
- * <para>
- * The RTPDTMFSrc element generates RTP DTMF (RFC 2833) event packets on request
- * from application. The application communicates the beginning and end of a
- * DTMF event using custom upstream gstreamer events. To report a DTMF event, an
- * application must send an event of type GST_EVENT_CUSTOM_UPSTREAM, having a
- * structure of name "dtmf-event" with fields set according to the following
- * table:
- * </para>
- *
- * <para>
- * <informaltable>
- * <tgroup cols='4'>
- * <colspec colname='Name' />
- * <colspec colname='Type' />
- * <colspec colname='Possible values' />
- * <colspec colname='Purpose' />
- *
- * <thead>
- * <row>
- * <entry>Name</entry>
- * <entry>GType</entry>
- * <entry>Possible values</entry>
- * <entry>Purpose</entry>
- * </row>
- * </thead>
- *
- * <tbody>
- * <row>
- * <entry>type</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>0-1</entry>
- * <entry>The application uses this field to specify which of the two methods
- * specified in RFC 2833 to use. The value should be 0 for tones and 1 for
- * named events. Tones are specified by their frequencies and events are specied
- * by their number. This element can only take events as input. Do not confuse
- * with "method" which specified the output.
- * </entry>
- * </row>
- * <row>
- * <entry>number</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>0-16</entry>
- * <entry>The event number.</entry>
- * </row>
- * <row>
- * <entry>volume</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>0-36</entry>
- * <entry>This field describes the power level of the tone, expressed in dBm0
- * after dropping the sign. Power levels range from 0 to -63 dBm0. The range of
- * valid DTMF is from 0 to -36 dBm0. Can be omitted if start is set to FALSE.
- * </entry>
- * </row>
- * <row>
- * <entry>start</entry>
- * <entry>G_TYPE_BOOLEAN</entry>
- * <entry>True or False</entry>
- * <entry>Whether the event is starting or ending.</entry>
- * </row>
- * <row>
- * <entry>method</entry>
- * <entry>G_TYPE_INT</entry>
- * <entry>1</entry>
- * <entry>The method used for sending event, this element will react if this
- * field is absent or 1.
- * </entry>
- * </row>
- * </tbody>
- * </tgroup>
- * </informaltable>
- * </para>
- *
- * <para>For example, the following code informs the pipeline (and in turn, the
- * RTPDTMFSrc element inside the pipeline) about the start of an RTP DTMF named
- * event '1' of volume -25 dBm0:
- * </para>
- *
- * <para>
- * <programlisting>
- * structure = gst_structure_new ("dtmf-event",
- * "type", G_TYPE_INT, 1,
- * "number", G_TYPE_INT, 1,
- * "volume", G_TYPE_INT, 25,
- * "start", G_TYPE_BOOLEAN, TRUE, NULL);
- *
- * event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, structure);
- * gst_element_send_event (pipeline, event);
- * </programlisting>
- * </para>
- *
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include "gstrtpdtmfsrc.h"
-
-#define GST_RTP_DTMF_TYPE_EVENT 1
-#define DEFAULT_PACKET_INTERVAL 50 /* ms */
-#define MIN_PACKET_INTERVAL 10 /* ms */
-#define MAX_PACKET_INTERVAL 50 /* ms */
-#define DEFAULT_SSRC -1
-#define DEFAULT_PT 96
-#define DEFAULT_TIMESTAMP_OFFSET -1
-#define DEFAULT_SEQNUM_OFFSET -1
-#define DEFAULT_CLOCK_RATE 8000
-#define MIN_EVENT 0
-#define MAX_EVENT 16
-#define MIN_EVENT_STRING "0"
-#define MAX_EVENT_STRING "16"
-#define MIN_VOLUME 0
-#define MAX_VOLUME 36
-
-#define MIN_INTER_DIGIT_INTERVAL 50 /* ms */
-#define MIN_PULSE_DURATION 70 /* ms */
-
-#define DEFAULT_PACKET_REDUNDANCY 1
-#define MIN_PACKET_REDUNDANCY 1
-#define MAX_PACKET_REDUNDANCY 5
-
-/* elementfactory information */
-static const GstElementDetails gst_rtp_dtmf_src_details =
-GST_ELEMENT_DETAILS ("RTP DTMF packet generator",
- "Source/Network",
- "Generates RTP DTMF packets",
- "Zeeshan Ali <zeeshan.ali at nokia.com>");
-
-GST_DEBUG_CATEGORY_STATIC (gst_rtp_dtmf_src_debug);
-#define GST_CAT_DEFAULT gst_rtp_dtmf_src_debug
-
-/* signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_0,
- PROP_SSRC,
- PROP_TIMESTAMP_OFFSET,
- PROP_SEQNUM_OFFSET,
- PROP_PT,
- PROP_CLOCK_RATE,
- PROP_TIMESTAMP,
- PROP_SEQNUM,
- PROP_INTERVAL,
- PROP_REDUNDANCY
-};
-
-static GstStaticPadTemplate gst_rtp_dtmf_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp, "
- "media = (string) \"audio\", "
- "payload = (int) [ 96, 127 ], "
- "clock-rate = (int) [ 0, MAX ], "
- "ssrc = (int) [ 0, MAX ], "
- "encoding-name = (string) \"TELEPHONE-EVENT\"")
- /* "events = (string) \"0-15\" */
-
- );
-
-
-GST_BOILERPLATE (GstRTPDTMFSrc, gst_rtp_dtmf_src, GstBaseSrc,
- GST_TYPE_BASE_SRC);
-
-
-static void gst_rtp_dtmf_src_base_init (gpointer g_class);
-static void gst_rtp_dtmf_src_class_init (GstRTPDTMFSrcClass * klass);
-static void gst_rtp_dtmf_src_finalize (GObject * object);
-
-
-static void gst_rtp_dtmf_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtp_dtmf_src_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static gboolean gst_rtp_dtmf_src_handle_event (GstBaseSrc *basesrc,
- GstEvent * event);
-static GstStateChangeReturn gst_rtp_dtmf_src_change_state (GstElement * element,
- GstStateChange transition);
-static void gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc *dtmfsrc,
- gint event_number, gint event_volume);
-static void gst_rtp_dtmf_src_add_stop_event (GstRTPDTMFSrc *dtmfsrc);
-
-static gboolean gst_rtp_dtmf_src_unlock (GstBaseSrc *src);
-static gboolean gst_rtp_dtmf_src_unlock_stop (GstBaseSrc *src);
-static GstFlowReturn gst_rtp_dtmf_src_create (GstBaseSrc * basesrc,
- guint64 offset, guint length, GstBuffer ** buffer);
-static gboolean gst_rtp_dtmf_src_negotiate (GstBaseSrc * basesrc);
-
-
-static void
-gst_rtp_dtmf_src_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- GST_DEBUG_CATEGORY_INIT (gst_rtp_dtmf_src_debug,
- "rtpdtmfsrc", 0, "rtpdtmfsrc element");
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_rtp_dtmf_src_template));
-
- gst_element_class_set_details (element_class, &gst_rtp_dtmf_src_details);
-}
-
-static void
-gst_rtp_dtmf_src_class_init (GstRTPDTMFSrcClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseSrcClass *gstbasesrc_class;
- GstElementClass *gstelement_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
- gstelement_class = GST_ELEMENT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_finalize);
- gobject_class->set_property =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_set_property);
- gobject_class->get_property =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_get_property);
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMESTAMP,
- g_param_spec_uint ("timestamp", "Timestamp",
- "The RTP timestamp of the last processed packet",
- 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM,
- g_param_spec_uint ("seqnum", "Sequence number",
- "The RTP sequence number of the last processed packet",
- 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (G_OBJECT_CLASS (klass),
- PROP_TIMESTAMP_OFFSET, g_param_spec_int ("timestamp-offset",
- "Timestamp Offset",
- "Offset to add to all outgoing timestamps (-1 = random)", -1,
- G_MAXINT, DEFAULT_TIMESTAMP_OFFSET, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SEQNUM_OFFSET,
- g_param_spec_int ("seqnum-offset", "Sequence number Offset",
- "Offset to add to all outgoing seqnum (-1 = random)", -1, G_MAXINT,
- DEFAULT_SEQNUM_OFFSET, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CLOCK_RATE,
- g_param_spec_uint ("clock-rate", "clockrate",
- "The clock-rate at which to generate the dtmf packets",
- 0, G_MAXUINT, DEFAULT_CLOCK_RATE, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
- g_param_spec_uint ("ssrc", "SSRC",
- "The SSRC of the packets (-1 == random)",
- 0, G_MAXUINT, DEFAULT_SSRC, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
- g_param_spec_uint ("pt", "payload type",
- "The payload type of the packets",
- 0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INTERVAL,
- g_param_spec_uint ("interval", "Interval between rtp packets",
- "Interval in ms between two rtp packets", MIN_PACKET_INTERVAL,
- MAX_PACKET_INTERVAL, DEFAULT_PACKET_INTERVAL, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_REDUNDANCY,
- g_param_spec_uint ("packet-redundancy", "Packet Redundancy",
- "Number of packets to send to indicate start and stop dtmf events",
- MIN_PACKET_REDUNDANCY, MAX_PACKET_REDUNDANCY,
- DEFAULT_PACKET_REDUNDANCY, G_PARAM_READWRITE));
-
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_change_state);
-
- gstbasesrc_class->unlock =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_unlock);
- gstbasesrc_class->unlock_stop =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_unlock_stop);
-
- gstbasesrc_class->event =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_handle_event);
- gstbasesrc_class->create =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_create);
- gstbasesrc_class->negotiate =
- GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_negotiate);
-}
-
-static void
-gst_rtp_dtmf_src_init (GstRTPDTMFSrc * object, GstRTPDTMFSrcClass * g_class)
-{
- gst_base_src_set_format (GST_BASE_SRC (object), GST_FORMAT_TIME);
- gst_base_src_set_live (GST_BASE_SRC (object), TRUE);
-
- object->ssrc = DEFAULT_SSRC;
- object->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
- object->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
- object->pt = DEFAULT_PT;
- object->clock_rate = DEFAULT_CLOCK_RATE;
- object->interval = DEFAULT_PACKET_INTERVAL;
- object->packet_redundancy = DEFAULT_PACKET_REDUNDANCY;
-
- object->event_queue = g_async_queue_new ();
- object->payload = NULL;
-
- GST_DEBUG_OBJECT (object, "init done");
-}
-
-static void
-gst_rtp_dtmf_src_finalize (GObject * object)
-{
- GstRTPDTMFSrc *dtmfsrc;
-
- dtmfsrc = GST_RTP_DTMF_SRC (object);
-
- if (dtmfsrc->event_queue) {
- g_async_queue_unref (dtmfsrc->event_queue);
- dtmfsrc->event_queue = NULL;
- }
-
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static gboolean
-gst_rtp_dtmf_src_handle_dtmf_event (GstRTPDTMFSrc *dtmfsrc,
- const GstStructure * event_structure)
-{
- gint event_type;
- gboolean start;
- gint method;
-
- if (!gst_structure_get_int (event_structure, "type", &event_type) ||
- !gst_structure_get_boolean (event_structure, "start", &start) ||
- event_type != GST_RTP_DTMF_TYPE_EVENT)
- goto failure;
-
- if (gst_structure_get_int (event_structure, "method", &method)) {
- if (method != 1) {
- goto failure;
- }
- }
-
- if (start) {
- gint event_number;
- gint event_volume;
-
- if (!gst_structure_get_int (event_structure, "number", &event_number) ||
- !gst_structure_get_int (event_structure, "volume", &event_volume))
- goto failure;
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d",
- event_number, event_volume);
- gst_rtp_dtmf_src_add_start_event (dtmfsrc, event_number, event_volume);
- }
-
- else {
- GST_DEBUG_OBJECT (dtmfsrc, "Received stop event");
- gst_rtp_dtmf_src_add_stop_event (dtmfsrc);
- }
-
- return TRUE;
-failure:
- return FALSE;
-}
-
-static gboolean
-gst_rtp_dtmf_src_handle_custom_upstream (GstRTPDTMFSrc *dtmfsrc,
- GstEvent * event)
-{
- gboolean result = FALSE;
- gchar *struct_str;
- const GstStructure *structure;
-
- GstState state;
- GstStateChangeReturn ret;
-
- ret = gst_element_get_state (GST_ELEMENT (dtmfsrc), &state, NULL, 0);
- if (ret != GST_STATE_CHANGE_SUCCESS || state != GST_STATE_PLAYING) {
- GST_DEBUG_OBJECT (dtmfsrc, "Received event while not in PLAYING state");
- goto ret;
- }
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received event is of our interest");
- structure = gst_event_get_structure (event);
- struct_str = gst_structure_to_string (structure);
- GST_DEBUG_OBJECT (dtmfsrc, "Event has structure %s", struct_str);
- g_free (struct_str);
- if (structure && gst_structure_has_name (structure, "dtmf-event"))
- result = gst_rtp_dtmf_src_handle_dtmf_event (dtmfsrc, structure);
-
-ret:
- return result;
-}
-
-static gboolean
-gst_rtp_dtmf_src_handle_event (GstBaseSrc *basesrc, GstEvent * event)
-{
- GstRTPDTMFSrc *dtmfsrc;
- gboolean result = FALSE;
-
- dtmfsrc = GST_RTP_DTMF_SRC (basesrc);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received an event on the src pad");
- if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UPSTREAM) {
- result = gst_rtp_dtmf_src_handle_custom_upstream (dtmfsrc, event);
- }
-
- return result;
-}
-
-static void
-gst_rtp_dtmf_src_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRTPDTMFSrc *dtmfsrc;
-
- dtmfsrc = GST_RTP_DTMF_SRC (object);
-
- switch (prop_id) {
- case PROP_TIMESTAMP_OFFSET:
- dtmfsrc->ts_offset = g_value_get_int (value);
- break;
- case PROP_SEQNUM_OFFSET:
- dtmfsrc->seqnum_offset = g_value_get_int (value);
- break;
- case PROP_CLOCK_RATE:
- dtmfsrc->clock_rate = g_value_get_uint (value);
- dtmfsrc->dirty = TRUE;
- break;
- case PROP_SSRC:
- dtmfsrc->ssrc = g_value_get_uint (value);
- break;
- case PROP_PT:
- dtmfsrc->pt = g_value_get_uint (value);
- dtmfsrc->dirty = TRUE;
- break;
- case PROP_INTERVAL:
- dtmfsrc->interval = g_value_get_uint (value);
- break;
- case PROP_REDUNDANCY:
- dtmfsrc->packet_redundancy = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtp_dtmf_src_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRTPDTMFSrc *dtmfsrc;
-
- dtmfsrc = GST_RTP_DTMF_SRC (object);
-
- switch (prop_id) {
- case PROP_TIMESTAMP_OFFSET:
- g_value_set_int (value, dtmfsrc->ts_offset);
- break;
- case PROP_SEQNUM_OFFSET:
- g_value_set_int (value, dtmfsrc->seqnum_offset);
- break;
- case PROP_CLOCK_RATE:
- g_value_set_uint (value, dtmfsrc->clock_rate);
- break;
- case PROP_SSRC:
- g_value_set_uint (value, dtmfsrc->ssrc);
- break;
- case PROP_PT:
- g_value_set_uint (value, dtmfsrc->pt);
- break;
- case PROP_TIMESTAMP:
- g_value_set_uint (value, dtmfsrc->rtp_timestamp);
- break;
- case PROP_SEQNUM:
- g_value_set_uint (value, dtmfsrc->seqnum);
- break;
- case PROP_INTERVAL:
- g_value_set_uint (value, dtmfsrc->interval);
- break;
- case PROP_REDUNDANCY:
- g_value_set_uint (value, dtmfsrc->packet_redundancy);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtp_dtmf_src_set_stream_lock (GstRTPDTMFSrc *dtmfsrc, gboolean lock)
-{
- GstEvent *event;
- GstStructure *structure;
-
- structure = gst_structure_new ("stream-lock",
- "lock", G_TYPE_BOOLEAN, lock, NULL);
-
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, structure);
- if (!gst_pad_push_event (GST_BASE_SRC_PAD (dtmfsrc), event)) {
- GST_WARNING_OBJECT (dtmfsrc, "stream-lock event not handled");
- }
-
-}
-
-static void
-gst_rtp_dtmf_prepare_timestamps (GstRTPDTMFSrc *dtmfsrc)
-{
- GstClock *clock;
- GstClockTime base_time;
-
-#ifdef MAEMO_BROKEN
- base_time = 0;
-#else
- base_time = gst_element_get_base_time (GST_ELEMENT (dtmfsrc));
-#endif
-
- clock = gst_element_get_clock (GST_ELEMENT (dtmfsrc));
- if (clock != NULL) {
- dtmfsrc->timestamp = gst_clock_get_time (clock)
- + (MIN_INTER_DIGIT_INTERVAL * GST_MSECOND) - base_time;
- dtmfsrc->start_timestamp = dtmfsrc->timestamp;
- gst_object_unref (clock);
- } else {
- gchar *dtmf_name = gst_element_get_name (dtmfsrc);
- GST_ERROR_OBJECT (dtmfsrc, "No clock set for element %s", dtmf_name);
- dtmfsrc->timestamp = GST_CLOCK_TIME_NONE;
- g_free (dtmf_name);
- }
-
- dtmfsrc->rtp_timestamp = dtmfsrc->ts_base +
- gst_util_uint64_scale_int (
- gst_segment_to_running_time (&GST_BASE_SRC (dtmfsrc)->segment,
- GST_FORMAT_TIME, dtmfsrc->timestamp),
- dtmfsrc->clock_rate, GST_SECOND);
-}
-
-
-static void
-gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc *dtmfsrc, gint event_number,
- gint event_volume)
-{
-
- GstRTPDTMFSrcEvent * event = g_malloc (sizeof(GstRTPDTMFSrcEvent));
- event->event_type = RTP_DTMF_EVENT_TYPE_START;
-
- event->payload = g_new0 (GstRTPDTMFPayload, 1);
- event->payload->event = CLAMP (event_number, MIN_EVENT, MAX_EVENT);
- event->payload->volume = CLAMP (event_volume, MIN_VOLUME, MAX_VOLUME);
- event->payload->duration = dtmfsrc->interval * dtmfsrc->clock_rate / 1000;
-
- g_async_queue_push (dtmfsrc->event_queue, event);
-}
-
-static void
-gst_rtp_dtmf_src_add_stop_event (GstRTPDTMFSrc *dtmfsrc)
-{
-
- GstRTPDTMFSrcEvent * event = g_malloc (sizeof(GstRTPDTMFSrcEvent));
- event->event_type = RTP_DTMF_EVENT_TYPE_STOP;
-
- g_async_queue_push (dtmfsrc->event_queue, event);
-}
-
-
-static void
-gst_rtp_dtmf_prepare_rtp_headers (GstRTPDTMFSrc *dtmfsrc, GstBuffer *buf)
-{
- gst_rtp_buffer_set_ssrc (buf, dtmfsrc->current_ssrc);
- gst_rtp_buffer_set_payload_type (buf, dtmfsrc->pt);
- /* Only the very first packet gets a marker */
- if (dtmfsrc->first_packet) {
- gst_rtp_buffer_set_marker (buf, TRUE);
- } else if (dtmfsrc->last_packet) {
- dtmfsrc->payload->e = 1;
- }
-
- dtmfsrc->seqnum++;
- gst_rtp_buffer_set_seq (buf, dtmfsrc->seqnum);
-
- /* timestamp of RTP header */
- gst_rtp_buffer_set_timestamp (buf, dtmfsrc->rtp_timestamp);
-}
-
-static void
-gst_rtp_dtmf_prepare_buffer_data (GstRTPDTMFSrc *dtmfsrc, GstBuffer *buf)
-{
- GstRTPDTMFPayload *payload;
-
- gst_rtp_dtmf_prepare_rtp_headers (dtmfsrc, buf);
-
- /* timestamp and duration of GstBuffer */
- /* Redundant buffer have no duration ... */
- if (dtmfsrc->redundancy_count > 1)
- GST_BUFFER_DURATION (buf) = 0;
- else
- GST_BUFFER_DURATION (buf) = dtmfsrc->interval * GST_MSECOND;
- GST_BUFFER_TIMESTAMP (buf) = dtmfsrc->timestamp;
-
- dtmfsrc->timestamp += GST_BUFFER_DURATION (buf);
-
- payload = (GstRTPDTMFPayload *) gst_rtp_buffer_get_payload (buf);
-
- /* copy payload and convert to network-byte order */
- g_memmove (payload, dtmfsrc->payload, sizeof (GstRTPDTMFPayload));
- /* Force the packet duration to a certain minumum
- * if its the end of the event
- */
- if (payload->e &&
- payload->duration < MIN_PULSE_DURATION * dtmfsrc->clock_rate / 1000 )
- payload->duration = MIN_PULSE_DURATION * dtmfsrc->clock_rate / 1000;
-
- payload->duration = g_htons (payload->duration);
-
-
- /* duration of DTMF payloadfor the NEXT packet */
- /* not updated for redundant packets */
- if (dtmfsrc->redundancy_count == 0)
- dtmfsrc->payload->duration +=
- dtmfsrc->interval * dtmfsrc->clock_rate / 1000;
-
-}
-
-static GstBuffer *
-gst_rtp_dtmf_src_create_next_rtp_packet (GstRTPDTMFSrc *dtmfsrc)
-{
- GstBuffer *buf = NULL;
-
- /* create buffer to hold the payload */
- buf = gst_rtp_buffer_new_allocate (sizeof (GstRTPDTMFPayload), 0, 0);
-
- gst_rtp_dtmf_prepare_buffer_data (dtmfsrc, buf);
-
- /* Set caps on the buffer before pushing it */
- gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (dtmfsrc)));
-
- return buf;
-}
-
-static GstFlowReturn
-gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset,
- guint length, GstBuffer ** buffer)
-{
- GstRTPDTMFSrcEvent *event;
- GstRTPDTMFSrc * dtmfsrc;
- GstClock *clock;
- GstClockID *clockid;
- GstClockReturn clockret;
-
- dtmfsrc = GST_RTP_DTMF_SRC (basesrc);
-
- do {
-
- if (dtmfsrc->payload == NULL) {
- GST_DEBUG_OBJECT (dtmfsrc, "popping");
- event = g_async_queue_pop (dtmfsrc->event_queue);
-
- GST_DEBUG_OBJECT (dtmfsrc, "popped %d", event->event_type);
-
- switch (event->event_type) {
- case RTP_DTMF_EVENT_TYPE_STOP:
- GST_WARNING_OBJECT (dtmfsrc,
- "Received a DTMF stop event when already stopped");
- break;
-
- case RTP_DTMF_EVENT_TYPE_START:
- dtmfsrc->first_packet = TRUE;
- dtmfsrc->last_packet = FALSE;
- /* Set the redundancy on the first packet */
- dtmfsrc->redundancy_count = dtmfsrc->packet_redundancy;
- gst_rtp_dtmf_prepare_timestamps (dtmfsrc);
-
- /* Don't forget to get exclusive access to the stream */
- gst_rtp_dtmf_src_set_stream_lock (dtmfsrc, TRUE);
-
- dtmfsrc->payload = event->payload;
- break;
-
- case RTP_DTMF_EVENT_TYPE_PAUSE_TASK:
- /*
- * We're pushing it back because it has to stay in there until
- * the task is really paused (and the queue will then be flushed
- */
- GST_OBJECT_LOCK (dtmfsrc);
- if (dtmfsrc->paused) {
- g_async_queue_push (dtmfsrc->event_queue, event);
- goto paused_locked;
- }
- GST_OBJECT_UNLOCK (dtmfsrc);
- break;
- }
-
- g_free (event);
- } else if (!dtmfsrc->first_packet && !dtmfsrc->last_packet &&
- (dtmfsrc->timestamp - dtmfsrc->start_timestamp)/GST_MSECOND >=
- MIN_PULSE_DURATION) {
- GST_DEBUG_OBJECT (dtmfsrc, "try popping");
- event = g_async_queue_try_pop (dtmfsrc->event_queue);
-
-
- if (event != NULL) {
- GST_DEBUG_OBJECT (dtmfsrc, "try popped %d", event->event_type);
-
- switch (event->event_type) {
- case RTP_DTMF_EVENT_TYPE_START:
- GST_WARNING_OBJECT (dtmfsrc,
- "Received two consecutive DTMF start events");
- break;
-
- case RTP_DTMF_EVENT_TYPE_STOP:
- dtmfsrc->first_packet = FALSE;
- dtmfsrc->last_packet = TRUE;
- /* Set the redundancy on the last packet */
- dtmfsrc->redundancy_count = dtmfsrc->packet_redundancy;
- break;
-
- case RTP_DTMF_EVENT_TYPE_PAUSE_TASK:
- /*
- * We're pushing it back because it has to stay in there until
- * the task is really paused (and the queue will then be flushed)
- */
- GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
- GST_OBJECT_LOCK (dtmfsrc);
- if (dtmfsrc->paused) {
- g_async_queue_push (dtmfsrc->event_queue, event);
- goto paused_locked;
- }
- GST_OBJECT_UNLOCK (dtmfsrc);
- break;
- }
- g_free (event);
- }
- }
- } while (dtmfsrc->payload == NULL);
-
-
- GST_DEBUG_OBJECT (dtmfsrc, "Processed events, now lets wait on the clock");
-
- clock = gst_element_get_clock (GST_ELEMENT (basesrc));
-
-#ifdef MAEMO_BROKEN
- clockid = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp);
-#else
- clockid = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp +
- gst_element_get_base_time (GST_ELEMENT (dtmfsrc)));
-#endif
- gst_object_unref (clock);
-
- GST_OBJECT_LOCK (dtmfsrc);
- if (!dtmfsrc->paused) {
- dtmfsrc->clockid = clockid;
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- clockret = gst_clock_id_wait (clockid, NULL);
-
- GST_OBJECT_LOCK (dtmfsrc);
- if (dtmfsrc->paused)
- clockret = GST_CLOCK_UNSCHEDULED;
- } else {
- clockret = GST_CLOCK_UNSCHEDULED;
- }
- gst_clock_id_unref (clockid);
- dtmfsrc->clockid = NULL;
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- if (clockret == GST_CLOCK_UNSCHEDULED) {
- goto paused;
- }
-
- send_last:
-
- if (dtmfsrc->dirty)
- if (!gst_rtp_dtmf_src_negotiate (basesrc))
- return GST_FLOW_NOT_NEGOTIATED;
-
- /* create buffer to hold the payload */
- *buffer = gst_rtp_dtmf_src_create_next_rtp_packet (dtmfsrc);
-
- if (dtmfsrc->redundancy_count)
- dtmfsrc->redundancy_count--;
-
- /* Only the very first one has a marker */
- dtmfsrc->first_packet = FALSE;
-
- /* This is the end of the event */
- if (dtmfsrc->last_packet == TRUE && dtmfsrc->redundancy_count == 0) {
-
- /* Don't forget to release the stream lock */
- gst_rtp_dtmf_src_set_stream_lock (dtmfsrc, FALSE);
-
- g_free (dtmfsrc->payload);
- dtmfsrc->payload = NULL;
-
- dtmfsrc->last_packet = FALSE;
- }
-
- return GST_FLOW_OK;
-
- paused_locked:
-
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- paused:
-
- if (dtmfsrc->payload) {
- dtmfsrc->first_packet = FALSE;
- dtmfsrc->last_packet = TRUE;
- /* Set the redundanc on the last packet */
- dtmfsrc->redundancy_count = dtmfsrc->packet_redundancy;
- goto send_last;
- } else {
- return GST_FLOW_WRONG_STATE;
- }
-}
-
-
-static gboolean
-gst_rtp_dtmf_src_negotiate (GstBaseSrc * basesrc)
-{
- GstCaps *srccaps, *peercaps;
- GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (basesrc);
- gboolean ret;
-
- /* fill in the defaults, there properties cannot be negotiated. */
- srccaps = gst_caps_new_simple ("application/x-rtp",
- "media", G_TYPE_STRING, "audio",
- "encoding-name", G_TYPE_STRING, "TELEPHONE-EVENT", NULL);
-
- /* the peer caps can override some of the defaults */
- peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
- if (peercaps == NULL) {
- /* no peer caps, just add the other properties */
- gst_caps_set_simple (srccaps,
- "payload", G_TYPE_INT, dtmfsrc->pt,
- "ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc,
- "clock-base", G_TYPE_UINT, dtmfsrc->ts_base,
- "clock-rate", G_TYPE_INT, dtmfsrc->clock_rate,
- "seqnum-base", G_TYPE_UINT, dtmfsrc->seqnum_base, NULL);
-
- GST_DEBUG_OBJECT (dtmfsrc, "no peer caps: %" GST_PTR_FORMAT, srccaps);
- } else {
- GstCaps *temp;
- GstStructure *s;
- const GValue *value;
- gint pt;
- gint clock_rate;
-
- /* peer provides caps we can use to fixate, intersect. This always returns a
- * writable caps. */
- temp = gst_caps_intersect (srccaps, peercaps);
- gst_caps_unref (srccaps);
- gst_caps_unref (peercaps);
-
- if (!temp) {
- GST_DEBUG_OBJECT (dtmfsrc, "Could not get intersection with peer caps");
- return FALSE;
- }
-
- if (gst_caps_is_empty (temp)) {
- GST_DEBUG_OBJECT (dtmfsrc, "Intersection with peer caps is empty");
- gst_caps_unref (temp);
- return FALSE;
- }
-
- /* now fixate, start by taking the first caps */
- gst_caps_truncate (temp);
- srccaps = temp;
-
- /* get first structure */
- s = gst_caps_get_structure (srccaps, 0);
-
- if (gst_structure_get_int (s, "payload", &pt)) {
- /* use peer pt */
- dtmfsrc->pt = pt;
- GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
- } else {
- if (gst_structure_has_field (s, "payload")) {
- /* can only fixate if there is a field */
- gst_structure_fixate_field_nearest_int (s, "payload",
- dtmfsrc->pt);
- gst_structure_get_int (s, "payload", &pt);
- GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
- } else {
- /* no pt field, use the internal pt */
- pt = dtmfsrc->pt;
- gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
- GST_LOG_OBJECT (dtmfsrc, "using internal pt %d", pt);
- }
- }
-
- if (gst_structure_get_int (s, "clock-rate", &clock_rate))
- {
- dtmfsrc->clock_rate = clock_rate;
- GST_LOG_OBJECT (dtmfsrc, "using clock-rate from caps %d",
- dtmfsrc->clock_rate);
- } else {
- GST_LOG_OBJECT (dtmfsrc, "using existing clock-rate %d",
- dtmfsrc->clock_rate);
- }
- gst_structure_set (s, "clock-rate", G_TYPE_INT, dtmfsrc->clock_rate,
- NULL);
-
-
- if (gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT)) {
- value = gst_structure_get_value (s, "ssrc");
- dtmfsrc->current_ssrc = g_value_get_uint (value);
- GST_LOG_OBJECT (dtmfsrc, "using peer ssrc %08x", dtmfsrc->current_ssrc);
- } else {
- /* FIXME, fixate_nearest_uint would be even better */
- gst_structure_set (s, "ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc, NULL);
- GST_LOG_OBJECT (dtmfsrc, "using internal ssrc %08x",
- dtmfsrc->current_ssrc);
- }
-
- if (gst_structure_has_field_typed (s, "clock-base", G_TYPE_UINT)) {
- value = gst_structure_get_value (s, "clock-base");
- dtmfsrc->ts_base = g_value_get_uint (value);
- GST_LOG_OBJECT (dtmfsrc, "using peer clock-base %u", dtmfsrc->ts_base);
- } else {
- /* FIXME, fixate_nearest_uint would be even better */
- gst_structure_set (s, "clock-base", G_TYPE_UINT, dtmfsrc->ts_base, NULL);
- GST_LOG_OBJECT (dtmfsrc, "using internal clock-base %u",
- dtmfsrc->ts_base);
- }
- if (gst_structure_has_field_typed (s, "seqnum-base", G_TYPE_UINT)) {
- value = gst_structure_get_value (s, "seqnum-base");
- dtmfsrc->seqnum_base = g_value_get_uint (value);
- GST_LOG_OBJECT (dtmfsrc, "using peer seqnum-base %u",
- dtmfsrc->seqnum_base);
- } else {
- /* FIXME, fixate_nearest_uint would be even better */
- gst_structure_set (s, "seqnum-base", G_TYPE_UINT, dtmfsrc->seqnum_base,
- NULL);
- GST_LOG_OBJECT (dtmfsrc, "using internal seqnum-base %u",
- dtmfsrc->seqnum_base);
- }
- GST_DEBUG_OBJECT (dtmfsrc, "with peer caps: %" GST_PTR_FORMAT, srccaps);
- }
-
- ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), srccaps);
- gst_caps_unref (srccaps);
-
- dtmfsrc->dirty = FALSE;
-
- return ret;
-
-}
-
-
-static void
-gst_rtp_dtmf_src_ready_to_paused (GstRTPDTMFSrc *dtmfsrc)
-{
- if (dtmfsrc->ssrc == -1)
- dtmfsrc->current_ssrc = g_random_int ();
- else
- dtmfsrc->current_ssrc = dtmfsrc->ssrc;
-
- if (dtmfsrc->seqnum_offset == -1)
- dtmfsrc->seqnum_base = g_random_int_range (0, G_MAXUINT16);
- else
- dtmfsrc->seqnum_base = dtmfsrc->seqnum_offset;
- dtmfsrc->seqnum = dtmfsrc->seqnum_base;
-
- if (dtmfsrc->ts_offset == -1)
- dtmfsrc->ts_base = g_random_int ();
- else
- dtmfsrc->ts_base = dtmfsrc->ts_offset;
-
-}
-
-static GstStateChangeReturn
-gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
-{
- GstRTPDTMFSrc *dtmfsrc;
- GstStateChangeReturn result;
- gboolean no_preroll = FALSE;
- GstRTPDTMFSrcEvent *event= NULL;
-
- dtmfsrc = GST_RTP_DTMF_SRC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- gst_rtp_dtmf_src_ready_to_paused (dtmfsrc);
-
- /* Flushing the event queue */
- while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL)
- g_free (event);
-
- no_preroll = TRUE;
- break;
- default:
- break;
- }
-
- if ((result =
- GST_ELEMENT_CLASS (parent_class)->change_state (element,
- transition)) == GST_STATE_CHANGE_FAILURE)
- goto failure;
-
- switch (transition) {
- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
- no_preroll = TRUE;
- break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
-
- /* Flushing the event queue */
- while ((event = g_async_queue_try_pop (dtmfsrc->event_queue)) != NULL)
- g_free (event);
-
- /* Indicate that we don't do PRE_ROLL */
- break;
-
- default:
- break;
- }
-
- if (no_preroll && result == GST_STATE_CHANGE_SUCCESS)
- result = GST_STATE_CHANGE_NO_PREROLL;
-
- return result;
-
- /* ERRORS */
-failure:
- {
- GST_ERROR_OBJECT (dtmfsrc, "parent failed state change");
- return result;
- }
-}
-
-
-static gboolean
-gst_rtp_dtmf_src_unlock (GstBaseSrc *src) {
- GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (src);
- GstRTPDTMFSrcEvent *event = NULL;
-
- GST_DEBUG_OBJECT (dtmfsrc, "Called unlock");
-
- GST_OBJECT_LOCK (dtmfsrc);
- dtmfsrc->paused = TRUE;
- if (dtmfsrc->clockid) {
- gst_clock_id_unschedule (dtmfsrc->clockid);
- }
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Pushing the PAUSE_TASK event on unlock request");
- event = g_malloc (sizeof(GstRTPDTMFSrcEvent));
- event->event_type = RTP_DTMF_EVENT_TYPE_PAUSE_TASK;
- g_async_queue_push (dtmfsrc->event_queue, event);
-
- return TRUE;
-}
-
-
-static gboolean
-gst_rtp_dtmf_src_unlock_stop (GstBaseSrc *src) {
- GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (src);
-
- GST_DEBUG_OBJECT (dtmfsrc, "Unlock stopped");
-
- GST_OBJECT_LOCK (dtmfsrc);
- dtmfsrc->paused = FALSE;
- GST_OBJECT_UNLOCK (dtmfsrc);
-
- return TRUE;
-}
-
-gboolean
-gst_rtp_dtmf_src_plugin_init (GstPlugin * plugin)
-{
- return gst_element_register (plugin, "rtpdtmfsrc",
- GST_RANK_NONE, GST_TYPE_RTP_DTMF_SRC);
-}
diff --git a/gst/dtmf/gstrtpdtmfsrc.h b/gst/dtmf/gstrtpdtmfsrc.h
deleted file mode 100644
index ade3a67..0000000
--- a/gst/dtmf/gstrtpdtmfsrc.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* GStreamer RTP DTMF source
- *
- * gstrtpdtmfsrc.h:
- *
- * Copyright (C) <2007> Nokia Corporation.
- * Contact: Zeeshan Ali <zeeshan.ali at nokia.com>
- * Copyright (C) <2005> Wim Taymans <wim at fluendo.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_RTP_DTMF_SRC_H__
-#define __GST_RTP_DTMF_SRC_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstbasesrc.h>
-#include <gst/rtp/gstrtpbuffer.h>
-
-#include "gstrtpdtmfcommon.h"
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_RTP_DTMF_SRC (gst_rtp_dtmf_src_get_type())
-#define GST_RTP_DTMF_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_DTMF_SRC,GstRTPDTMFSrc))
-#define GST_RTP_DTMF_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_DTMF_SRC,GstRTPDTMFSrcClass))
-#define GST_RTP_DTMF_SRC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTP_DTMF_SRC, GstRTPDTMFSrcClass))
-#define GST_IS_RTP_DTMF_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_DTMF_SRC))
-#define GST_IS_RTP_DTMF_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_DTMF_SRC))
-#define GST_RTP_DTMF_SRC_CAST(obj) ((GstRTPDTMFSrc *)(obj))
-
-
-typedef struct _GstRTPDTMFSrc GstRTPDTMFSrc;
-typedef struct _GstRTPDTMFSrcClass GstRTPDTMFSrcClass;
-
-
-
-enum _GstRTPDTMFEventType {
- RTP_DTMF_EVENT_TYPE_START,
- RTP_DTMF_EVENT_TYPE_STOP,
- RTP_DTMF_EVENT_TYPE_PAUSE_TASK
-};
-
-typedef enum _GstRTPDTMFEventType GstRTPDTMFEventType;
-
-struct _GstRTPDTMFSrcEvent {
- GstRTPDTMFEventType event_type;
- GstRTPDTMFPayload* payload;
-};
-
-typedef struct _GstRTPDTMFSrcEvent GstRTPDTMFSrcEvent;
-
-/**
- * GstRTPDTMFSrc:
- * @element: the parent element.
- *
- * The opaque #GstRTPDTMFSrc data structure.
- */
-struct _GstRTPDTMFSrc {
- GstBaseSrc basesrc;
-
- GAsyncQueue* event_queue;
- GstClockID clockid;
- gboolean paused;
- GstRTPDTMFPayload* payload;
-
- GstClockTime timestamp;
- GstClockTime start_timestamp;
- gboolean first_packet;
- gboolean last_packet;
- guint32 ts_base;
- guint16 seqnum_base;
- gint16 seqnum_offset;
- guint16 seqnum;
- gint32 ts_offset;
- guint32 rtp_timestamp;
- guint pt;
- guint ssrc;
- guint current_ssrc;
- guint16 interval;
- guint16 packet_redundancy;
- guint32 clock_rate;
-
- gboolean dirty;
- guint16 redundancy_count;
-};
-
-struct _GstRTPDTMFSrcClass {
- GstBaseSrcClass parent_class;
-};
-
-GType gst_rtp_dtmf_src_get_type (void);
-
-gboolean gst_rtp_dtmf_src_plugin_init (GstPlugin * plugin);
-
-
-G_END_DECLS
-
-#endif /* __GST_RTP_DTMF_SRC_H__ */
--
1.5.6.5
More information about the farsight-commits
mailing list