RTP: decode iLBC payload

It is possible to decode iLBC payload. It uses libilbc library (https://github.com/TimothyGu/libilbc).

Bug: 16314
Change-Id: Id4cad7ae32305a0e94ef32beb24e07733d7f834e
Reviewed-on: https://code.wireshark.org/review/35686
Reviewed-by: João Valverde <j@v6e.pt>
Petri-Dish: Pascal Quantin <pascal@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Jirka Novak 2019-11-18 23:55:25 +01:00 committed by Anders Broman
parent 7bd57479b6
commit 12a13a6926
15 changed files with 328 additions and 5 deletions

View File

@ -1154,6 +1154,8 @@ ws_find_package(SPANDSP ENABLE_SPANDSP HAVE_SPANDSP)
ws_find_package(BCG729 ENABLE_BCG729 HAVE_BCG729)
ws_find_package(ILBC ENABLE_ILBC HAVE_ILBC)
# CMake 3.9 and below used 'LIBXML2_LIBRARIES' as the name of the cache entry
# storing the find_library result. Transfer it to the new cache variable such
# that reset_find_package can detect and clear outdated cache variables.
@ -1467,6 +1469,11 @@ if(ENABLE_PLUGINS)
plugins/codecs/G729
)
endif()
if(ILBC_FOUND)
list(APPEND PLUGIN_SRC_DIRS
plugins/codecs/iLBC
)
endif()
if(SBC_FOUND)
list(APPEND PLUGIN_SRC_DIRS
plugins/codecs/sbc
@ -1580,6 +1587,11 @@ set_package_properties(BCG729 PROPERTIES
URL "https://www.linphone.org/technical-corner/bcg729/overview"
PURPOSE "Support for G.729 codec in RTP player"
)
set_package_properties(ILBC PROPERTIES
DESCRIPTION "iLBC decoder"
URL "https://github.com/TimothyGu/libilbc"
PURPOSE "Support for iLBC codec in RTP player"
)
set_package_properties(LIBXML2 PROPERTIES
DESCRIPTION "XML parsing library"
URL "http://xmlsoft.org/"
@ -1846,6 +1858,9 @@ if(WIN32)
if (BCG729_FOUND)
list (APPEND OPTIONAL_DLLS "${BCG729_DLL_DIR}/${BCG729_DLL}")
endif(BCG729_FOUND)
if (ILBC_FOUND)
list (APPEND OPTIONAL_DLLS "${ILBC_DLL_DIR}/${ILBC_DLL}")
endif(ILBC_FOUND)
if (LIBXML2_FOUND)
foreach( _dll ${LIBXML2_DLLS} )
list (APPEND OPTIONAL_DLLS "${LIBXML2_DLL_DIR}/${_dll}")
@ -2975,6 +2990,9 @@ if(RPMBUILD_EXECUTABLE)
if (BCG729_FOUND)
list(APPEND _rpmbuild_with_args --with bcg729)
endif()
if (ILBC_FOUND)
list(APPEND _rpmbuild_with_args --with ilbc)
endif()
if (LIBXML2_FOUND)
list(APPEND _rpmbuild_with_args --with libxml2)
endif()

View File

@ -92,6 +92,7 @@ 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)
option(ENABLE_BCG729 "Build with G.729 codec support in RTP Player" ON)
option(ENABLE_ILBC "Build with iLBC codec support in RTP Player" ON)
option(ENABLE_LIBXML2 "Build with libxml2 support" ON)
# How to install

View File

@ -0,0 +1,77 @@
# Find the system's ilbc includes and library
#
# ILBC_INCLUDE_DIRS - where to find ilbc.h
# ILBC_LIBRARIES - List of libraries when using ilbc
# ILBC_FOUND - True if ilbc found
# ILBC_DLL_DIR - (Windows) Path to the ilbc DLL
# ILBC_DLL - (Windows) Name of the ilbc DLL
include( FindWSWinLibs )
FindWSWinLibs( "libilbc-.*" "ILBC_HINTS" )
if (NOT WIN32)
find_package(PkgConfig)
pkg_search_module(PC_ILBC libilbc)
endif()
find_path(ILBC_INCLUDE_DIR
NAMES ilbc.h
HINTS
"${PC_ILBC_INCLUDE_DIRS}"
"${ILBC_HINTS}/include"
PATHS /usr/local/include /usr/include
)
find_library(ILBC_LIBRARY
NAMES
ilbc
libilbc
HINTS
"${PC_ILBC_LIBRARY_DIRS}"
"${ILBC_HINTS}/lib"
PATHS /usr/local/lib /usr/lib
)
# Check if ilbc library is WebRTC from https://github.com/TimothyGu/libilbc
if(ILBC_INCLUDE_DIR AND ILBC_LIBRARY)
include(CheckSymbolExists)
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES ${ILBC_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${ILBC_LIBRARY})
check_symbol_exists("WebRtcIlbcfix_DecoderCreate" "ilbc.h" HAVE_ILBC_LIB_WEBRTC)
cmake_pop_check_state()
if(NOT HAVE_ILBC_LIB_WEBRTC)
message(STATUS "Ignoring incompatible iLBC library.")
# Unset the variables so the search will rerun next time
set(ILBC_INCLUDE_DIR "ILBC_INCLUDE_DIR-NOTFOUND" CACHE PATH "" FORCE)
set(ILBC_LIBRARY "ILBC_LIBRARY-NOTFOUND" CACHE FILEPATH "" FORCE)
unset(HAVE_ILBC_LIB_WEBRTC CACHE)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(iLBC DEFAULT_MSG ILBC_LIBRARY ILBC_INCLUDE_DIR)
if( ILBC_FOUND )
set( ILBC_INCLUDE_DIRS ${ILBC_INCLUDE_DIR} )
set( ILBC_LIBRARIES ${ILBC_LIBRARY} )
if (WIN32)
set ( ILBC_DLL_DIR "${ILBC_HINTS}/bin"
CACHE PATH "Path to ilbc DLL"
)
file( GLOB _ilbc_dll RELATIVE "${ILBC_DLL_DIR}"
"${ILBC_DLL_DIR}/libilbc.dll"
)
set ( ILBC_DLL ${_ilbc_dll}
# We're storing filenames only. Should we use STRING instead?
CACHE FILEPATH "ilbc DLL file name"
)
mark_as_advanced( ILBC_DLL_DIR ILBC_DLL )
endif()
else()
set( ILBC_INCLUDE_DIRS )
set( ILBC_LIBRARIES )
endif()
mark_as_advanced( ILBC_LIBRARIES ILBC_INCLUDE_DIRS )

View File

@ -278,6 +278,9 @@
/* Define to 1 if you have the bcg729 library. */
#cmakedefine HAVE_BCG729 1
/* Define to 1 if you have the ilbc library. */
#cmakedefine HAVE_ILBC 1
/* Define to 1 if you have the speexdsp library. */
#cmakedefine HAVE_SPEEXDSP 1

View File

@ -39,6 +39,7 @@ since version 3.2.0:
the full names of Protobuf fields or messages in Filter toolbar for searching.
* Dissector based on Protobuf can register itself to a new 'protobuf_field' dissector table,
which is keyed with the full names of fields, for further parsing fields of BYETS or STRING type.
* Wireshark is able to decode, play and save iLBC payload on platforms where iLBC library (https://github.com/TimothyGu/libilbc) is available.
// === Removed Features and Support

View File

@ -150,7 +150,7 @@ foreach(_dll ${CARES_DLL} ${GCRYPT_DLLS}
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLLS} ${WINSPARKLE_DLL}
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL}
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL} ${ILBC_DLL}
# Needed for mmdbresolve
${MAXMINDDB_DLL}
)

View File

@ -1031,6 +1031,7 @@ File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\codecs\g726.dll"
File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\codecs\g729.dll"
File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\codecs\l16mono.dll"
File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\codecs\sbc.dll"
File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\codecs\ilbc.dll"
SectionEnd
Section "Configuration Profiles" SecProfiles

View File

@ -20,6 +20,7 @@
%bcond_with guides
%bcond_with brotli
%bcond_with zstd
%bcond_with ilbc
# Set at most one of these two:
# Note that setcap requires rpmbuild 4.7.0 or later.
@ -340,6 +341,11 @@ cmake3 \
%if %{with ninja}
-G Ninja \
%endif
%if %{with ilbc}
-DENABLE_ILBC=ON \
%else
-DENABLE_ILBC=OFF \
%endif
%if %{with ninja}
# Older RPM-based distributions used ninja-build in order to prevent a collision with
@ -497,6 +503,9 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
%{_libdir}/pkgconfig/wireshark.pc
%changelog
* Sun Jan 19 2019 Jiri Novak
- Added ilbc codec as an option
* Fri Nov 22 2019 Gerald Combs
- c-ares is a required package

View File

@ -135,7 +135,7 @@ foreach(_dll ${CARES_DLL} ${GCRYPT_DLLS}
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLLS} ${WINSPARKLE_DLL}
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL}
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL} ${ILBC_DLL}
# Required for mmdbresolve
${MAXMINDDB_DLL}
)
@ -174,7 +174,7 @@ foreach(_dll ${CARES_DLL} ${GCRYPT_DLLS}
${GNUTLS_DLLS} ${KERBEROS_DLLS} ${LIBSSH_DLL} ${LUA_DLL}
${LZ4_DLL} ${NGHTTP2_DLL} ${SBC_DLL} ${SMI_DLL} ${SNAPPY_DLL}
${SPANDSP_DLL} ${BCG729_DLL} ${LIBXML2_DLLS} ${WINSPARKLE_DLL}
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL}
${ZLIB_DLL} ${BROTLI_DLLS} ${ZSTD_DLL} ${ILBC_DLL}
# mmdbresolve
${MAXMINDDB_DLL}
)

View File

@ -126,6 +126,9 @@
<Component Id="cmpSBC_dll" Guid="*">
<File Id="filSBC_dll" KeyPath="yes" Source="$(var.Plugins.Dir)\$(var.WiresharkMajorVersion).$(var.WiresharkMinorVersion)\codecs\sbc.dll" />
</Component>
<Component Id="cmpILBC_dll" Guid="*">
<File Id="filILBC_dll" KeyPath="yes" Source="$(var.Plugins.Dir)\$(var.WiresharkMajorVersion).$(var.WiresharkMinorVersion)\codecs\ilbc.dll" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
@ -136,6 +139,7 @@
<ComponentRef Id="cmpG729_dll" />
<ComponentRef Id="cmpL16mono_dll" />
<ComponentRef Id="cmpSBC_dll" />
<ComponentRef Id="cmpILBC_dll" />
</ComponentGroup>
</Fragment>

View File

@ -0,0 +1,70 @@
# CMakeLists.txt
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
include(WiresharkPlugin)
# Plugin name and version info (major minor micro extra)
set_module_info(ilbc 0 1 0 0)
set(CODEC_SRC
iLBCdecode.c
)
set(PLUGIN_FILES
plugin.c
${CODEC_SRC}
)
set_source_files_properties(
${PLUGIN_FILES}
PROPERTIES
COMPILE_FLAGS "${WERROR_COMMON_FLAGS}"
)
include_directories(
${CMAKE_SOURCE_DIR}/codecs
${CMAKE_CURRENT_SOURCE_DIR}
)
register_plugin_files(plugin.c
plugin_codec
${CODEC_SRC}
)
add_plugin_library(ilbc codecs)
target_link_libraries(ilbc wsutil ${ILBC_LIBRARIES})
target_include_directories(ilbc SYSTEM PRIVATE ${ILBC_INCLUDE_DIRS})
install_plugin(ilbc codecs)
file(GLOB CODEC_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h")
CHECKAPI(
NAME
ilbc
SWITCHES
-g abort -g termoutput -build
SOURCES
${CODEC_SRC}
${CODEC_HEADERS}
)
#
# Editor modelines - https://www.wireshark.org/tools/modelines.html
#
# Local variables:
# c-basic-offset: 8
# tab-width: 8
# indent-tabs-mode: t
# End:
#
# vi: set shiftwidth=8 tabstop=8 noexpandtab:
# :indentSize=8:tabSize=8:noTabs=false:
#

View File

@ -0,0 +1,129 @@
/* iLBCdecode.c
* iLBC codec
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <stdio.h>
#include <glib.h>
#include "ilbc.h"
#include "wsutil/codecs.h"
#include "ws_attributes.h"
#define ILBC_20MS 20
#define ILBC_30MS 30
#define ILBC_PAYLOAD_LEN_20MS 38
#define ILBC_PAYLOAD_LEN_30MS 50
#define SAMPLE_SIZE 2
typedef struct {
iLBC_decinst_t *ilbc_ctx; /* Real iLBC context */
guint8 payload_len; /* Remember last payload_len */
} ilbc_ctx_t;
static void *
codec_iLBC_init(void)
{
ilbc_ctx_t *ctx;
ctx=(ilbc_ctx_t *)g_malloc0(sizeof(*ctx));
WebRtcIlbcfix_DecoderCreate(&(ctx->ilbc_ctx));
return ctx;
}
static void
codec_iLBC_release(void *ctx)
{
WebRtcIlbcfix_DecoderFree(((ilbc_ctx_t *)ctx)->ilbc_ctx);
g_free(ctx);
}
static unsigned
codec_iLBC_get_channels(void *ctx _U_)
{
return 1;
}
static unsigned
codec_iLBC_get_frequency(void *ctx _U_)
{
return 8000;
}
static size_t
codec_iLBC_decode(void *ctx, const void *inputBytes, size_t inputBytesSize,
void *outputSamples, size_t *outputSamplesSize)
{
int16_t speechType; // Not used in Wireshark code
int16_t *dataIn = (int16_t *)inputBytes;
int16_t *dataOut = (int16_t *)outputSamples;
ilbc_ctx_t *dataCtx = (ilbc_ctx_t *)ctx;
size_t outputSamplesCount;
if (!outputSamples || !outputSamplesSize)
{
if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_20MS) {
/* 20ms packet size = 160 samples = 320 bytes */
return BLOCKL_20MS*SAMPLE_SIZE;
} else if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_30MS) {
/* 30ms packet size = 240 samples = 480 bytes */
return BLOCKL_30MS*SAMPLE_SIZE;
} else {
/* unknown packet size */
return 0;
}
}
if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_20MS) {
/* 20ms packet size */
if (dataCtx->payload_len != ILBC_20MS) {
WebRtcIlbcfix_DecoderInit(dataCtx->ilbc_ctx, ILBC_20MS);
dataCtx->payload_len = ILBC_20MS;
}
outputSamplesCount = WebRtcIlbcfix_Decode(dataCtx->ilbc_ctx, dataIn,
(int16_t)inputBytesSize, dataOut, &speechType);
} else if (0 == inputBytesSize%ILBC_PAYLOAD_LEN_30MS) {
/* 30ms packet size */
if (dataCtx->payload_len != ILBC_30MS) {
WebRtcIlbcfix_DecoderInit(dataCtx->ilbc_ctx, ILBC_30MS);
dataCtx->payload_len = ILBC_30MS;
}
outputSamplesCount = WebRtcIlbcfix_Decode(dataCtx->ilbc_ctx, dataIn,
(int16_t)inputBytesSize, dataOut, &speechType);
} else {
/* unknown packet size */
outputSamplesCount = 0;
}
/* WebRtcIlbcfix_Decode returns count of samples, but we return count of bytes */
*outputSamplesSize = outputSamplesCount*SAMPLE_SIZE;
return *outputSamplesSize;
}
void
codec_register_iLBC(void)
{
register_codec("iLBC", codec_iLBC_init, codec_iLBC_release,
codec_iLBC_get_channels, codec_iLBC_get_frequency, codec_iLBC_decode);
}
/*
* Editor modelines - https://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:
*/

View File

@ -155,6 +155,10 @@ add_package ADDITIONAL_LIST libsystemd-dev ||
add_package ADDITIONAL_LIST libsystemd-journal-dev ||
echo "libsystemd-dev is unavailable"
# ilbc library from http://www.deb-multimedia.org
add_package ADDITIONAL_LIST libilbc-dev ||
echo "libilbc-dev is unavailable"
# softhsm2 2.0.0: Ubuntu 16.04
# softhsm2 2.2.0: Debian >= jessie-backports, Ubuntu 18.04
# softhsm2 >= 2.4.0: Debian >= buster, Ubuntu >= 18.10

View File

@ -219,6 +219,9 @@ echo "speex is unavailable" >&2
add_package ADDITIONAL_LIST libnl3-devel || add_package ADDITIONAL_LIST libnl-devel ||
echo "libnl3/libnl are unavailable" >&2
add_package ADDITIONAL_LIST ilbc-devel ||
echo "ilbc is unavailable" >&2
ACTUAL_LIST=$BASIC_LIST
# Now arrange for optional support libraries

View File

@ -69,8 +69,8 @@ Param(
# trouble instead of trying to catch exceptions everywhere.
$ErrorActionPreference = "Stop"
$Win64CurrentTag = "2019-12-18"
$Win32CurrentTag = "2019-12-18"
$Win64CurrentTag = "2020-01-09"
$Win32CurrentTag = "2020-01-09"
# Archive file / SHA256
$Win64Archives = @{
@ -81,6 +81,7 @@ $Win64Archives = @{
"gnutls-3.6.3-1-win64ws.zip" = "994ac2578e7b4ca01e589ab2598927d53f7370bc3ff679f3006b0e6bb7a06df4";
"krb5-1.17-1-win64ws.zip" = "1f4a7ab86ae331ea9e58c9776a60def81ae9fe622882b2e8da2ad6ce6f6fb1d8";
"libgcrypt-1.8.3-win64ws.zip" = "53b1c636cb89de308ca4ea01b4990cf1deca7f6c2446189c7ff6e971137ffd76";
"libilbc-2.0.2-3-win64ws.zip" = "d7baeb98627c405bd7c3e41d6b07c4ea4f0f5db88436e566148320afd10cbb66";
"libsmi-svn-40773-win64ws.zip" = "571fcee71d741bf847c3247d4c2e1c42388ca6a9feebe08fc0d4ce053571d15d";
"libssh-0.7.3-1-win64ws.zip" = "3a81b9f4a914a46f15243bbb13b6919ef1c20d4bf502c47646caeccff2cbd75c";
"lua-5.2.4-unicode-win64-vc14.zip" = "e8968d2c7871ce1ea82cbd29ac1b3a2c59d3dec25e483c5e12de85df66f5d928";
@ -105,6 +106,7 @@ $Win32Archives = @{
"gnutls-3.6.3-1-win32ws.zip" = "42d8313ffb888f525d6c39330c39bcc2182e68ee8433a09dd85e1f1e1474f592";
"krb5-1.17-1-win32ws.zip" = "f90cac08355ccfe624652d3e05f8e2e077b8830382315d4ea0a6fa52af08260b";
"libgcrypt-1.8.3-win32ws.zip" = "409b72f2809019050cca91b9e670047c50a0752ff52999089178da54ef926393";
"libilbc-2.0.2-3-win32ws.zip" = "e8582a98024d619f80e1212a7ef3179390f33b21697004cfd487f34fa886145c";
"libsmi-svn-40773-win32ws.zip" = "44bc81edfeb8948322ca365fc632e419383907c305cc922e6b74fdbb13827958";
"libssh-0.7.3-1-win32ws.zip" = "b02f0d318175194ac538a24c9c9fc280a0ecad69fb3afd4945c106b4b7c4fa6f";
"lua-5.2.4-unicode-win32-vc14.zip" = "ca2368a83f623674178e9441f71fb791e3c0b46f208e3dac28c6ac735f034bff";
@ -161,6 +163,7 @@ $CleanupItems = @(
"kfw-3-2-2*"
"krb5-*-win??ws"
"libgcrypt-*-win??ws"
"libilbc-2.0.2-3-win??ws"
"libsmi-0.4.8"
"libsmi-svn-40773-win??ws"
"libssh-0.7.?-win??ws"