aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2012-09-14 15:08:17 +0200
committerEvan Huus <eapache@gmail.com>2014-02-12 01:36:02 +0000
commit10084c344c89fdadc915e47bcece84a2ac511dc5 (patch)
treecf48eed191bfd99bd2087f2d7cb3a13fa3049047
parentab3348eeb412d45acd89ffb7d0b39189b36399ce (diff)
RTP: Add support for SBC codec in RTP Player
Add optional dependancy to libsbc to play Bluetooth SBC in A2DP payload. Also simplify RTP Player and extent codec interface. Change-Id: I52e1fce9c82e2885736354fe73c6c37168a4fda3 Reviewed-on: https://code.wireshark.org/review/19 Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Reviewed-by: Evan Huus <eapache@gmail.com>
-rw-r--r--codecs/G711a/G711adecode.c68
-rw-r--r--codecs/G711a/G711adecode.h21
-rw-r--r--codecs/G711a/G711atable.h78
-rw-r--r--codecs/G711u/G711udecode.c69
-rw-r--r--codecs/G711u/G711udecode.h21
-rw-r--r--codecs/G711u/G711utable.h13
-rw-r--r--codecs/G722/G722decode.c42
-rw-r--r--codecs/G722/G722decode.h24
-rw-r--r--codecs/G726/G726decode.c41
-rw-r--r--codecs/G726/G726decode.h24
-rw-r--r--codecs/Makefile.common2
-rw-r--r--codecs/codecs.c172
-rw-r--r--codecs/codecs.h27
-rw-r--r--codecs/sbc/sbc.c37
-rw-r--r--codecs/sbc/sbc_private.h (renamed from codecs/sbc/sbc.h)21
-rw-r--r--configure.ac10
-rw-r--r--ui/gtk/rtp_player.c180
17 files changed, 598 insertions, 252 deletions
diff --git a/codecs/G711a/G711adecode.c b/codecs/G711a/G711adecode.c
index 10fe3e2cc1..e5518932cc 100644
--- a/codecs/G711a/G711adecode.c
+++ b/codecs/G711a/G711adecode.c
@@ -22,21 +22,67 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "config.h"
+
#include <glib.h>
+
#include "G711adecode.h"
#include "G711atable.h"
+void *
+codec_g711a_init(void)
+{
+ return NULL;
+}
+
+void
+codec_g711a_release(void *ctx _U_)
+{
+
+}
+
+int
+codec_g711a_get_channels(void *ctx _U_)
+{
+ return 1;
+}
+
+int
+codec_g711a_get_frequency(void *ctx _U_)
+{
+ return 8000;
+}
+
int
-decodeG711a(void *input, int inputSizeBytes, void *output, int *outputSizeBytes)
+codec_g711a_decode(void *ctx _U_, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes)
{
- guint8 *dataIn = (guint8 *)input;
- gint16 *dataOut = (gint16 *)output;
- int i;
-
- for (i=0; i<inputSizeBytes; i++)
- {
- dataOut[i] = alaw_exp_table[dataIn[i]];
- }
- *outputSizeBytes = inputSizeBytes * 2;
- return 0;
+ const guint8 *dataIn = (const guint8 *) input;
+ gint16 *dataOut = (gint16 *) output;
+ int i;
+
+ if (!output || !outputSizeBytes) {
+ return inputSizeBytes * 2;
+ }
+
+ for (i = 0; i < inputSizeBytes; i++)
+ {
+ dataOut[i] = alaw_exp_table[dataIn[i]];
+ }
+
+ *outputSizeBytes = inputSizeBytes * 2;
+ return inputSizeBytes * 2;
}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/G711a/G711adecode.h b/codecs/G711a/G711adecode.h
index 4acdca31bd..b7ccd3ffaa 100644
--- a/codecs/G711a/G711adecode.h
+++ b/codecs/G711a/G711adecode.h
@@ -25,7 +25,24 @@
#ifndef __CODECS_G711ADECODE_H__
#define __CODECS_G711ADECODE_H__
-int
-decodeG711a(void *input, int inputSizeBytes, void *output, int *outputSizeBytes);
+void *codec_g711a_init(void);
+void codec_g711a_release(void *ctx);
+int codec_g711a_get_channels(void *ctx);
+int codec_g711a_get_frequency(void *ctx);
+int codec_g711a_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes);
#endif /* G711adecode.h */
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/G711a/G711atable.h b/codecs/G711a/G711atable.h
index 5c5e042127..19f2d0069d 100644
--- a/codecs/G711a/G711atable.h
+++ b/codecs/G711a/G711atable.h
@@ -23,35 +23,49 @@
*/
gint16 alaw_exp_table[256] = {
- -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
- -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
- -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
- -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
- -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,
- -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,
- -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472,
- -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,
- -344, -328, -376, -360, -280, -264, -312, -296,
- -472, -456, -504, -488, -408, -392, -440, -424,
- -88, -72, -120, -104, -24, -8, -56, -40,
- -216, -200, -248, -232, -152, -136, -184, -168,
- -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
- -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
- -688, -656, -752, -720, -560, -528, -624, -592,
- -944, -912, -1008, -976, -816, -784, -880, -848,
- 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
- 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
- 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
- 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
- 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
- 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
- 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
- 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
- 344, 328, 376, 360, 280, 264, 312, 296,
- 472, 456, 504, 488, 408, 392, 440, 424,
- 88, 72, 120, 104, 24, 8, 56, 40,
- 216, 200, 248, 232, 152, 136, 184, 168,
- 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
- 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
- 688, 656, 752, 720, 560, 528, 624, 592,
- 944, 912, 1008, 976, 816, 784, 880, 848};
+ -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
+ -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
+ -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
+ -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
+ -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,
+ -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,
+ -11008,-10496,-12032,-11520, -8960, -8448, -9984, -9472,
+ -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,
+ -344, -328, -376, -360, -280, -264, -312, -296,
+ -472, -456, -504, -488, -408, -392, -440, -424,
+ -88, -72, -120, -104, -24, -8, -56, -40,
+ -216, -200, -248, -232, -152, -136, -184, -168,
+ -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
+ -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
+ -688, -656, -752, -720, -560, -528, -624, -592,
+ -944, -912, -1008, -976, -816, -784, -880, -848,
+ 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
+ 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
+ 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
+ 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
+ 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
+ 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
+ 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
+ 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
+ 344, 328, 376, 360, 280, 264, 312, 296,
+ 472, 456, 504, 488, 408, 392, 440, 424,
+ 88, 72, 120, 104, 24, 8, 56, 40,
+ 216, 200, 248, 232, 152, 136, 184, 168,
+ 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
+ 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
+ 688, 656, 752, 720, 560, 528, 624, 592,
+ 944, 912, 1008, 976, 816, 784, 880, 848};
+
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/G711u/G711udecode.c b/codecs/G711u/G711udecode.c
index c56018ad32..369e47df3f 100644
--- a/codecs/G711u/G711udecode.c
+++ b/codecs/G711u/G711udecode.c
@@ -22,21 +22,68 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "config.h"
+
#include <glib.h>
+
#include "G711udecode.h"
#include "G711utable.h"
+void *
+codec_g711u_init(void)
+{
+ return NULL;
+}
+
+void
+codec_g711u_release(void *ctx _U_)
+{
+
+}
+
+int
+codec_g711u_get_channels(void *ctx _U_)
+{
+ return 1;
+}
+
int
-decodeG711u(void *input, int inputSizeBytes, void *output, int *outputSizeBytes)
+codec_g711u_get_frequency(void *ctx _U_)
{
- guint8 *dataIn = (guint8 *)input;
- gint16 *dataOut = (gint16 *)output;
- int i;
-
- for (i=0; i<inputSizeBytes; i++)
- {
- dataOut[i] = ulaw_exp_table[dataIn[i]];
- }
- *outputSizeBytes = inputSizeBytes * 2;
- return 0;
+ return 8000;
}
+
+int
+codec_g711u_decode(void *ctx _U_, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes)
+{
+ const guint8 *dataIn = (const guint8 *) input;
+ gint16 *dataOut = (gint16 *) output;
+ int i;
+
+ if (!output || !outputSizeBytes) {
+ return inputSizeBytes * 2;
+ }
+
+ for (i = 0; i < inputSizeBytes; i++)
+ {
+ dataOut[i] = ulaw_exp_table[dataIn[i]];
+ }
+
+ *outputSizeBytes = inputSizeBytes * 2;
+ return inputSizeBytes * 2;
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
+
diff --git a/codecs/G711u/G711udecode.h b/codecs/G711u/G711udecode.h
index 529d6b31fe..81cd379139 100644
--- a/codecs/G711u/G711udecode.h
+++ b/codecs/G711u/G711udecode.h
@@ -25,7 +25,24 @@
#ifndef __CODECS_G711UDECODE_H__
#define __CODECS_G711UDECODE_H__
-int
-decodeG711u(void *input, int inputSizeBytes, void *output, int *outputSizeBytes);
+void *codec_g711u_init(void);
+void codec_g711u_release(void *ctx);
+int codec_g711u_get_channels(void *ctx);
+int codec_g711u_get_frequency(void *ctx);
+int codec_g711u_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes);
#endif /* G711udecode.h */
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/G711u/G711utable.h b/codecs/G711u/G711utable.h
index 58daff053c..7e11118aef 100644
--- a/codecs/G711u/G711utable.h
+++ b/codecs/G711u/G711utable.h
@@ -55,3 +55,16 @@ gint16 ulaw_exp_table[256] = {
244, 228, 212, 196, 180, 164, 148, 132,
120, 112, 104, 96, 88, 80, 72, 64,
56, 48, 40, 32, 24, 16, 8, 0};
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/G722/G722decode.c b/codecs/G722/G722decode.c
index b668b2bf57..746d150947 100644
--- a/codecs/G722/G722decode.c
+++ b/codecs/G722/G722decode.c
@@ -33,19 +33,53 @@
static g722_decode_state_t state;
-void
-initG722(void)
+void *
+codec_g722_init(void)
{
memset (&state, 0, sizeof (state));
g722_decode_init(&state, 64000, 0);
+
+ return NULL;
+}
+
+void
+codec_g722_release(void *ctx _U_)
+{
+
+}
+
+int
+codec_g722_get_channels(void *ctx _U_)
+{
+ return 1;
+}
+
+int
+codec_g722_get_frequency(void *ctx _U_)
+{
+ return 64000;
}
int
-decodeG722(void *input _U_NOSPANDSP_, int inputSizeBytes _U_NOSPANDSP_,
- void *output _U_NOSPANDSP_, int *outputSizeBytes _U_NOSPANDSP_)
+codec_g722_decode(void *ctx _U_, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes)
{
*outputSizeBytes = g722_decode(&state, output, input, inputSizeBytes);
return 0;
}
#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
+
diff --git a/codecs/G722/G722decode.h b/codecs/G722/G722decode.h
index 255092190a..0b5d8d0f88 100644
--- a/codecs/G722/G722decode.h
+++ b/codecs/G722/G722decode.h
@@ -25,10 +25,24 @@
#ifndef __CODECS_G722DECODE_H__
#define __CODECS_G722DECODE_H__
-void
-initG722(void);
-
-int
-decodeG722(void *input, int inputSizeBytes, void *output, int *outputSizeBytes);
+void *codec_g722_init(void);
+void codec_g722_release(void *ctx);
+int codec_g722_get_channels(void *ctx);
+int codec_g722_get_frequency(void *ctx);
+int codec_g722_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes);
#endif /* G722decode.h */
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/G726/G726decode.c b/codecs/G726/G726decode.c
index bcc2cd1fdc..7961364d41 100644
--- a/codecs/G726/G726decode.c
+++ b/codecs/G726/G726decode.c
@@ -37,21 +37,56 @@
static g726_state_t state;
/* Currently, only G.726-32, linear encoding, left packed is supported */
-void initG726_32(void)
+void *
+codec_g726_init(void)
{
memset (&state, 0, sizeof (state));
g726_init(&state, 32000, 0, 1);
+
+ return NULL;
+}
+
+void
+codec_g726_release(void *ctx _U_)
+{
+
+}
+
+int
+codec_g726_get_channels(void *ctx _U_)
+{
+ return 1;
+}
+
+int
+codec_g726_get_frequency(void *ctx _U_)
+{
+ return 32000;
}
/* Packing should be user defined (via the decode dialog) since due to historical reasons two diverging
* de facto standards are in use today (see RFC3551).
*/
int
-decodeG726_32(void *input, int inputSizeBytes,
- void *output, int *outputSizeBytes)
+codec_g726_decode(void *ctx _U_, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes)
{
*outputSizeBytes = 2 * g726_decode(&state, output, (void*) input, inputSizeBytes);
return 0;
}
#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
+
diff --git a/codecs/G726/G726decode.h b/codecs/G726/G726decode.h
index 3858ae33b1..a61ec9b237 100644
--- a/codecs/G726/G726decode.h
+++ b/codecs/G726/G726decode.h
@@ -25,10 +25,24 @@
#ifndef __CODECS_G726DECODE_H__
#define __CODECS_G726DECODE_H__
-void
-initG726_32(void);
-
-int
-decodeG726_32(void *input, int inputSizeBytes, void *output, int *outputSizeBytes);
+void *codec_g726_init(void);
+void codec_g726_release(void *ctx);
+int codec_g726_get_channels(void *ctx);
+int codec_g726_get_frequency(void *ctx);
+int codec_g726_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
+ int *outputSizeBytes);
#endif /* G726decode.h */
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/Makefile.common b/codecs/Makefile.common
index 42009472c0..7f35b87d2e 100644
--- a/codecs/Makefile.common
+++ b/codecs/Makefile.common
@@ -37,5 +37,5 @@ noinst_HEADERS = \
G711u/G711udecode.h G711u/G711utable.h \
G722/G722decode.h \
G726/G726decode.h \
- sbc/sbc.h
+ sbc/sbc_private.h
diff --git a/codecs/codecs.c b/codecs/codecs.c
index 6f622bbe16..68def22dc4 100644
--- a/codecs/codecs.c
+++ b/codecs/codecs.c
@@ -26,6 +26,14 @@
#include <glib.h>
#include "codecs.h"
+#include "config.h"
+
+#include "G711a/G711adecode.h"
+#include "G711u/G711udecode.h"
+
+#ifdef HAVE_SBC
+#include "sbc/sbc_private.h"
+#endif
#ifdef HAVE_PLUGINS
@@ -37,7 +45,7 @@
* List of codec plugins.
*/
typedef struct {
- void (*register_codec_module)(void); /* routine to call to register a codec */
+ void (*register_codec_module)(void); /* routine to call to register a codec */
} codec_plugin;
static GSList *codec_plugins = NULL;
@@ -48,44 +56,44 @@ static GSList *codec_plugins = NULL;
static gboolean
check_for_codec_plugin(GModule *handle)
{
- gpointer gp;
- void (*register_codec_module)(void);
- codec_plugin *plugin;
-
- /*
- * Do we have a register_codec_module routine?
- */
- if (!g_module_symbol(handle, "register_codec_module", &gp)) {
- /* No, so this isn't a codec plugin. */
- return FALSE;
- }
-
- /*
- * Yes - this plugin includes one or more codecs.
- */
- register_codec_module = (void (*)(void))gp;
-
- /*
- * Add this one to the list of codec plugins.
- */
- plugin = (codec_plugin *)g_malloc(sizeof (codec_plugin));
- plugin->register_codec_module = register_codec_module;
- codec_plugins = g_slist_append(codec_plugins, plugin);
- return TRUE;
+ gpointer gp;
+ void (*register_codec_module)(void);
+ codec_plugin *plugin;
+
+ /*
+ * Do we have a register_codec_module routine?
+ */
+ if (!g_module_symbol(handle, "register_codec_module", &gp)) {
+ /* No, so this isn't a codec plugin. */
+ return FALSE;
+ }
+
+ /*
+ * Yes - this plugin includes one or more codecs.
+ */
+ register_codec_module = (void (*)(void))gp;
+
+ /*
+ * Add this one to the list of codec plugins.
+ */
+ plugin = (codec_plugin *)g_malloc(sizeof (codec_plugin));
+ plugin->register_codec_module = register_codec_module;
+ codec_plugins = g_slist_append(codec_plugins, plugin);
+ return TRUE;
}
void
codec_register_plugin_types(void)
{
- add_plugin_type("codec", check_for_codec_plugin);
+ add_plugin_type("codec", check_for_codec_plugin);
}
static void
register_codec_plugin(gpointer data, gpointer user_data _U_)
{
- codec_plugin *plugin = (codec_plugin *)data;
+ codec_plugin *plugin = (codec_plugin *)data;
- (plugin->register_codec_module)();
+ (plugin->register_codec_module)();
}
/*
@@ -94,15 +102,32 @@ register_codec_plugin(gpointer data, gpointer user_data _U_)
void
register_all_codecs(void)
{
- g_slist_foreach(codec_plugins, register_codec_plugin, NULL);
+ register_codec("g711U", codec_g711u_init, codec_g711u_release,
+ codec_g711u_get_channels, codec_g711u_get_frequency, codec_g711u_decode);
+ register_codec("g711A", codec_g711a_init, codec_g711a_release,
+ codec_g711a_get_channels, codec_g711a_get_frequency, codec_g711a_decode);
+#ifdef HAVE_SPANDSP
+ register_codec("g722", codec_g722_init, codec_g722_release,
+ codec_g722_get_channels, codec_g722_get_frequency, codec_g722_decode);
+ register_codec("g726", codec_g726_init, codec_g726_release,
+ codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+#endif
+#ifdef HAVE_SBC
+ register_codec("SBC", codec_sbc_init, codec_sbc_release,
+ codec_sbc_get_channels, codec_sbc_get_frequency, codec_sbc_decode);
+#endif
+
+ g_slist_foreach(codec_plugins, register_codec_plugin, NULL);
}
#endif /* HAVE_PLUGINS */
struct codec_handle {
- const char *name;
- codec_init_fn init_fn;
- codec_release_fn release_fn;
- codec_decode_fn decode_fn;
+ const char *name;
+ codec_init_fn init_fn;
+ codec_release_fn release_fn;
+ codec_get_channels_fn channels_fn;
+ codec_get_frequency_fn frequency_fn;
+ codec_decode_fn decode_fn;
};
/*
@@ -115,47 +140,76 @@ static GHashTable *registered_codecs = NULL;
codec_handle_t
find_codec(const char *name)
{
- return (registered_codecs) ? (codec_handle_t)g_hash_table_lookup(registered_codecs, name) : NULL;
+ return (registered_codecs) ? (codec_handle_t)g_hash_table_lookup(registered_codecs, name) : NULL;
}
/* Register a codec by name. */
gboolean
-register_codec(const char *name, codec_init_fn init_fn, codec_release_fn release_fn, codec_decode_fn decode_fn)
+register_codec(const char *name, codec_init_fn init_fn, codec_release_fn release_fn,
+ codec_get_channels_fn channels_fn, codec_get_frequency_fn frequency_fn,
+ codec_decode_fn decode_fn)
{
- struct codec_handle *handle;
-
- /* Create our hash table if it doesn't already exist */
- if (registered_codecs == NULL)
- registered_codecs = g_hash_table_new(g_str_hash, g_str_equal);
-
- /* Make sure the registration is unique */
- if (g_hash_table_lookup(registered_codecs, name) != NULL)
- return FALSE; /* report an error, or have our caller do it? */
-
- handle = (struct codec_handle *)g_malloc(sizeof (struct codec_handle));
- handle->name = name;
- handle->init_fn = init_fn;
- handle->release_fn = release_fn;
- handle->decode_fn = decode_fn;
-
- g_hash_table_insert(registered_codecs, (gpointer)name, (gpointer) handle);
- return TRUE;
+ struct codec_handle *handle;
+
+ /* Create our hash table if it doesn't already exist */
+ if (registered_codecs == NULL)
+ registered_codecs = g_hash_table_new(g_str_hash, g_str_equal);
+
+ /* Make sure the registration is unique */
+ if (g_hash_table_lookup(registered_codecs, name) != NULL)
+ return FALSE; /* report an error, or have our caller do it? */
+
+ handle = (struct codec_handle *)g_malloc(sizeof (struct codec_handle));
+ handle->name = name;
+ handle->init_fn = init_fn;
+ handle->release_fn = release_fn;
+ handle->channels_fn = channels_fn;
+ handle->frequency_fn = frequency_fn;
+ handle->decode_fn = decode_fn;
+
+ g_hash_table_insert(registered_codecs, (gpointer)name, (gpointer) handle);
+ return TRUE;
}
void *codec_init(codec_handle_t codec)
{
- if (!codec) return NULL;
- return (codec->init_fn)();
+ if (!codec) return NULL;
+ return (codec->init_fn)();
}
void codec_release(codec_handle_t codec, void *context)
{
- if (!codec) return;
- (codec->release_fn)(context);
+ if (!codec) return;
+ (codec->release_fn)(context);
+}
+
+int codec_get_channels(codec_handle_t codec, void *context)
+{
+ if (!codec) return 0;
+ return (codec->channels_fn)(context);
+}
+
+int codec_get_frequency(codec_handle_t codec, void *context)
+{
+ if (!codec) return 0;
+ return (codec->frequency_fn)(context);
}
int codec_decode(codec_handle_t codec, void *context, const void *input, int inputSizeBytes, void *output, int *outputSizeBytes)
{
- if (!codec) return 0;
- return (codec->decode_fn)(context, input, inputSizeBytes, output, outputSizeBytes);
+ if (!codec) return 0;
+ return (codec->decode_fn)(context, input, inputSizeBytes, output, outputSizeBytes);
}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/codecs.h b/codecs/codecs.h
index 6093b5559c..29ec7e7faa 100644
--- a/codecs/codecs.h
+++ b/codecs/codecs.h
@@ -44,16 +44,37 @@ typedef struct codec_handle *codec_handle_t;
typedef void *(*codec_init_fn)(void);
typedef void (*codec_release_fn)(void *context);
-typedef int (*codec_decode_fn)(void *context, const void *input, int inputSizeBytes, void *output, int *outputSizeBytes);
+typedef int (*codec_get_channels_fn)(void *context);
+typedef int (*codec_get_frequency_fn)(void *context);
+typedef int (*codec_decode_fn)(void *context, const void *input, int inputSizeBytes,
+ void *output, int *outputSizeBytes);
-extern gboolean register_codec(const char *name, codec_init_fn init_fn, codec_release_fn release_fn, codec_decode_fn decode_fn);
+extern gboolean register_codec(const char *name, codec_init_fn init_fn,
+ codec_release_fn release_fn, codec_get_channels_fn channels_fn,
+ codec_get_frequency_fn frequency_fn, codec_decode_fn decode_fn);
extern codec_handle_t find_codec(const char *name);
extern void *codec_init(codec_handle_t codec);
extern void codec_release(codec_handle_t codec, void *context);
-extern int codec_decode(codec_handle_t codec, void *context, const void *input, int inputSizeBytes, void *output, int *outputSizeBytes);
+extern int codec_get_channels(codec_handle_t codec, void *context);
+extern int codec_get_frequency(codec_handle_t codec, void *context);
+extern int codec_decode(codec_handle_t codec, void *context, const void *input,
+ int inputSizeBytes, void *output, int *outputSizeBytes);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _CODECS_H_ */
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/sbc/sbc.c b/codecs/sbc/sbc.c
index b14b5bb681..786144f640 100644
--- a/codecs/sbc/sbc.c
+++ b/codecs/sbc/sbc.c
@@ -31,7 +31,7 @@
#include <glib.h>
#include <sbc/sbc.h>
-#include "sbc.h"
+#include "sbc_private.h"
#define SBC_BUFFER 8192
@@ -40,7 +40,7 @@ codec_sbc_init(void)
{
sbc_t *sbc;
- sbc = g_malloc(sizeof(sbc_t));
+ sbc = (sbc_t *) g_malloc(sizeof(sbc_t));
sbc_init(sbc, 0L);
return sbc;
@@ -98,16 +98,16 @@ int
codec_sbc_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
int *outputSizeBytes)
{
- size_t size_in = (size_t) inputSizeBytes;
- size_t size_out = SBC_BUFFER;
- size_t len;
- int framelen;
- int xframe_pos = 0;
- guint8 *data_in = (guint8 *) input;
- guint8 *data_out = (guint8 *) output;
- sbc_t *sbc = (sbc_t *) ctx;
- guint8 *i_data;
- guint8 tmp;
+ size_t size_in = (size_t) inputSizeBytes;
+ size_t size_out = SBC_BUFFER;
+ size_t len;
+ int framelen;
+ int xframe_pos = 0;
+ const guint8 *data_in = (const guint8 *) input;
+ guint8 *data_out = (guint8 *) output;
+ sbc_t *sbc = (sbc_t *) ctx;
+ guint8 *i_data;
+ guint8 tmp;
if (!output || !outputSizeBytes) {
return size_out;
@@ -136,3 +136,16 @@ codec_sbc_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
}
#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/codecs/sbc/sbc.h b/codecs/sbc/sbc_private.h
index 5cc8ad0927..71f643532b 100644
--- a/codecs/sbc/sbc.h
+++ b/codecs/sbc/sbc_private.h
@@ -28,10 +28,23 @@
#define __CODECS_SBC_H__
void *codec_sbc_init(void);
-void codec_sbc_release(void *ctx);
-int codec_sbc_get_channels(void *ctx);
-int codec_sbc_get_frequency(void *ctx);
-int codec_sbc_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
+void codec_sbc_release(void *ctx);
+int codec_sbc_get_channels(void *ctx);
+int codec_sbc_get_frequency(void *ctx);
+int codec_sbc_decode(void *ctx, const void *input, int inputSizeBytes, void *output,
int *outputSizeBytes);
#endif /* sbc.h */
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/configure.ac b/configure.ac
index 3843403a4a..29ed59a562 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2623,6 +2623,15 @@ AC_CHECK_FUNCS(mmap mprotect sysconf)
dnl blank for now, but will be used in future
AC_SUBST(wireshark_SUBDIRS)
+# Check Bluetooth SBC codec for RTP Player
+# git://git.kernel.org/pub/scm/bluetooth/sbc.git
+PKG_CHECK_MODULES(SBC, sbc >= 1.0, [have_sbc=yes], [have_sbc=no])
+if (test "${have_sbc}" = "yes"); then
+ AC_DEFINE(HAVE_SBC, 1, [Define to support playing SBC by standalone BlueZ SBC library])
+ CFLAGS="$CFLAGS $(pkg-config sbc --cflags)"
+ LIBS="$LIBS $(pkg-config sbc --libs)"
+fi
+
dnl
dnl check whether plugins should be enabled and, if they should be,
dnl check for plugins directory - stolen from Amanda's configure.ac
@@ -3053,3 +3062,4 @@ echo " Use gnutls library : $tls_message"
echo " Use POSIX capabilities library : $libcap_message"
echo " Use GeoIP library : $geoip_message"
echo " Use nl library : $libnl_message"
+echo " Use SBC codec library : $have_sbc"
diff --git a/ui/gtk/rtp_player.c b/ui/gtk/rtp_player.c
index 63c9eca427..6e6d83b39b 100644
--- a/ui/gtk/rtp_player.c
+++ b/ui/gtk/rtp_player.c
@@ -69,8 +69,7 @@
#include <codecs/codecs.h>
#include "../globals.h"
-#include "../codecs/G711a/G711adecode.h"
-#include "../codecs/G711u/G711udecode.h"
+#include "ui/simple_dialog.h"
#include "ui/gtk/gui_utils.h"
#include "ui/gtk/dlg_utils.h"
@@ -84,14 +83,6 @@
#include "ui/gtk/old-gtk-compat.h"
#include "ui/gtk/gui_utils.h"
-/*define this symbol to compile with G729 and G723 codecs*/
-/*#define HAVE_G729_G723 1*/
-
-#ifdef HAVE_G729_G723
-#include "codecs/G729/G729decode.h"
-#include "codecs/G723/G723decode.h"
-#endif /* HAVE_G729_G723 */
-
static gboolean initialized = FALSE;
static voip_calls_tapinfo_t *voip_calls = NULL;
@@ -107,7 +98,9 @@ static GtkWidget *rtp_player_dlg_w;
static GtkWidget *channels_vb;
static GtkWidget *main_scrolled_window = NULL;
static GtkWidget *jitter_spinner;
+static GtkWidget *cb_use_jitter_buffer;
static GtkWidget *cb_use_rtp_timestamp;
+static GtkWidget *cb_use_uninterrupted_mode;
static GtkWidget *cb_view_as_time_of_day;
static GtkWidget *bt_decode;
static GtkWidget *bt_play;
@@ -127,6 +120,7 @@ static int new_jitter_buff;
static GHashTable *rtp_channels_hash = NULL;
static int sample_rate = 8000;
+static int channels = 1;
/* Port Audio stuff */
static int output_channels = 2;
@@ -248,6 +242,10 @@ typedef struct _rtp_decoder_t {
} rtp_decoder_t;
+typedef struct _data_info {
+ int current_channel;
+} data_info;
+
/****************************************************************************/
static void
rtp_key_destroy(gpointer key)
@@ -319,11 +317,15 @@ bt_state(gboolean decode, gboolean play_state, gboolean pause_state, gboolean st
gboolean false_val = FALSE;
gtk_widget_set_sensitive(bt_decode, decode);
+ gtk_widget_set_sensitive(cb_use_jitter_buffer, decode);
gtk_widget_set_sensitive(cb_use_rtp_timestamp, decode);
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb_use_rtp_timestamp))) {
- gtk_widget_set_sensitive(jitter_spinner, FALSE);
- } else {
+ gtk_widget_set_sensitive(cb_use_uninterrupted_mode, decode);
+ gtk_widget_set_sensitive(cb_view_as_time_of_day, decode);
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb_use_jitter_buffer))) {
gtk_widget_set_sensitive(jitter_spinner, decode);
+ } else {
+ gtk_widget_set_sensitive(jitter_spinner, FALSE);
}
if (new_jitter_buff != (int) gtk_spin_button_get_value((GtkSpinButton * )jitter_spinner)) {
@@ -499,7 +501,13 @@ decode_rtp_packet(rtp_packet_t *rp, SAMPLE **out_buff, GHashTable *decoders_hash
decoder = g_new(rtp_decoder_t,1);
decoder->handle = NULL;
decoder->context = NULL;
- p = try_val_to_str_ext(payload_type, &rtp_payload_type_short_vals_ext);
+
+ if (rp->info->info_payload_type_str && find_codec(rp->info->info_payload_type_str)) {
+ p = rp->info->info_payload_type_str;
+ } else {
+ p = try_val_to_str_ext(payload_type, &rtp_payload_type_short_vals_ext);
+ }
+
if (p) {
decoder->handle = find_codec(p);
if (decoder->handle)
@@ -512,57 +520,15 @@ decode_rtp_packet(rtp_packet_t *rp, SAMPLE **out_buff, GHashTable *decoders_hash
tmp_buff = (SAMPLE *)g_malloc(tmp_buff_len);
decoded_bytes = codec_decode(decoder->handle, decoder->context, rp->payload_data, rp->info->info_payload_len, tmp_buff, &tmp_buff_len);
*out_buff = tmp_buff;
- return decoded_bytes;
- }
- /* Try to decode with built-in codec */
-
- switch (payload_type) {
-
- case PT_PCMU: /* G.711 u-law */
- tmp_buff = (SAMPLE *)g_malloc(sizeof(SAMPLE) * rp->info->info_payload_len * 1);
- decodeG711u(rp->payload_data, rp->info->info_payload_len,
- tmp_buff, &decoded_bytes);
- break;
-
- case PT_PCMA: /* G.711 A-law */
- tmp_buff = (SAMPLE *)g_malloc(sizeof(SAMPLE) * rp->info->info_payload_len * 1);
- decodeG711a(rp->payload_data, rp->info->info_payload_len,
- tmp_buff, &decoded_bytes);
- break;
-
-#ifdef HAVE_G729_G723
- case PT_G729: /* G.729 */
- /* G729 8kbps => 64kbps/8kbps = 8 */
- /* Compensate for possible 2 octet SID frame (G.729B) */
- tmp_buff = g_malloc(sizeof(SAMPLE) * ((rp->info->info_payload_len + 8) / 10) * 80);
- decodeG729(rp->payload_data, rp->info->info_payload_len,
- tmp_buff, &decoded_bytes);
- break;
-
- case PT_G723: /* G.723 */
- if (rp->info->info_payload_len%24 == 0) /* G723 High 6.4kbps */
- tmp_buff = g_malloc(sizeof(SAMPLE) * rp->info->info_payload_len * 10); /* G723 High 64kbps/6.4kbps = 10 */
- else if (rp->info->info_payload_len%20 == 0) /* G723 Low 5.3kbps */
- tmp_buff = g_malloc(sizeof(SAMPLE) * rp->info->info_payload_len * 13); /* G723 High 64kbps/5.3kbps = 13 */
- else {
- return 0;
- }
- decodeG723(rp->payload_data, rp->info->info_payload_len,
- tmp_buff, &decoded_bytes);
- break;
-#endif /* HAVE_G729_G723 */
-
- default:
- /*
- * XXX - return an error here, so the user gets told that
- * we don't support this codec!
- */
- break;
+ channels = codec_get_channels(decoder->handle, decoder->context);
+ sample_rate = codec_get_frequency(decoder->handle, decoder->context);
+
+ return decoded_bytes;
}
- *out_buff = tmp_buff;
- return decoded_bytes;
+ *out_buff = NULL;
+ return 0;
}
/****************************************************************************/
@@ -582,7 +548,7 @@ update_progress_bar(gfloat fraction)
/* Decode the RTP streams and add them to the RTP channels struct
*/
static void
-decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
+decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
{
GString *key_str = NULL;
rtp_channel_info_t *rci;
@@ -620,6 +586,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
guint32 progbar_nextstep;
int progbar_quantum;
gfloat progbar_val;
+ data_info *info = (data_info *) ptr;
silence.val = 0;
silence.status = S_NORMAL;
@@ -636,9 +603,9 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
* uses: src_ip:src_port dst_ip:dst_port call_num
*/
key_str = g_string_new("");
- g_string_printf(key_str, "%s:%d %s:%d %d", get_addr_name(&(rsi->src_addr)),
+ g_string_printf(key_str, "%s:%d %s:%d %d %u", get_addr_name(&(rsi->src_addr)),
rsi->src_port, get_addr_name(&(rsi->dest_addr)),
- rsi->dest_port, rsi->call_num );
+ rsi->dest_port, rsi->call_num, info->current_channel);
/* create the rtp_channels_hash table if it doesn't exist */
if (!rtp_channels_hash) {
@@ -729,7 +696,9 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
rp = (rtp_packet_t *)rtp_packets_list->data;
if (first == TRUE) {
- start_timestamp = rp->info->info_timestamp; /* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
+/* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
+/* XXX: if timestamps (RTP) are missing/ignored try use packet arrive time only (see also "rtp_time") */
+ start_timestamp = rp->info->info_timestamp;
start_rtp_time = 0;
rtp_time_prev = start_rtp_time;
first = FALSE;
@@ -767,7 +736,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
fflush(stdout);
#endif
/* if the jitter buffer was exceeded */
- if ( diff*1000 > jitter_buff ) {
+ if ( diff*1000 > jitter_buff && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb_use_uninterrupted_mode))) {
#ifdef DEBUG
printf("Packet drop by jitter buffer exceeded\n");
#endif
@@ -779,8 +748,7 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
#ifdef DEBUG
printf("Resync...\n");
#endif
- silence_frames = (gint32)((arrive_time - arrive_time_prev)*sample_rate - decoded_bytes_prev/2);
-
+ silence_frames = (gint32)((arrive_time - arrive_time_prev)*sample_rate - decoded_bytes_prev / sizeof(SAMPLE));
/* Fix for bug 4119/5902: don't insert too many silence frames.
* XXX - is there a better thing to do here?
*/
@@ -797,14 +765,22 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
}
decoded_bytes_prev = 0;
- start_timestamp = rp->info->info_timestamp; /* defined start_timestamp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
+/* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
+/* XXX: if timestamps (RTP) are missing/ignored try use packet arrive time only (see also "rtp_time") */
+ start_timestamp = rp->info->info_timestamp;
start_rtp_time = 0;
start_time = (double)rp->arrive_offset/1000;
rtp_time_prev = 0;
}
} else {
/* Add silence if it is necessary */
- silence_frames = (gint32)((rtp_time - rtp_time_prev)*sample_rate - decoded_bytes_prev/2);
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb_use_uninterrupted_mode))) {
+ silence_frames = 0;
+ } else {
+ silence_frames = (gint32)((rtp_time - rtp_time_prev)*sample_rate - decoded_bytes_prev / sizeof(SAMPLE));
+ }
+
if (silence_frames != 0) {
rci->wrong_timestamp++;
status = S_WRONG_TIMESTAMP;
@@ -824,20 +800,19 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr _U_)
status = S_NORMAL;
}
-
if (silence_frames > 0) {
silence_frames = 0;
}
+
/* Add the audio */
- for (i = - silence_frames; i< (decoded_bytes/2); i++) {
+ for (i = -silence_frames + ((info->current_channel) ? 1 : 0); i < decoded_bytes / (int) sizeof(SAMPLE); i += channels) {
sample.val = out_buff[i];
sample.status = status;
g_array_append_val(rci->samples, sample);
status = S_NORMAL;
}
-
rtp_time_prev = rtp_time;
- pack_period = (double)(decoded_bytes/2)/sample_rate;
+ pack_period = (double) decoded_bytes / sizeof(SAMPLE) / sample_rate;
decoded_bytes_prev = decoded_bytes;
arrive_time_prev = arrive_time;
}
@@ -1876,13 +1851,13 @@ play_channels(void)
&pa_stream,
paNoDevice, /* default input device */
0, /* no input */
- PA_SAMPLE_TYPE, /* 16 bit Integer input */
+ PA_SAMPLE_TYPE,
NULL,
Pa_GetDefaultOutputDeviceID(),
- output_channels, /* Stereo output */
- PA_SAMPLE_TYPE, /* 16 bit Integer output */
+ output_channels,
+ PA_SAMPLE_TYPE,
NULL,
- sample_rate, /* 8 kHz */
+ sample_rate,
FRAMES_PER_BUFFER,
0, /* number of buffers, if zero then use default minimum */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
@@ -1922,9 +1897,9 @@ play_channels(void)
err = Pa_OpenDefaultStream(
&pa_stream,
0,
- output_channels, /* Stereo output */
- PA_SAMPLE_TYPE, /* 16 bit Integer output */
- sample_rate, /* 8 kHz */
+ output_channels,
+ PA_SAMPLE_TYPE,
+ sample_rate,
FRAMES_PER_BUFFER,
paCallback,
rtp_channels );
@@ -1954,8 +1929,8 @@ play_channels(void)
{
PaStreamParameters stream_parameters;
stream_parameters.device = host_api_info->defaultOutputDevice;
- stream_parameters.channelCount = output_channels; /* Stereo output */
- stream_parameters.sampleFormat = PA_SAMPLE_TYPE; /* 16 bit Integer output */
+ stream_parameters.channelCount = channels;
+ stream_parameters.sampleFormat = PA_SAMPLE_TYPE;
stream_parameters.suggestedLatency = 0;
stream_parameters.hostApiSpecificStreamInfo = NULL;
#ifdef DEBUG
@@ -1965,7 +1940,7 @@ play_channels(void)
&pa_stream,
NULL, /* no input */
&stream_parameters,
- sample_rate, /* 8 kHz */
+ sample_rate,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
paCallback,
@@ -2160,6 +2135,7 @@ decode_streams(void)
{
guint statusbar_context;
guint counter;
+ data_info info;
/* set the sensitive state of the buttons (decode, play, pause, stop) */
bt_state(FALSE, FALSE, FALSE, FALSE);
@@ -2191,7 +2167,12 @@ decode_streams(void)
}
/* Decode the RTP streams and add them to the RTP channels to be played */
- g_list_foreach( rtp_streams_list, (GFunc)decode_rtp_stream, NULL);
+ info.current_channel = 0;
+ g_list_foreach(rtp_streams_list, (GFunc) decode_rtp_stream, &info);
+ if (channels > 1) {
+ info.current_channel = 1;
+ g_list_foreach(rtp_streams_list, (GFunc) decode_rtp_stream, &info);
+ }
/* reset the number of frames to be displayed, this is used for the progress bar */
total_frames = 0;
@@ -2246,7 +2227,7 @@ on_cb_view_as_time_of_day_clicked(GtkButton *button _U_, gpointer user_data _U_)
/****************************************************************************/
static void
-on_cb_use_rtp_clicked(GtkToggleButton *button _U_, gpointer user_data _U_)
+on_cb_use_method_group_clicked(GtkToggleButton *button _U_, gpointer user_data _U_)
{
/* set the sensitive state of the buttons (decode, play, pause, stop) */
bt_state(TRUE, FALSE, FALSE, FALSE);
@@ -2337,7 +2318,7 @@ rtp_player_dlg_create(void)
gchar *win_name;
title_name_ptr = cf_get_display_name(&cfile);
- win_name = g_strdup_printf("%s - VoIP - RTP Player", title_name_ptr);
+ win_name = g_strdup_printf("%s - RTP Player", title_name_ptr);
g_free(title_name_ptr);
rtp_player_dlg_w = dlg_window_new(win_name); /* transient_for top_level */
@@ -2385,11 +2366,20 @@ rtp_player_dlg_create(void)
gtk_widget_set_tooltip_text (jitter_spinner, "The simulated jitter buffer in [ms]");
g_signal_connect(G_OBJECT (jitter_spinner_adj), "value_changed", G_CALLBACK(jitter_spinner_value_changed), NULL);
- cb_use_rtp_timestamp = gtk_check_button_new_with_label("Use RTP timestamp");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb_use_rtp_timestamp), FALSE);
+ cb_use_jitter_buffer = gtk_radio_button_new_with_label(NULL, "Jitter buffer");
+ gtk_box_pack_start(GTK_BOX(h_jitter_buttons_box), cb_use_jitter_buffer, FALSE, FALSE, 10);
+ g_signal_connect(cb_use_jitter_buffer, "toggled", G_CALLBACK(on_cb_use_method_group_clicked), NULL);
+ gtk_widget_set_tooltip_text(cb_use_jitter_buffer, "Use jitter buffer to heard RTP stream as end user");
+
+ cb_use_rtp_timestamp = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(cb_use_jitter_buffer)), "Use RTP timestamp");
gtk_box_pack_start(GTK_BOX(h_jitter_buttons_box), cb_use_rtp_timestamp, FALSE, FALSE, 10);
- g_signal_connect(cb_use_rtp_timestamp, "toggled", G_CALLBACK(on_cb_use_rtp_clicked), NULL);
- gtk_widget_set_tooltip_text (cb_use_rtp_timestamp, "Use RTP Timestamp instead of the arriving packet time. This will not reproduce the RTP stream as the user heard it, but is useful when the RTP is being tunneled and the original packet timing is missing");
+ g_signal_connect(cb_use_rtp_timestamp, "toggled", G_CALLBACK(on_cb_use_method_group_clicked), NULL);
+ gtk_widget_set_tooltip_text(cb_use_rtp_timestamp, "Use RTP Timestamp instead of the arriving packet time. This will not reproduce the RTP stream as the user heard it, but is useful when the RTP is being tunneled and the original packet timing is missing");
+
+ cb_use_uninterrupted_mode = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(cb_use_jitter_buffer)), "Uninterrupted mode");
+ gtk_box_pack_start(GTK_BOX(h_jitter_buttons_box), cb_use_uninterrupted_mode, FALSE, FALSE, 10);
+ g_signal_connect(cb_use_uninterrupted_mode, "toggled", G_CALLBACK(on_cb_use_method_group_clicked), NULL);
+ gtk_widget_set_tooltip_text(cb_use_uninterrupted_mode, "Ignore RTP Timestamp. Play stream as it is completed. It is useful when the RTP timestamp is missing.");
/* button row */
hbuttonbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
@@ -2478,12 +2468,6 @@ rtp_player_init(voip_calls_tapinfo_t *voip_calls_tap)
new_jitter_buff = -1;
-#ifdef HAVE_G729_G723
- /* Initialize the G729 and G723 decoders */
- initG723();
- initG729();
-#endif /* HAVE_G729_G723 */
-
if (!rtp_channels) {
rtp_channels = g_new(rtp_play_channels_t,1);
}