codecs: Add support for G.722 and G.726
authorPeter Wu <peter@lekensteyn.nl>
Wed, 23 Nov 2016 23:27:14 +0000 (00:27 +0100)
committerPeter Wu <peter@lekensteyn.nl>
Tue, 6 Dec 2016 17:51:47 +0000 (17:51 +0000)
Integrate the Spandsp library for G.722 and G.726 support. Adds support
for G.722 and all eight variants of G.726.

Note: this also fixes a crash in Qt (buffer overrun, reading too much
data) caused by confusion of the larger output buffer (resample_buff)
with the smaller input buffer (decode_buff). It was not triggered before
because the sample rate was always 8k, but with the addition of the new
codecs, a different sample rate became possible (16k).

Fix also a crash which occurs when the RTP_STREAM_DEBUG macro is enabled
and the VOIP Calls dialog is opened (the begin frame, start_fd, is not
yet known and therfore a NULL dereference could occur).

Passes testing (plays normally without bad RTP timing errors) with
SampleCaptures files: sip-rtp-g722.pcap and sip-rtp-g726.pcap. Tested
with cmake (Qt), autotools (Qt and GTK+) with ASAN enabled.

Bug: 5619
Change-Id: I5661908d193927bba50901079119eeff0c04991f
Reviewed-on: https://code.wireshark.org/review/18939
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
22 files changed:
CMakeLists.txt
CMakeOptions.txt
cmake/modules/FindSPANDSP.cmake [new file with mode: 0644]
cmakeconfig.h.in
codecs/CMakeLists.txt
codecs/G722/G722decode.c
codecs/G722/G722decode.h
codecs/G726/G726decode.c
codecs/G726/G726decode.h
codecs/Makefile.am
codecs/codecs.c
configure.ac
debian/control
docbook/release-notes.asciidoc
packaging/nsis/CMakeLists.txt
packaging/rpm/SPECS/wireshark.spec.in
packaging/wix/CMakeLists.txt
tools/debian-setup.sh
tools/win-setup.ps1
ui/gtk/rtp_player.c
ui/qt/rtp_audio_stream.cpp
ui/qt/rtp_player_dialog.cpp

index 446657c950a34d405505c5b6530f67f71d6efee2..48ff874ae8bfe4fe7591318f93eeb27e0fa13887 100644 (file)
@@ -858,6 +858,10 @@ if(ENABLE_SBC)
        set(PACKAGELIST ${PACKAGELIST} SBC)
 endif()
 
+if(ENABLE_SPANDSP)
+       set(PACKAGELIST ${PACKAGELIST} SPANDSP)
+endif()
+
 # Capabilities
 if(ENABLE_CAP)
        set(PACKAGELIST ${PACKAGELIST} CAP SETCAP)
@@ -966,6 +970,9 @@ endif()
 if(HAVE_LIBSBC)
        set(HAVE_SBC 1)
 endif()
+if(SPANDSP_FOUND)
+       set(HAVE_SPANDSP 1)
+endif()
 if(EXTCAP_ANDROIDDUMP_LIBPCAP)
        set(ANDROIDDUMP_USE_LIBPCAP 1)
 endif()
@@ -1335,6 +1342,7 @@ endforeach()
 include(FeatureSummary)
 #SET_FEATURE_INFO(NAME DESCRIPTION [URL [COMMENT] ])
 SET_FEATURE_INFO(SBC "SBC Codec for Bluetooth A2DP stream playing" "www: http://git.kernel.org/cgit/bluetooth/sbc.git" )
+SET_FEATURE_INFO(SPANDSP "Support for G.722 and G.726 codecs in RTP player" "http://www.soft-switch.org/" )
 SET_FEATURE_INFO(LIBSSH "libssh is library for ssh connections and it is needed to build sshdump/ciscodump" "www: https://www.libssh.org/get-it/" )
 
 FEATURE_SUMMARY(WHAT ALL)
@@ -1607,6 +1615,13 @@ if(WIN32)
                                "${_dll_output_dir}"
                )
        endif(SBC_FOUND)
+       if (SPANDSP_FOUND)
+               add_custom_command(TARGET copy_cli_dlls PRE_BUILD
+                       COMMAND ${CMAKE_COMMAND} -E copy_if_different
+                               "${SPANDSP_DLL_DIR}/${SPANDSP_DLL}"
+                               "${_dll_output_dir}"
+               )
+       endif(SPANDSP_FOUND)
        if (SMI_FOUND)
                # Wireshark.nsi wants SMI_DIR which is the base SMI directory
                get_filename_component(SMI_DIR ${SMI_DLL_DIR} DIRECTORY)
index 41a8ab69cd90b7be726c09def200319f993efca9..7c39b2884f7555deb3e4b8a12b3cf814de699382 100644 (file)
@@ -87,6 +87,7 @@ endif()
 # todo Mostly hardcoded
 option(ENABLE_KERBEROS   "Build with Kerberos support" ON)
 option(ENABLE_SBC        "Build with SBC Codec support in RTP Player" ON)
+option(ENABLE_SPANDSP    "Build with G.722/G.726 codecs support in RTP Player" ON)
 # How to install
 set(DUMPCAP_INSTALL_OPTION   "normal" CACHE STRING "Permissions to install")
 set(DUMPCAP_INST_VALS "normal" "suid" "capabilities")
diff --git a/cmake/modules/FindSPANDSP.cmake b/cmake/modules/FindSPANDSP.cmake
new file mode 100644 (file)
index 0000000..6c64d8f
--- /dev/null
@@ -0,0 +1,55 @@
+# Find the system's Spandsp includes and library
+#
+#  SPANDSP_INCLUDE_DIRS - where to find spandsp.h
+#  SPANDSP_LIBRARIES    - List of libraries when using spandsp
+#  SPANDSP_FOUND        - True if spandsp found
+#  SPANDSP_DLL_DIR      - (Windows) Path to the Spandsp DLL
+#  SPANDSP_DLL          - (Windows) Name of the Spandsp DLL
+
+include( FindWSWinLibs )
+FindWSWinLibs( "spandsp-.*" "SPANDSP_HINTS" )
+
+find_package(PkgConfig)
+pkg_search_module(SPANDSP spandsp)
+
+find_path( SPANDSP_INCLUDE_DIR
+  NAMES spandsp.h
+  HINTS
+    "${SPANDSP_INCLUDEDIR}"
+    "${SPANDSP_HINTS}/include"
+  PATHS /usr/local/include /usr/include
+)
+
+find_library( SPANDSP_LIBRARY
+  NAMES spandsp
+  HINTS
+    "${SPANDSP_LIBDIR}"
+    "${SPANDSP_HINTS}/lib"
+  PATHS /usr/local/lib /usr/lib
+)
+
+include( FindPackageHandleStandardArgs )
+find_package_handle_standard_args( Spandsp DEFAULT_MSG SPANDSP_INCLUDE_DIR SPANDSP_LIBRARY )
+
+if( SPANDSP_FOUND )
+  set( SPANDSP_INCLUDE_DIRS ${SPANDSP_INCLUDE_DIR} )
+  set( SPANDSP_LIBRARIES ${SPANDSP_LIBRARY} )
+  if (WIN32)
+    set ( SPANDSP_DLL_DIR "${SPANDSP_HINTS}/bin"
+      CACHE PATH "Path to spandsp DLL"
+    )
+    file( GLOB _spandsp_dll RELATIVE "${SPANDSP_DLL_DIR}"
+      "${SPANDSP_DLL_DIR}/libspandsp-*.dll"
+    )
+    set ( SPANDSP_DLL ${_spandsp_dll}
+      # We're storing filenames only. Should we use STRING instead?
+      CACHE FILEPATH "spandsp DLL file name"
+    )
+    mark_as_advanced( SPANDSP_DLL_DIR SPANDSP_DLL )
+  endif()
+else()
+  set( SPANDSP_INCLUDE_DIRS )
+  set( SPANDSP_LIBRARIES )
+endif()
+
+mark_as_advanced( SPANDSP_LIBRARIES SPANDSP_INCLUDE_DIRS )
index abf94fdbc88a841d7c185165acdca65bb453af1e..dbdfa8d340ae16d31673611d1cd9a65845408b2c 100644 (file)
 /* Define to 1 if you want to playing SBC by standalone BlueZ SBC library */
 #cmakedefine HAVE_SBC 1
 
+/* Define to 1 if you have the spandsp library. */
+#cmakedefine HAVE_SPANDSP 1
+
 /* Define to 1 if you have the `setresgid' function. */
 #cmakedefine HAVE_SETRESGID 1
 
index 34bd7be88519746bcfdecd23f49d11eca8ee90dc..45950540593a7252125187cc480dd4f979501740 100644 (file)
@@ -23,10 +23,6 @@ set(WSCODECS_FILES
   codecs.c
   G711a/G711adecode.c
   G711u/G711udecode.c
-  # These are wrapped in "#ifdef HAVE_SPANDSP", which we don't currently
-  # handle or define.
-  # G722/G722decode.c
-  # G726/G726decode.c
   speex/resample.c
 )
 
@@ -51,6 +47,11 @@ set(wscodecs_LIBS
   wsutil
 )
 
+if(HAVE_SPANDSP)
+  list(APPEND WSCODECS_FILES G722/G722decode.c G726/G726decode.c)
+  list(APPEND wscodecs_LIBS ${SPANDSP_LIBRARIES})
+endif()
+
 add_library(wscodecs ${LINK_MODE_LIB}
   ${WSCODECS_FILES}
   ${CMAKE_BINARY_DIR}/image/libwscodecs.rc
index af45520d086e09dabe51259d4726f429c1d5fc78..fae16c0626ef9cbd890a009fabd54df92e22505a 100644 (file)
@@ -1,5 +1,5 @@
 /* G722decode.c
- * A-law G.711 codec
+ * G.722 codec
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
 #include <glib.h>
 
 #ifdef HAVE_SPANDSP
-#include "telephony.h"
-#include "g722.h"
+#include "spandsp.h"
 #include "G722decode.h"
 
-static g722_decode_state_t state;
-
 void *
 codec_g722_init(void)
 {
-    memset (&state, 0, sizeof (state));
-    g722_decode_init(&state, 64000, 0);
+    g722_decode_state_t *state;
+
+    /* Valid values for bit_rate for G.722 are 48000, 56000, 64000, but RTP/AVP
+     * profile requires 64kbps, aligned at octets. */
+    state = g722_decode_init(NULL, 64000, 0);
 
-    return NULL;
+    return state;
 }
 
 void
-codec_g722_release(void *ctx _U_)
+codec_g722_release(void *ctx)
 {
+    g722_decode_state_t *state = (g722_decode_state_t *)ctx;
+
+    if (!state) {
+        return;  /* out-of-memory; */
+    }
 
+    /* Note: replaces g722_decode_release since spandsp 20090211 */
+    g722_decode_free(state);
 }
 
-int
+unsigned
 codec_g722_get_channels(void *ctx _U_)
 {
+    /* G.722 has only one channel. */
     return 1;
 }
 
-int
+unsigned
 codec_g722_get_frequency(void *ctx _U_)
 {
-    return 64000;
+    /* Note: RTP Clock rate is 8kHz due to a historic error, but actual sampling
+     * rate is 16kHz (RFC 3551, section 4.5.2). */
+    return 16000;
 }
 
-int
-codec_g722_decode(void *ctx _U_, const void *input, int inputSizeBytes, void *output,
-        int *outputSizeBytes)
+size_t
+codec_g722_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output,
+        size_t *outputSizeBytes)
 {
-    *outputSizeBytes = g722_decode(&state, output, input, inputSizeBytes);
-    return 0;
+    g722_decode_state_t *state = (g722_decode_state_t *)ctx;
+
+    if (!state) {
+        return 0;  /* out-of-memory; */
+    }
+
+    if (!output || !outputSizeBytes) {
+        return 4 * inputSizeBytes;
+    }
+
+    /* g722_decode returns the number of 16-bit samples. */
+    *outputSizeBytes = 2 * g722_decode(state, (int16_t *)output, (const uint8_t *)input, (int)inputSizeBytes);
+    return *outputSizeBytes;
 }
 
 #endif
index fa30a092c01654b99bb5d4bd4e194935e38df3ab..46502632a7b77402d7130dc79ccf9eea6afabd26 100644 (file)
@@ -1,5 +1,5 @@
 /* G722decode.h
- * Definitions for A-law G.722 codec
+ * Definitions for G.722 codec
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
 
 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);
+unsigned codec_g722_get_channels(void *ctx);
+unsigned codec_g722_get_frequency(void *ctx);
+size_t codec_g722_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output,
+        size_t *outputSizeBytes);
 
 #endif /* G722decode.h */
 
index e454be5ac83b28374513fe979326d809d9bef9ab..cb157d6c4617bc52bcfad786d3a92ffe53368380 100644 (file)
 
 #include <glib.h>
 #ifdef HAVE_SPANDSP
-#include "telephony.h"
-#include "bitstream.h"
-#include "g726.h"
+#include "spandsp.h"
 #include "G726decode.h"
 
-/* this isn't reentrant. Making it might involve quite a few changes to be able to pass a g726 state
- * variable to the various functions involved in G.726 decoding.
- */
-static g726_state_t state;
+typedef struct _g726_codec_ctx {
+    g726_state_t *state;
+    int bit_rate;
+} g726_codec_ctx;
 
-/* Currently, only G.726-32, linear encoding, left packed is supported */
-void *
-codec_g726_init(void)
+static inline void *
+codec_g726_init(int bit_rate, int packing)
 {
-    memset (&state, 0, sizeof (state));
-    g726_init(&state, 32000, 0, 1);
+    g726_state_t *decoder = g726_init(NULL, bit_rate, G726_ENCODING_LINEAR, packing);
+
+    if (!decoder) {
+        return NULL;  /* out-of-memory; */
+    }
+
+    g726_codec_ctx *state = g_new(g726_codec_ctx, 1);
+    state->state = decoder;
+    state->bit_rate = bit_rate;
 
-    return NULL;
+    return state;
 }
 
+void *codec_g726_16_init(void) { return codec_g726_init(16000, G726_PACKING_RIGHT); }
+void *codec_g726_24_init(void) { return codec_g726_init(24000, G726_PACKING_RIGHT); }
+void *codec_g726_32_init(void) { return codec_g726_init(32000, G726_PACKING_RIGHT); }
+void *codec_g726_40_init(void) { return codec_g726_init(40000, G726_PACKING_RIGHT); }
+void *codec_aal2_g726_16_init(void) { return codec_g726_init(16000, G726_PACKING_LEFT); }
+void *codec_aal2_g726_24_init(void) { return codec_g726_init(24000, G726_PACKING_LEFT); }
+void *codec_aal2_g726_32_init(void) { return codec_g726_init(32000, G726_PACKING_LEFT); }
+void *codec_aal2_g726_40_init(void) { return codec_g726_init(40000, G726_PACKING_LEFT); }
+
 void
-codec_g726_release(void *ctx _U_)
+codec_g726_release(void *ctx)
 {
+    g726_codec_ctx *state = (g726_codec_ctx *)ctx;
+
+    if (!state) {
+        return;  /* out-of-memory; */
+    }
 
+    /* Note: replaces g726_release since spandsp 20090211 */
+    g726_free(state->state);
+    g_free(state);
 }
 
-int
+unsigned
 codec_g726_get_channels(void *ctx _U_)
 {
     return 1;
 }
 
-int
+unsigned
 codec_g726_get_frequency(void *ctx _U_)
 {
-    return 32000;
+    return 8000;
 }
 
-/* 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
-codec_g726_decode(void *ctx _U_, const void *input, int inputSizeBytes, void *output,
-        int *outputSizeBytes)
+size_t
+codec_g726_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output,
+        size_t *outputSizeBytes)
 {
-    *outputSizeBytes = 2 * g726_decode(&state, output, (void*) input, inputSizeBytes);
-    return 0;
+    g726_codec_ctx *state = (g726_codec_ctx *)ctx;
+
+    if (!state) {
+        return 0;  /* out-of-memory; */
+    }
+
+    if (!output || !outputSizeBytes) {
+        /*
+         * sample rate 8kHz, for bitrate 16kHz we have 16/8 = 2 bits/sample, so
+         * 1 input byte (8 bits) will expand to four 16-bit samples. Likewise,
+         * for bitrate 40kHz we have 40/8 = 5 bits/sample.  Alternatively:
+         * bitsPerSample = bitRate / sampleRate (8kHz).
+         * outputBytes = (inputBits / bitsPerSample) * sizeof(sample)
+         */
+        return inputSizeBytes * 8 / (state->bit_rate / 8000) * 2;
+    }
+
+    /* g726_decode returns the number of 16-bit samples. */
+    *outputSizeBytes = 2 * g726_decode(state->state, (int16_t *)output, (const uint8_t *) input, (int)inputSizeBytes);
+    return *outputSizeBytes;
 }
 
 #endif
index f795c73a14c49b2d9bd4cd9d7c7955c743289530..1ac36eec7fe60238e50649aafa043a778a7bd35a 100644 (file)
@@ -1,5 +1,5 @@
 /* G726decode.h
- * Definitions for A-law G.722 codec
+ * Definitions for G.726 codec
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
 #ifndef __CODECS_G726DECODE_H__
 #define __CODECS_G726DECODE_H__
 
-void *codec_g726_init(void);
+void *codec_g726_16_init(void);
+void *codec_g726_24_init(void);
+void *codec_g726_32_init(void);
+void *codec_g726_40_init(void);
+void *codec_aal2_g726_16_init(void);
+void *codec_aal2_g726_24_init(void);
+void *codec_aal2_g726_32_init(void);
+void *codec_aal2_g726_40_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);
+unsigned codec_g726_get_channels(void *ctx);
+unsigned codec_g726_get_frequency(void *ctx);
+size_t codec_g726_decode(void *ctx, const void *input, size_t inputSizeBytes, void *output,
+        size_t *outputSizeBytes);
 
 #endif /* G726decode.h */
 
index da74a8d87fba13a5a1b3f124a4a3e72a02e5f1a1..46c4190a992bac581d1ba361c2ccbf05e84a2ff2 100644 (file)
@@ -30,14 +30,16 @@ lib_LTLIBRARIES = libwscodecs.la
 libwscodecs_la_SOURCES = \
        codecs.c                \
        G711a/G711adecode.c     \
-       G711u/G711udecode.c     \
-       G722/G722decode.c       \
-       G726/G726decode.c
+       G711u/G711udecode.c
 
 if HAVE_SBC
 libwscodecs_la_SOURCES += sbc/sbc.c
 endif
 
+if HAVE_SPANDSP
+libwscodecs_la_SOURCES += G722/G722decode.c G726/G726decode.c
+endif
+
 if !HAVE_SPEEXDSP
 libwscodecs_la_SOURCES += speex/resample.c
 endif
@@ -45,7 +47,7 @@ endif
 # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
 libwscodecs_la_LDFLAGS = -version-info 0:0:0 @LDFLAGS_SHAREDLIB@
 
-libwscodecs_la_LIBADD = $(top_builddir)/wsutil/libwsutil.la $(GLIB_LIBS) $(SBC_LIBS)
+libwscodecs_la_LIBADD = $(top_builddir)/wsutil/libwsutil.la $(GLIB_LIBS) $(SBC_LIBS) $(SPANDSP_LIBS)
 
 libwscodecs_la_DEPENDENCIES = $(top_builddir)/wsutil/libwsutil.la
 
index 8b6fcb3efcf4ca03796fce45e36abd46d58477cf..447ee67793527648bcc7779773366d74d6482842 100644 (file)
 #include "sbc/sbc_private.h"
 #endif
 
+#ifdef HAVE_SPANDSP
+#include "G722/G722decode.h"
+#include "G726/G726decode.h"
+#endif
+
 #ifdef HAVE_PLUGINS
 
 #include <gmodule.h>
@@ -108,7 +113,21 @@ register_all_codecs(void)
 #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,
+    register_codec("G726-16", codec_g726_16_init, codec_g726_release,
+            codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+    register_codec("G726-24", codec_g726_24_init, codec_g726_release,
+            codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+    register_codec("G726-32", codec_g726_32_init, codec_g726_release,
+            codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+    register_codec("G726-40", codec_g726_40_init, codec_g726_release,
+            codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+    register_codec("AAL2-G726-16", codec_aal2_g726_16_init, codec_g726_release,
+            codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+    register_codec("AAL2-G726-24", codec_aal2_g726_24_init, codec_g726_release,
+            codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+    register_codec("AAL2-G726-32", codec_aal2_g726_32_init, codec_g726_release,
+            codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
+    register_codec("AAL2-G726-40", codec_aal2_g726_40_init, codec_g726_release,
             codec_g726_get_channels, codec_g726_get_frequency, codec_g726_decode);
 #endif
 #ifdef HAVE_SBC
index d39c3746d679bb02a19e77fd46e54028852b61cb..6510b983fe15c48894c30672e5e2c6c54a0d7997 100644 (file)
@@ -2538,6 +2538,27 @@ else
 fi
 AM_CONDITIONAL(HAVE_SBC, test "x$have_sbc" = "xyes")
 
+#`
+# Check Spandsp library for RTP Player
+# http://www.soft-switch.org/
+AC_ARG_WITH([spandsp],
+  AC_HELP_STRING( [--with-spandsp=@<:@yes/no@:>@],
+                 [use Spandsp to play G.722/G.726 codecs @<:@default=yes, if available@:>@]),
+  with_spandsp="$withval"; want_spandsp="yes", with_spandsp="yes")
+
+PKG_CHECK_MODULES(SPANDSP, spandsp, [have_spandsp=yes], [have_spandsp=no])
+if test "x$with_spandsp" != "xno"; then
+    if (test "${have_spandsp}" = "yes"); then
+        AC_DEFINE(HAVE_SPANDSP, 1, [Define if you have the spandsp library])
+    elif test "x$want_spandsp" = "xyes"; then
+        # Error out if the user explicitly requested the spandsp library
+        AC_MSG_ERROR([Spandsp library was requested, but is not available])
+    fi
+else
+    have_spandsp=no
+fi
+AM_CONDITIONAL(HAVE_SPANDSP, test "x$have_spandsp" = "xyes")
+
 dnl
 dnl check whether plugins should be enabled and, if they should be,
 dnl check for plugins directory - stolen from Amanda's configure.ac
@@ -3151,6 +3172,7 @@ echo "                 Use libssh library : $libssh_message"
 echo "            Have ssh_userauth_agent : $ssh_userauth_agent_message"
 echo "                     Use nl library : $libnl_message"
 echo "              Use SBC codec library : $have_sbc"
+echo "                Use Spandsp library : $have_spandsp"
 echo "                Use nghttp2 library : $nghttp2_message"
 echo "                    Use LZ4 library : $have_lz4"
 echo "                 Use Snappy library : $have_snappy"
index 681f8b8c1faa55556dca71ff584ecbf90ef34ddb..9e1cf5b04d515dd348c1b14a24ba5f930ac43b55 100644 (file)
@@ -22,7 +22,7 @@ Build-Depends: libgtk-3-dev, lsb-release,
  libgeoip-dev, dpkg-dev (>= 1.16.1~), imagemagick, xdg-utils,
  libnl-genl-3-dev [linux-any], libnl-route-3-dev [linux-any], asciidoc,
  cmake (>= 2.8.8), w3m, libsbc-dev, libnghttp2-dev, libssh-gcrypt-dev,
- libnghttp2-dev, liblz4-dev, libsnappy-dev
+ liblz4-dev, libsnappy-dev, libspandsp-dev
 Build-Conflicts: libsnmp4.2-dev, libsnmp-dev
 Vcs-Svn: svn://svn.debian.org/svn/collab-maint/ext-maint/wireshark/trunk
 Vcs-Browser: http://svn.debian.org/wsvn/collab-maint/ext-maint/wireshark/trunk/
index 2b9b7d61100b85fdb780b00afd44e8aaf5279c57..83745f4bf1f78decc863f740c5ed97cefde7db4c 100644 (file)
@@ -38,6 +38,7 @@ since version 2.2.0:
 * SS7 Point Codes can now be resolved into names with a hosts-like file.
 * Wireshark can now go fullscreen to have more room for packets.
 * TShark can now export objects like the other GUI interfaces.
+* Support for G.722 and G.726 codecs in the RTP Player (via the Spandsp library).
 
 //=== Removed Dissectors
 
index 3406afe4a8060bc25ce460ee0879af5e49fad23e..9c78f088bbdb2344339924ce4e709fc17e443b4c 100644 (file)
@@ -132,7 +132,7 @@ set(_all_manifest_contents "# Files required for all sections. Generated by CMak
 foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
                ${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
                ${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
-               ${WINSPARKLE_DLL} ${ZLIB_DLL}
+               ${SPANDSP_DLL} ${WINSPARKLE_DLL} ${ZLIB_DLL}
        )
        set(_all_manifest_contents "${_all_manifest_contents}File \"\${STAGING_DIR}\\${_dll}\"\n")
 endforeach()
index df4dbf4e8da9a0e3e567dd1280ea9d291d15d8a7..c2ffb1f581e68d27e68baf774e21893f01856d34 100644 (file)
@@ -12,6 +12,7 @@
 %global with_lz4_and_snappy 1
 %global with_c_ares 1
 %global with_portaudio 0
+%global with_spandsp 0
 %global with_nghttp2 1
 
 # Set at most one of these two:
@@ -234,6 +235,10 @@ BuildRequires:     update-desktop-files
 BuildRequires: portaudio-devel
 Requires:      portaudio
 %endif
+%if %{with_spandsp}
+BuildRequires: spandsp-devel
+Requires:      spandsp
+%endif
 
 # Uncomment these if you want to be sure you get them...
 #BuildRequires:        GeoIP-devel
@@ -268,6 +273,9 @@ This package contains the GTK+ Wireshark GUI and desktop integration files.
 %if %{with_portaudio}
   --with-portaudio \
 %endif
+%if %{with_spandsp}
+  --with-spandsp \
+%endif
 %if %{with qt}
   --with-qt=4 \
 %else
@@ -462,6 +470,9 @@ fi
 %endif
 
 %changelog
+* Mon Dec  5 2016 Jeff Morriss
+- Add spandsp (as an option, defaulting to not required).
+
 * Tue Oct 18 2016 Benoit Canet
 - Add LZ4 and snappy compression support.
 
index 2cc5ea7f412b0006bb31d8d3f82e9ffdd703ddbd..ca37d94ed6973f5ec697369d5509509e7251a282 100644 (file)
@@ -124,7 +124,7 @@ SET(unique_component "")
 foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
                ${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
                ${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
-               ${WINSPARKLE_DLL} ${ZLIB_DLL}
+               ${SPANDSP_DLL} ${WINSPARKLE_DLL} ${ZLIB_DLL}
        )
        #ensure uniqueness of files
        IF(NOT "${unique_component}" MATCHES "(^|;)${_dll}(;|$)")
@@ -149,7 +149,7 @@ SET(unique_file "")
 foreach(_dll ${GLIB2_DLLS} ${CARES_DLL} ${GCRYPT_DLLS} ${GEOIP_DLL}
                ${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
                ${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
-               ${WINSPARKLE_DLL} ${ZLIB_DLL}
+               ${SPANDSP_DLL} ${WINSPARKLE_DLL} ${ZLIB_DLL}
        )
        #ensure uniqueness of files
        IF(NOT "${unique_file}" MATCHES "(^|;)${_dll}(;|$)")
index f38659d3ae4dcad10d6aafde9d1740c8fb7fbc80..932aa78fc6f52dfec3fce72d182e93833545cffe 100755 (executable)
@@ -41,7 +41,7 @@ ADDITIONAL_LIST="libnl-3-dev qttools5-dev qttools5-dev-tools libgtk-3-dev \
                portaudio19-dev asciidoc libgcrypt-dev libsbc-dev libgeoip-dev \
                qtmultimedia5-dev liblua5.2-dev libnl-cli-3-dev \
                libparse-yapp-perl qt5-default cmake libcap-dev \
-               liblz4-dev libsnappy-dev"
+               liblz4-dev libsnappy-dev libspandsp-dev"
 
 # Adds package $2 to list variable $1 if the package is found
 add_package() {
index de3710ebe0455e7fd409e5260316f0697f408ab5..9432864887dd7a86e4431042bb228f1bef79de48 100644 (file)
@@ -99,8 +99,8 @@ Param(
 # trouble instead of trying to catch exceptions everywhere.
 $ErrorActionPreference = "Stop"
 
-$Win64CurrentTag = "2016-10-26"
-$Win32CurrentTag = "2016-10-26"
+$Win64CurrentTag = "2016-11-29"
+$Win32CurrentTag = "2016-11-29"
 
 # Archive file / subdir.
 $Win64Archives = @{
@@ -119,6 +119,7 @@ $Win64Archives = @{
     "portaudio_v19_2.zip" = "";
     "sbc-1.3-win64ws.zip" = "";
     "snappy-1.1.3-win64ws.zip" = "";
+    "spandsp-0.0.6-win64ws.zip" = "";
     "upx303w.zip" = "";
     "WinSparkle-0.3-44-g2c8d9d3-win64ws.zip" = "";
     "WpdPack_4_1_2.zip" = "";
@@ -141,6 +142,7 @@ $Win32Archives = @{
     "portaudio_v19_2.zip" = "";
     "sbc-1.3-win32ws.zip" = "";
     "snappy-1.1.3-win32ws.zip" = "";
+    "spandsp-0.0.6-win32ws.zip" = "";
     "upx303w.zip" = "";
     "WinSparkle-0.3-44-g2c8d9d3-win32ws.zip" = "";
     "WpdPack_4_1_2.zip" = "";
@@ -191,6 +193,7 @@ $CleanupItems = @(
     "portaudio_v19_2"
     "sbc-1.3-win??ws"
     "snappy-1.1.3-win??ws"
+    "spandsp-0.0.6-win??ws"
     "upx301w"
     "upx303w"
     "user-guide"
index 2fd1a5ef329b9964ceee91a3523b00b0afcfa2e0..269db471794a8fbd42a16bcaf0b7481fc77748f3 100644 (file)
@@ -599,7 +599,13 @@ decode_rtp_stream(rtp_stream_info_t *rsi, gpointer ptr)
                        seq = rp->info->info_seq_num;
                }
 
-               rtp_time = (double)(rp->info->info_timestamp-start_timestamp)/sample_rate - start_rtp_time;
+               unsigned rtp_clock_rate = sample_rate;
+               if (rp->info->info_payload_type == PT_G722) {
+                       // G.722 sample rate is 16kHz, but RTP clock rate is 8kHz for historic reasons.
+                       rtp_clock_rate = 8000;
+               }
+
+               rtp_time = (double)(rp->info->info_timestamp-start_timestamp)/rtp_clock_rate - start_rtp_time;
 
                if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb_use_rtp_timestamp))) {
                        arrive_time = rtp_time;
index 1d8971c1d1822c3355e1912e508387f803f9c5da..798d73fcbea6f41edfe7a4d96eccbac21e0a420d 100644 (file)
@@ -252,7 +252,13 @@ void RtpAudioStream::decode()
         }
         last_sequence = rtp_packet->info->info_seq_num;
 
-        double rtp_time = (double)(rtp_packet->info->info_timestamp-start_timestamp)/sample_rate - start_rtp_time;
+        unsigned rtp_clock_rate = sample_rate;
+        if (rtp_packet->info->info_payload_type == PT_G722) {
+            // G.722 sample rate is 16kHz, but RTP clock rate is 8kHz for historic reasons.
+            rtp_clock_rate = 8000;
+        }
+
+        double rtp_time = (double)(rtp_packet->info->info_timestamp-start_timestamp)/rtp_clock_rate - start_rtp_time;
         double arrive_time;
         if (timing_mode_ == RtpTimestamp) {
             arrive_time = rtp_time;
@@ -351,7 +357,7 @@ void RtpAudioStream::decode()
             }
 
             speex_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len);
-            write_buff = (char *) decode_buff;
+            write_buff = (char *) resample_buff;
             write_bytes = out_len * sample_bytes_;
         }
 
index 100daa1adbcde4cba8099baa7ca08c0a8b1615a8..743685c30777dcb41dc3eaca43f25e019cce4a56 100644 (file)
@@ -392,7 +392,7 @@ void RtpPlayerDialog::addRtpStream(struct _rtp_stream_info *rtp_stream)
                      ui->streamTreeWidget->topLevelItemCount(),
                      rtp_stream->packet_count,
                      g_list_length(rtp_stream->rtp_packet_list),
-                     rtp_stream->start_fd->num);
+                     rtp_stream->start_fd ? rtp_stream->start_fd->num : 0);
 }
 
 void RtpPlayerDialog::showEvent(QShowEvent *)