Browse Source

TT#28163 logging and documentation improvements

Change-Id: Ib82b80c9ddcf557cd5ab6f99e693a5234471b1ac
changes/46/18946/4
Richard Fuchs 8 years ago
parent
commit
126a69f29c
7 changed files with 104 additions and 23 deletions
  1. +57
    -1
      README.md
  2. +2
    -0
      daemon/call_interfaces.c
  3. +10
    -2
      daemon/codec.c
  4. +8
    -1
      daemon/main.c
  5. +21
    -15
      lib/codeclib.c
  6. +5
    -3
      lib/codeclib.h
  7. +1
    -1
      recording-daemon/main.c

+ 57
- 1
README.md View File

@ -43,6 +43,7 @@ the following additional features are available:
- RTP/RTCP multiplexing (RFC 5761) and demultiplexing
- Breaking of BUNDLE'd media streams (draft-ietf-mmusic-sdp-bundle-negotiation)
- Recording of media streams, decrypted if possible
- Transcoding and repacketization
*Rtpengine* does not (yet) support:
@ -58,7 +59,7 @@ On a Debian System
On a Debian system, everything can be built and packaged into Debian packages
by executing `dpkg-buildpackage` (which can be found in the `dpkg-dev` package) in the main directory.
This script will issue an error and stop if any of the dependency packages are
not installed.
not installed. The script `dpkg-checkbuilddeps` can be used to check missing dependencies.
Before that, run `./debian/flavors/no_ngcp` in order to remove any NGCP dependencies.
@ -96,6 +97,10 @@ The generated files are (with version 2.3.0 being built on an amd64 system):
module for manual compilation. Required for in-kernel operation, but only if the DKMS package
can't be used.
For transcoding purposes, Debian provides an additional package `libavcodec-extra` to replace
the regular `libavcodec` package. It is recommended to install this extra package to offer support
for additional codecs.
Manual Compilation
------------------
@ -115,6 +120,7 @@ There's 3 parts to *rtpengine*, which can be found in the respective subdirector
- *XMLRPC-C* version 1.16.08 or higher
- *hiredis* library
- *libiptc* library for iptables management (optional)
- *ffmpeg* codec libraries for transcoding (options) such as *libavcodec*, *libavfilter*, *libavresample*
The `Makefile` contains a few Debian-specific flags, which may have to removed for compilation to
be successful. This will not affect operation in any way.
@ -123,6 +129,9 @@ There's 3 parts to *rtpengine*, which can be found in the respective subdirector
`Makefile` also contains a switch to disable it. See the `--iptables-chain` option for
a description.
Similarly, the transcoding feature can be excluded via a switch in the `Makefile`, making it
unnecessary to have the *ffmpeg* libraries installed.
* `iptables-extension`
Required for in-kernel packet forwarding.
@ -207,6 +216,7 @@ option and which are reproduced below:
--recording-method=pcap|proc Strategy for call recording
--recording-format=raw|eth PCAP file format for recorded calls.
--iptables-chain=STRING Add explicit firewall rules to this iptables chain
--codecs Print a list of supported codecs and exit
Most of these options are indeed optional, with two exceptions. It's mandatory to specify at least one local
IP address through `--interface`, and at least one of the `--listen-...` options must be given.
@ -855,6 +865,52 @@ then the start-up sequence might look like this:
With this setup, the SIP proxy can choose which instance of *rtpengine* to talk to and thus which local
interface to use by sending its control messages to either port 2223 or port 2224.
Transcoding
===========
Currently transcoding is supported for audio streams. The feature can be disabled on a compile-time
basis, and is enabled by default.
Even though the transcoding feature is available by default, it is not automatically engaged for
normal calls. Normally *rtpengine* leaves codec negotation up to the clients involved in the call
and does not interfere. In this case, if the clients fail to agree on a codec, the call will fail.
The transcoding feature can be engaged for a call by instructing *rtpengine* to do so by using
one of the transcoding options in the *ng* control protocol, such as `transcode` or `ptime` (see below).
If a codec is requested via the `transcode` option that was not originally offered, transcoding will
be engaged for that call.
With transcoding active for a call, all unsupported codecs will be removed from the SDP. Transcoding
happens in userspace only, so in-kernel packet forwarding will not be available for transcoded codecs.
The following codecs are supported by *rtpengine*:
* G.711 (a-Law and µ-Law)
* G.722
* G.723.1
* Speex
* GSM
* iLBC
* Opus
* AMR (narrowband and wideband)
Codec support is dependent on support provided by the `ffmpeg` codec libraries, which may vary from
version to version. Use the `--codecs` command line option to have *rtpengine* print a list of codecs
and their supported status. The list includes some codecs that are not listed above. Some of these
are not actual VoIP codecs (such as MP3), while others lack support for encoding by *ffmpeg* at the
time of writing (such as G.729, QCELP, or ATRAC). If encoding support for these codecs becomes available
in *ffmpeg*, *rtpengine* will be able to support them.
Audio format conversion including resampling and mono/stereo up/down-mixing happens automatically
as required by the codecs involved. For example, one side could be using stereo Opus at 48 kHz
sampling rate, and the other side could be using mono G.711 at 8 kHz, and *rtpengine* will perform
the necessary conversions.
If repacketization (using the `ptime` option) is requested, the transcoding feature will also be
engaged for the call, even if no additional codecs were requested.
Non-audio pseudo-codecs (such as T.38 or RFC 4733 `telephone-event`) are not currently supported.
The *ng* Control Protocol
=========================


+ 2
- 0
daemon/call_interfaces.c View File

@ -1042,9 +1042,11 @@ static void ng_stats_media(bencode_item_t *list, const struct call_media *m,
BF_M("passthrough", PASSTHRU);
BF_M("ICE", ICE);
BF_M("trickle ICE", TRICKLE_ICE);
BF_M("ICE controlling", ICE_CONTROLLING);
BF_M("ICE-lite", ICE_LITE);
BF_M("unidirectional", UNIDIRECTIONAL);
BF_M("loop check", LOOP_CHECK);
BF_M("transcoding", TRANSCODE);
stats:
for (l = m->streams.head; l; l = l->next) {


+ 10
- 2
daemon/codec.c View File

@ -135,7 +135,7 @@ static void __ensure_codec_def(struct rtp_payload_type *pt, struct call_media *m
pt->codec_def = codec_find(&pt->encoding, media->type_id);
if (!pt->codec_def)
return;
if (!pt->codec_def->encoder || !pt->codec_def->decoder)
if (pt->codec_def->avcodec_id != -1 && (!pt->codec_def->encoder || !pt->codec_def->decoder))
pt->codec_def = NULL;
}
static GList *__delete_receiver_codec(struct call_media *receiver, GList *link) {
@ -345,6 +345,8 @@ next:
// the list, as we must expect to potentially receive media in that codec, which we
// then could not transcode.
if (MEDIA_ISSET(receiver, TRANSCODE)) {
ilog(LOG_INFO, "Enabling transcoding engine");
for (GList *l = receiver->codecs_prefs_recv.head; l; ) {
struct rtp_payload_type *pt = l->data;
@ -720,6 +722,7 @@ static struct rtp_payload_type *codec_make_dynamic_payload_type(const codec_def_
}
// special return value `(void *) 0x1` to signal type mismatch
static struct rtp_payload_type *codec_make_payload_type(const str *codec_str, struct call_media *media) {
str codec_fmt = *codec_str;
str codec, parms, chans, opts;
@ -736,9 +739,11 @@ static struct rtp_payload_type *codec_make_payload_type(const str *codec_str, st
if (clockrate && !channels)
channels = 1;
const codec_def_t *dec = codec_find(&codec, media->type_id);
const codec_def_t *dec = codec_find(&codec, 0);
if (!dec)
return NULL;
if (media->type_id && dec->type != media->type_id)
return (void *) 0x1;
// we must support both encoding and decoding
if (!dec->encoder)
return NULL;
@ -769,6 +774,9 @@ static struct rtp_payload_type *codec_add_payload_type(const str *codec, struct
STR_FMT(codec));
return NULL;
}
if (pt == (void *) 0x1)
return NULL;
// find an unused payload type number
if (pt->payload_type < 0)
pt->payload_type = 96; // default first dynamic payload type number


+ 8
- 1
daemon/main.c View File

@ -244,6 +244,7 @@ static void options(int *argc, char ***argv) {
char *homerp = NULL;
char *homerproto = NULL;
char *endptr;
int codecs = 0;
GOptionEntry e[] = {
{ "table", 't', 0, G_OPTION_ARG_INT, &rtpe_config.kernel_table, "Kernel table to use", "INT" },
@ -292,12 +293,18 @@ static void options(int *argc, char ***argv) {
#ifdef WITH_IPTABLES_OPTION
{ "iptables-chain",0,0, G_OPTION_ARG_STRING, &rtpe_config.iptables_chain,"Add explicit firewall rules to this iptables chain","STRING" },
#endif
{ "codecs", 0, 0, G_OPTION_ARG_NONE, &codecs, "Print a list of supported codecs and exit", NULL },
{ NULL, }
};
config_load(argc, argv, e, " - next-generation media proxy",
"/etc/rtpengine/rtpengine.conf", "rtpengine", &rtpe_config.common);
if (codecs) {
codeclib_init(1);
exit(0);
}
if (!if_a)
die("Missing option --interface");
if (!listenps && !listenudps && !listenngs)
@ -556,7 +563,7 @@ static void init_everything() {
if (call_interfaces_init())
abort();
statistics_init();
codeclib_init();
codeclib_init(0);
}


+ 21
- 15
lib/codeclib.c View File

@ -86,7 +86,6 @@ static codec_def_t __codec_defs[] = {
.clockrate_mult = 1,
.default_ptime = 20,
.packetizer = packetizer_passthrough,
.decode_only_ok = 1,
.type = MT_AUDIO,
},
{
@ -169,7 +168,6 @@ static codec_def_t __codec_defs[] = {
.avcodec_id = AV_CODEC_ID_ATRAC3,
.default_ptime = 20,
.packetizer = packetizer_passthrough,
.decode_only_ok = 1,
.type = MT_AUDIO,
},
{
@ -177,7 +175,6 @@ static codec_def_t __codec_defs[] = {
.avcodec_id = AV_CODEC_ID_ATRAC3P,
.default_ptime = 20,
.packetizer = packetizer_passthrough,
.decode_only_ok = 1,
.type = MT_AUDIO,
},
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
@ -187,7 +184,6 @@ static codec_def_t __codec_defs[] = {
.avcodec_name = NULL,
.default_ptime = 20,
.packetizer = packetizer_passthrough,
.decode_only_ok = 1,
.type = MT_AUDIO,
},
{
@ -197,7 +193,6 @@ static codec_def_t __codec_defs[] = {
.default_clockrate = 8000,
.default_ptime = 20,
.packetizer = packetizer_passthrough,
.decode_only_ok = 1,
.type = MT_AUDIO,
},
{
@ -207,7 +202,6 @@ static codec_def_t __codec_defs[] = {
.default_clockrate = 8000,
.default_ptime = 20,
.packetizer = packetizer_passthrough,
.decode_only_ok = 1,
.type = MT_AUDIO,
},
#endif
@ -531,7 +525,7 @@ static void avlog_ilog(void *ptr, int loglevel, const char *fmt, va_list ap) {
free(msg);
}
}
void codeclib_init() {
void codeclib_init(int print) {
av_register_all();
avcodec_register_all();
avfilter_register_all();
@ -577,16 +571,28 @@ void codeclib_init() {
}
// check if we have support if we are supposed to
if (def->avcodec_name || def->avcodec_id >= 0) {
if (!def->encoder && !def->decoder)
ilog(LOG_INFO, "Codec %s is not supported by codec library", def->rtpname);
else if (!def->encoder) {
if (!def->decode_only_ok)
ilog(LOG_INFO, "Codec %s is only supported for decoding by codec library",
if (print) {
if (def->encoder && def->decoder)
printf("%20s: fully supported\n", def->rtpname);
else if (def->decoder)
printf("%20s: supported for decoding only\n", def->rtpname);
else if (def->encoder)
printf("%20s: supported for encoding only\n", def->rtpname);
else
printf("%20s: not supported\n", def->rtpname);
}
else {
if (!def->encoder && !def->decoder)
ilog(LOG_DEBUG, "Codec %s is not supported by codec library",
def->rtpname);
else if (!def->encoder) {
ilog(LOG_DEBUG, "Codec %s is only supported for decoding "
"by codec library", def->rtpname);
}
else if (!def->decoder)
ilog(LOG_DEBUG, "Codec %s is only supported for encoding "
"by codec library", def->rtpname);
}
else if (!def->decoder)
ilog(LOG_INFO, "Codec %s is only supported for encoding by codec library",
def->rtpname);
}
}
}


+ 5
- 3
lib/codeclib.h View File

@ -57,7 +57,6 @@ struct codec_def_s {
int default_ptime;
packetizer_f * const packetizer;
const int bits_per_sample;
const int decode_only_ok;
const enum media_type type;
// codec-specific callbacks
@ -125,7 +124,7 @@ struct packet_sequencer_s {
void codeclib_init(void);
void codeclib_init(int);
const codec_def_t *codec_find(const str *name, enum media_type);
@ -181,7 +180,10 @@ enum media_type {
struct codec_def_s {
};
INLINE void codeclib_init(void) { }
INLINE void codeclib_init(int print) {
if (print)
printf("No codecs supported.\n");
}
INLINE enum media_type codec_get_type(const str *type) {
return -1;


+ 1
- 1
recording-daemon/main.c View File

@ -65,7 +65,7 @@ static void signals(void) {
static void setup(void) {
log_init("rtpengine-recording");
if (output_enabled) {
codeclib_init();
codeclib_init(0);
output_init(output_format);
if (!g_file_test(output_dir, G_FILE_TEST_IS_DIR)) {
ilog(LOG_INFO, "Creating output dir '%s'", output_dir);


Loading…
Cancel
Save