TT#31197 include bcg729 build support

Change-Id: I3862c0b9b8010699e6a49f749b38568d08103840
changes/04/19004/4
Richard Fuchs 7 years ago
parent 83784d492c
commit 9eb9a2f421

@ -29,6 +29,7 @@ flags = [
'-DRE_PLUGIN_DIR="/usr/lib/rtpengine"',
'-DWITH_IPTABLES_OPTION',
'-DWITH_TRANSCODING',
'-DHAVE_BCG729',
'-O2',
'-fstack-protector',
'--param=ssp-buffer-size=4',

@ -3,6 +3,35 @@ TARGET= rtpengine
with_iptables_option ?= yes
with_transcoding ?= yes
# look for bcg729
# /usr/src
ifneq (,$(wildcard /usr/src/bcg729/include/bcg729/decoder.h))
have_bcg729 := yes
bcg729_inc := /usr/src/bcg729/include/
bcg729_lib := /usr/src/bcg729/src/
else
# rfuchs dev
ifneq (,$(wildcard $(HOME)/src/bcg729/include/bcg729/decoder.h))
have_bcg729 := yes
bcg729_inc := $(HOME)/src/bcg729/include/
bcg729_lib := $(HOME)/src/bcg729/src/
else
# home directory
ifneq (,$(wildcard $(HOME)/bcg729/include/bcg729/decoder.h))
have_bcg729 := yes
bcg729_inc := $(HOME)/bcg729/include/
bcg729_lib := $(HOME)/bcg729/src/
else
# included toplevel
ifneq (,$(wildcard ../bcg729/include/bcg729/decoder.h))
have_bcg729 := yes
bcg729_inc := ../bcg729/include/
bcg729_lib := ../bcg729/src/
endif
endif
endif
endif
CFLAGS= -g -Wall -pthread -fno-strict-aliasing
CFLAGS+= -std=c99
CFLAGS+= `pkg-config --cflags glib-2.0`
@ -31,6 +60,9 @@ CFLAGS+= -DWITH_TRANSCODING
else
CFLAGS+= -DWITHOUT_CODECLIB
endif
ifeq ($(have_bcg729),yes)
CFLAGS+= -DHAVE_BCG729 -I$(bcg729_inc)
endif
CFLAGS+= -DRE_PLUGIN_DIR="\"/usr/lib/rtpengine\""
@ -64,6 +96,9 @@ LDFLAGS+= `pkg-config --libs libavutil`
LDFLAGS+= `pkg-config --libs libavresample`
LDFLAGS+= `pkg-config --libs libavfilter`
endif
ifeq ($(have_bcg729),yes)
LDFLAGS+= -L$(bcg729_lib) -lbcg729
endif
include ../lib/lib.Makefile

@ -140,7 +140,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->avcodec_id != -1 && (!pt->codec_def->encoder || !pt->codec_def->decoder))
if (!pt->codec_def->pseudocodec && (!pt->codec_def->support_encoding || !pt->codec_def->support_decoding))
pt->codec_def = NULL;
}
static GList *__delete_receiver_codec(struct call_media *receiver, GList *link) {
@ -176,7 +176,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink)
for (GList *l = sink->codecs_prefs_send.head; l; l = l->next) {
struct rtp_payload_type *pt = l->data;
__ensure_codec_def(pt, sink);
if (!pt->codec_def || pt->codec_def->avcodec_id == -1) // not supported, next
if (!pt->codec_def || pt->codec_def->pseudocodec) // not supported, next
continue;
// fix up ptime
@ -219,7 +219,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink)
continue;
}
if (pt->codec_def->avcodec_id != -1) {
if (!pt->codec_def->pseudocodec) {
ilog(LOG_DEBUG, "Accepting offered codec " STR_FORMAT " due to transcoding",
STR_FMT(&pt->encoding_with_params));
MEDIA_SET(receiver, TRANSCODE);
@ -272,7 +272,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink)
// check our own support for this codec
__ensure_codec_def(pt, receiver);
if (!pt->codec_def || pt->codec_def->avcodec_id == -1) {
if (!pt->codec_def || pt->codec_def->pseudocodec) {
// not supported, or not a real audio codec
__make_passthrough(handler);
passthrough_handlers = g_slist_prepend(passthrough_handlers, handler);
@ -750,9 +750,9 @@ static struct rtp_payload_type *codec_make_payload_type(const str *codec_str, st
if (media->type_id && dec->media_type != media->type_id)
return (void *) 0x1;
// we must support both encoding and decoding
if (!dec->encoder)
if (!dec->support_decoding)
return NULL;
if (!dec->decoder)
if (!dec->support_encoding)
return NULL;
if (dec->rfc_payload_type >= 0) {

@ -23,9 +23,11 @@ flags = [
'-D__DEBUG=1',
'-D__YCM=1',
'-I../daemon',
'-I/home/dfx/src/bcg729/include',
'-DRTPENGINE_VERSION="dummy"',
'-DRE_PLUGIN_DIR="/usr/lib/rtpengine"',
'-DWITH_IPTABLES_OPTION',
'-DHAVE_BCG729',
'-O2',
'-fstack-protector',
'--param=ssp-buffer-size=4',

@ -4,6 +4,10 @@
#include <libavfilter/avfilter.h>
#include <libavutil/opt.h>
#include <glib.h>
#ifdef HAVE_BCG729
#include <bcg729/encoder.h>
#include <bcg729/decoder.h>
#endif
#include "str.h"
#include "log.h"
#include "loglib.h"
@ -34,7 +38,7 @@ static packetizer_f packetizer_samplestream; // flat stream of samples
static format_init_f opus_init;
static set_options_f opus_set_options;
static void avc_def_init(codec_def_t *, int);
static void avc_def_init(codec_def_t *);
static const char *avc_decoder_init(decoder_t *);
static int avc_decoder_input(decoder_t *dec, const str *data, GQueue *out);
static void avc_decoder_close(decoder_t *);
@ -55,6 +59,26 @@ static const codec_type_t codec_type_avcodec = {
.encoder_close = avc_encoder_close,
};
#ifdef HAVE_BCG729
static void bcg729_def_init(codec_def_t *);
static const char *bcg729_decoder_init(decoder_t *);
static int bcg729_decoder_input(decoder_t *dec, const str *data, GQueue *out);
static void bcg729_decoder_close(decoder_t *);
static const char *bcg729_encoder_init(encoder_t *enc);
static int bcg729_encoder_input(encoder_t *enc, AVFrame **frame);
static void bcg729_encoder_close(encoder_t *enc);
static const codec_type_t codec_type_bcg729 = {
.def_init = bcg729_def_init,
.decoder_init = bcg729_decoder_init,
.decoder_input = bcg729_decoder_input,
.decoder_close = bcg729_decoder_close,
.encoder_init = bcg729_encoder_init,
.encoder_input = bcg729_encoder_input,
.encoder_close = bcg729_encoder_close,
};
#endif
static codec_def_t __codec_defs[] = {
@ -115,17 +139,31 @@ static codec_def_t __codec_defs[] = {
.media_type = MT_AUDIO,
.codec_type = &codec_type_avcodec,
},
#ifndef HAVE_BCG729
{
.rtpname = "G729",
.avcodec_id = AV_CODEC_ID_G729,
.clockrate_mult = 1,
.default_clockrate = 8000,
.default_channels = 1,
.default_ptime = 20,
.default_ptime = 10,
.packetizer = packetizer_passthrough,
.media_type = MT_AUDIO,
.codec_type = &codec_type_avcodec,
},
#else
{
.rtpname = "G729",
.avcodec_id = -1,
.clockrate_mult = 1,
.default_clockrate = 8000,
.default_channels = 1,
.default_ptime = 10,
.packetizer = packetizer_passthrough,
.media_type = MT_AUDIO,
.codec_type = &codec_type_bcg729,
},
#endif
{
.rtpname = "speex",
.avcodec_id = AV_CODEC_ID_SPEEX,
@ -276,6 +314,7 @@ static codec_def_t __codec_defs[] = {
.avcodec_name = NULL,
.packetizer = packetizer_passthrough,
.media_type = MT_AUDIO,
.pseudocodec = 1,
},
// for file writing
{
@ -600,7 +639,7 @@ static void avlog_ilog(void *ptr, int loglevel, const char *fmt, va_list ap) {
}
static void avc_def_init(codec_def_t *def, int print) {
static void avc_def_init(codec_def_t *def) {
// look up AVCodec structs
if (def->avcodec_name) {
def->encoder = avcodec_find_encoder_by_name(def->avcodec_name);
@ -614,28 +653,10 @@ static void avc_def_init(codec_def_t *def, int print) {
}
// check if we have support if we are supposed to
if (def->avcodec_name || def->avcodec_id >= 0) {
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);
}
if (def->encoder)
def->support_encoding = 1;
if (def->decoder)
def->support_decoding = 1;
}
}
@ -673,7 +694,33 @@ void codeclib_init(int print) {
def->rfc_payload_type = -1;
if (def->codec_type && def->codec_type->def_init)
def->codec_type->def_init(def, print);
def->codec_type->def_init(def);
if (def->pseudocodec)
continue;
if (print) {
if (def->support_encoding && def->support_decoding)
printf("%20s: fully supported\n", def->rtpname);
else if (def->support_decoding)
printf("%20s: supported for decoding only\n", def->rtpname);
else if (def->support_encoding)
printf("%20s: supported for encoding only\n", def->rtpname);
else
printf("%20s: not supported\n", def->rtpname);
}
else {
if (!def->support_encoding && !def->support_decoding)
ilog(LOG_DEBUG, "Codec %s is not supported by codec library",
def->rtpname);
else if (!def->support_encoding) {
ilog(LOG_DEBUG, "Codec %s is only supported for decoding "
"by codec library", def->rtpname);
}
else if (!def->support_decoding)
ilog(LOG_DEBUG, "Codec %s is only supported for encoding "
"by codec library", def->rtpname);
}
}
}
@ -856,6 +903,7 @@ static const char *avc_encoder_init(encoder_t *enc) {
enc->u.avc.avcctx->sample_fmt = enc->actual_format.format;
enc->u.avc.avcctx->time_base = (AVRational){1,enc->actual_format.clockrate};
enc->u.avc.avcctx->bit_rate = enc->bitrate;
enc->samples_per_frame = enc->actual_format.clockrate * enc->ptime / 1000;
if (enc->u.avc.avcctx->frame_size)
enc->samples_per_frame = enc->u.avc.avcctx->frame_size;
@ -1026,10 +1074,10 @@ int encoder_input_data(encoder_t *enc, AVFrame *frame,
if (ret < 0)
return -1;
//av_write_frame(output->fmtctx, &output->avpkt);
callback(enc, u1, u2);
if (enc->avpkt.size) {
//av_write_frame(output->fmtctx, &output->avpkt);
callback(enc, u1, u2);
//output->fifo_pts += output->frame->nb_samples;
enc->mux_dts = enc->avpkt.dts + 1; // min next expected dts
@ -1168,3 +1216,94 @@ static void opus_set_options(encoder_t *enc) {
ilog(LOG_WARN, "Failed to set Opus frame_duration option (error code %i)", ret);
// XXX additional opus options
}
#ifdef HAVE_BCG729
static void bcg729_def_init(codec_def_t *def) {
// test init
bcg729EncoderChannelContextStruct *e = initBcg729EncoderChannel(0);
bcg729DecoderChannelContextStruct *d = initBcg729DecoderChannel();
if (e) {
def->support_encoding = 1;
closeBcg729EncoderChannel(e);
}
if (d) {
def->support_decoding = 1;
closeBcg729DecoderChannel(d);
}
}
static const char *bcg729_decoder_init(decoder_t *dec) {
dec->u.bcg729 = initBcg729DecoderChannel();
if (!dec->u.bcg729)
return "failed to initialize bcg729";
return NULL;
}
static int bcg729_decoder_input(decoder_t *dec, const str *data, GQueue *out) {
AVFrame *frame = av_frame_alloc();
frame->nb_samples = 80;
frame->format = AV_SAMPLE_FMT_S16;
frame->sample_rate = dec->in_format.clockrate; // 8000
frame->channel_layout = av_get_default_channel_layout(dec->in_format.channels); // 1 channel
if (av_frame_get_buffer(frame, 0) < 0)
abort();
// XXX handle lost packets and comfort noise
bcg729Decoder(dec->u.bcg729, (void *) data->s, data->len, 0, 0, 0, (void *) frame->extended_data[0]);
g_queue_push_tail(out, frame);
return 0;
}
static void bcg729_decoder_close(decoder_t *dec) {
if (dec->u.bcg729)
closeBcg729DecoderChannel(dec->u.bcg729);
dec->u.bcg729 = NULL;
}
static const char *bcg729_encoder_init(encoder_t *enc) {
enc->u.bcg729 = initBcg729EncoderChannel(0); // no VAD
if (!enc->u.bcg729)
return "failed to initialize bcg729";
enc->actual_format.format = AV_SAMPLE_FMT_S16;
enc->actual_format.channels = 1;
enc->actual_format.clockrate = 8000;
enc->samples_per_frame = 80;
return NULL;
}
static int bcg729_encoder_input(encoder_t *enc, AVFrame **frame) {
if (!*frame)
return 0;
if ((*frame)->nb_samples != 80) {
ilog(LOG_ERR, "bcg729: input %u samples instead of 80", (*frame)->nb_samples);
return -1;
}
av_new_packet(&enc->avpkt, 10);
unsigned char len = 0;
bcg729Encoder(enc->u.bcg729, (void *) (*frame)->extended_data[0], enc->avpkt.data, &len);
if (!len) {
av_packet_unref(&enc->avpkt);
return 0;
}
enc->avpkt.size = len;
enc->avpkt.pts = (*frame)->pts;
return 0;
}
static void bcg729_encoder_close(encoder_t *enc) {
if (enc->u.bcg729)
closeBcg729EncoderChannel(enc->u.bcg729);
enc->u.bcg729 = NULL;
}
#endif

@ -13,6 +13,10 @@ typedef struct codec_def_s codec_def_t;
#include <libavresample/avresample.h>
#include <libavcodec/avcodec.h>
#include <libavutil/audio_fifo.h>
#ifdef HAVE_BCG729
#include <bcg729/encoder.h>
#include <bcg729/decoder.h>
#endif
#include "str.h"
@ -49,7 +53,7 @@ enum media_type {
};
struct codec_type_s {
void (*def_init)(codec_def_t *, int print);
void (*def_init)(codec_def_t *);
const char *(*decoder_init)(decoder_t *);
int (*decoder_input)(decoder_t *, const str *data, GQueue *);
@ -80,6 +84,9 @@ struct codec_def_s {
// filled in by codeclib_init()
str rtpname_str;
int rfc_payload_type;
int support_encoding,
support_decoding,
pseudocodec;
const codec_type_t *codec_type;
@ -112,6 +119,9 @@ struct decoder_s {
AVCodecContext *avcctx;
AVPacket avpkt;
} avc;
#ifdef HAVE_BCG729
bcg729DecoderChannelContextStruct *bcg729;
#endif
} u;
unsigned long rtp_ts;
@ -131,6 +141,9 @@ struct encoder_s {
AVCodec *codec;
AVCodecContext *avcctx;
} avc;
#ifdef HAVE_BCG729
bcg729EncoderChannelContextStruct *bcg729;
#endif
} u;
AVPacket avpkt;
AVAudioFifo *fifo;

@ -126,6 +126,7 @@ use IO::Socket;
my %codec_map = (
PCMA => { payload_type => 8 },
PCMU => { payload_type => 0 },
G729 => { payload_type => 18 },
);
my %payload_type_map = map {$codec_map{$_}{payload_type} => $_} keys(%codec_map);

@ -367,10 +367,13 @@ sub _input {
defined($component) or return; # not one of ours
# must be RTP or RTCP input
my $exp = shift(@{$self->{media_receive_queues}->[$component]}) or die;
if (!$self->{args}->{no_data_check}) {
my $exp = shift(@{$self->{media_receive_queues}->[$component]}) or die;
$$input eq $exp or die;
}
else {
@{$self->{media_receive_queues}->[$component]} = ();
}
$self->{media_packets_received}->[$component]++;
$self->{client_components}->[$component] and

@ -7,8 +7,8 @@ use IO::Socket;
my $r = NGCP::Rtpengine::Test->new();
my ($a, $b) = $r->client_pair(
{sockdomain => &Socket::AF_INET, codecs => [qw(PCMA)], no_data_check => 1},
{sockdomain => &Socket::AF_INET, codecs => [qw(PCMU)], no_data_check => 1}
{sockdomain => &Socket::AF_INET, codecs => [qw(PCMU)], no_data_check => 1},
{sockdomain => &Socket::AF_INET, codecs => [qw(G729)], no_data_check => 1}
);
$r->timer_once(3, sub {
@ -18,7 +18,7 @@ $r->timer_once(3, sub {
});
$r->timer_once(10, sub { $r->stop(); });
$a->offer($b, ICE => 'remove', label => "caller", codec => { transcode => ['PCMU']});
$a->offer($b, ICE => 'remove', label => "caller", codec => { transcode => ['G729']});
$b->start_rtp();
$b->start_rtcp();

Loading…
Cancel
Save