Browse Source

TT#5566 rudimentary support for multiple audio codecs

Change-Id: I7e473f5d17874641253b4b16c3470851743818e1
changes/56/9756/1
Richard Fuchs 9 years ago
parent
commit
30dcadab15
12 changed files with 164 additions and 75 deletions
  1. +1
    -0
      daemon/call.c
  2. +1
    -0
      daemon/call_interfaces.c
  3. +1
    -0
      daemon/recording.c
  4. +8
    -6
      daemon/redis.c
  5. +2
    -47
      daemon/rtp.c
  6. +0
    -8
      daemon/rtp.h
  7. +1
    -0
      daemon/sdp.c
  8. +53
    -0
      lib/rtplib.c
  9. +14
    -0
      lib/rtplib.h
  10. +54
    -3
      recording-daemon/decoder.c
  11. +1
    -1
      recording-daemon/decoder.h
  12. +28
    -10
      recording-daemon/packet.c

+ 1
- 0
daemon/call.c View File

@ -37,6 +37,7 @@
#include "rtpengine_config.h"
#include "log_funcs.h"
#include "recording.h"
#include "rtplib.h"


+ 1
- 0
daemon/call_interfaces.c View File

@ -19,6 +19,7 @@
#include "rtp.h"
#include "ice.h"
#include "recording.h"
#include "rtplib.h"


+ 1
- 0
daemon/recording.c View File

@ -18,6 +18,7 @@
#include "call.h"
#include "kernel.h"
#include "bencode.h"
#include "rtplib.h"


+ 8
- 6
daemon/redis.c View File

@ -1,3 +1,5 @@
#include "redis.h"
#include <stdio.h>
#include <hiredis/hiredis.h>
#include <sys/types.h>
@ -6,9 +8,12 @@
#include <glib.h>
#include <stdarg.h>
#include <ctype.h>
#include <glib.h>
#include "redis.h"
#include <hiredis/hiredis.h>
#include <hiredis/async.h>
#include <hiredis/adapters/libevent.h>
#include <event2/thread.h>
#include "compat.h"
#include "aux.h"
#include "call.h"
@ -18,10 +23,7 @@
#include "crypto.h"
#include "dtls.h"
#include "recording.h"
#include "hiredis/hiredis.h"
#include "hiredis/async.h"
#include "hiredis/adapters/libevent.h"
#include "event2/thread.h"
#include "rtplib.h"


+ 2
- 47
daemon/rtp.c View File

@ -13,44 +13,6 @@
#define RFC_TYPE(type, name, c_rate) \
[type] = { \
.payload_type = type, \
.encoding = STR_CONST_INIT(#name), \
.clock_rate = c_rate, \
}
static const struct rtp_payload_type __rfc_types[] =
{
RFC_TYPE(0, PCMU, 8000),
RFC_TYPE(3, GSM, 8000),
RFC_TYPE(4, G723, 8000),
RFC_TYPE(5, DVI4, 8000),
RFC_TYPE(6, DVI4, 16000),
RFC_TYPE(7, LPC, 8000),
RFC_TYPE(8, PCMA, 8000),
RFC_TYPE(9, G722, 8000),
RFC_TYPE(10, L16, 44100),
RFC_TYPE(11, L16, 44100),
RFC_TYPE(12, QCELP, 8000),
RFC_TYPE(13, CN, 8000),
RFC_TYPE(14, MPA, 90000),
RFC_TYPE(15, G728, 8000),
RFC_TYPE(16, DVI4, 11025),
RFC_TYPE(17, DVI4, 22050),
RFC_TYPE(18, G729, 8000),
RFC_TYPE(25, CelB, 90000),
RFC_TYPE(26, JPEG, 90000),
RFC_TYPE(28, nv, 90000),
RFC_TYPE(31, H261, 90000),
RFC_TYPE(32, MPV, 90000),
RFC_TYPE(33, MP2T, 90000),
RFC_TYPE(34, H263, 90000),
};
INLINE int check_session_keys(struct crypto_context *c) {
str s;
const char *err;
@ -299,18 +261,11 @@ const struct rtp_payload_type *rtp_payload_type(unsigned int type, GHashTable *l
const struct rtp_payload_type *rtp_pt;
if (!lookup)
goto rfc_types;
return rtp_get_rfc_payload_type(type);
rtp_pt = g_hash_table_lookup(lookup, &type);
if (rtp_pt)
return rtp_pt;
rfc_types:
if (type >= G_N_ELEMENTS(__rfc_types))
return NULL;
rtp_pt = &__rfc_types[type];
if (!rtp_pt->encoding.s)
return NULL;
return rtp_pt;
return rtp_get_rfc_payload_type(type);
}

+ 0
- 8
daemon/rtp.h View File

@ -11,14 +11,6 @@
struct crypto_context;
struct rtp_header;
struct rtp_payload_type {
unsigned int payload_type;
str encoding_with_params;
str encoding;
unsigned int clock_rate;
str encoding_parameters;
};


+ 1
- 0
daemon/sdp.c View File

@ -17,6 +17,7 @@
#include "ice.h"
#include "socket.h"
#include "call_interfaces.h"
#include "rtplib.h"
struct network_address {
str network_type;


+ 53
- 0
lib/rtplib.c View File

@ -13,6 +13,47 @@ struct rtp_extension {
#define RFC_TYPE(type, name, c_rate) \
[type] = { \
.payload_type = type, \
.encoding = STR_CONST_INIT(#name), \
.encoding_with_params = STR_CONST_INIT(#name "/" #c_rate), \
.clock_rate = c_rate, \
}
const struct rtp_payload_type rfc_rtp_payload_types[] =
{
RFC_TYPE(0, PCMU, 8000),
RFC_TYPE(3, GSM, 8000),
RFC_TYPE(4, G723, 8000),
RFC_TYPE(5, DVI4, 8000),
RFC_TYPE(6, DVI4, 16000),
RFC_TYPE(7, LPC, 8000),
RFC_TYPE(8, PCMA, 8000),
RFC_TYPE(9, G722, 8000),
RFC_TYPE(10, L16, 44100),
RFC_TYPE(11, L16, 44100),
RFC_TYPE(12, QCELP, 8000),
RFC_TYPE(13, CN, 8000),
RFC_TYPE(14, MPA, 90000),
RFC_TYPE(15, G728, 8000),
RFC_TYPE(16, DVI4, 11025),
RFC_TYPE(17, DVI4, 22050),
RFC_TYPE(18, G729, 8000),
RFC_TYPE(25, CelB, 90000),
RFC_TYPE(26, JPEG, 90000),
RFC_TYPE(28, nv, 90000),
RFC_TYPE(31, H261, 90000),
RFC_TYPE(32, MPV, 90000),
RFC_TYPE(33, MP2T, 90000),
RFC_TYPE(34, H263, 90000),
};
const int num_rfc_rtp_payload_types = G_N_ELEMENTS(rfc_rtp_payload_types);
int rtp_payload(struct rtp_header **out, str *p, const str *s) {
struct rtp_header *rtp;
@ -72,3 +113,15 @@ int rtp_padding(struct rtp_header *header, str *payload) {
payload->len -= padding;
return 0;
}
const struct rtp_payload_type *rtp_get_rfc_payload_type(unsigned int type) {
const struct rtp_payload_type *rtp_pt;
if (type >= num_rfc_rtp_payload_types)
return NULL;
rtp_pt = &rfc_rtp_payload_types[type];
if (!rtp_pt->encoding.s)
return NULL;
return rtp_pt;
}

+ 14
- 0
lib/rtplib.h View File

@ -15,8 +15,22 @@ struct rtp_header {
} __attribute__ ((packed));
struct rtp_payload_type {
unsigned int payload_type;
str encoding_with_params;
str encoding;
unsigned int clock_rate;
str encoding_parameters;
};
extern const struct rtp_payload_type rfc_rtp_payload_types[];
extern const int num_rfc_rtp_payload_types;
int rtp_payload(struct rtp_header **out, str *p, const str *s);
int rtp_padding(struct rtp_header *header, str *payload);
const struct rtp_payload_type *rtp_get_rfc_payload_type(unsigned int type);
#endif

+ 54
- 3
recording-daemon/decoder.c View File

@ -5,6 +5,7 @@
#include <stdint.h>
#include "types.h"
#include "log.h"
#include "str.h"
struct decoder_s {
@ -24,16 +25,66 @@ struct output_s {
};
decoder_t *decoder_new(unsigned int payload_type, const char *payload_str) {
struct decoder_def_s {
const char *name;
int avcodec_id;
};
#define DECODER_DEF(ref, id) { \
.name = #ref, \
.avcodec_id = AV_CODEC_ID_ ## id, \
}
static const struct decoder_def_s decoders[] = {
DECODER_DEF(PCMA, PCM_ALAW),
DECODER_DEF(PCMU, PCM_MULAW),
DECODER_DEF(G723, G723_1),
DECODER_DEF(G722, ADPCM_G722),
DECODER_DEF(QCELP, QCELP),
DECODER_DEF(G729, G729),
DECODER_DEF(speex, SPEEX),
DECODER_DEF(GSM, GSM),
DECODER_DEF(iLBC, ILBC),
DECODER_DEF(opus, OPUS),
};
typedef struct decoder_def_s decoder_def_t;
static const decoder_def_t *decoder_find(const str *name) {
for (int i = 0; i < G_N_ELEMENTS(decoders); i++) {
if (!str_cmp(name, decoders[i].name))
return &decoders[i];
}
return NULL;
}
decoder_t *decoder_new(const char *payload_str) {
str name;
char *slash = strchr(payload_str, '/');
if (!slash) {
ilog(LOG_WARN, "Invalid payload format: %s", payload_str);
return NULL;
}
str_init_len(&name, (char *) payload_str, slash - payload_str);
int clockrate = atoi(slash + 1);
const decoder_def_t *def = decoder_find(&name);
if (!def) {
ilog(LOG_WARN, "No decoder for payload %s", payload_str);
return NULL;
}
decoder_t *ret = g_slice_alloc0(sizeof(*ret));
// XXX error reporting
AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_PCM_ALAW);
AVCodec *codec = avcodec_find_decoder(def->avcodec_id);
ret->avcctx = avcodec_alloc_context3(codec);
if (!ret->avcctx)
goto err;
ret->avcctx->channels = 1;
ret->avcctx->sample_rate = 8000;
ret->avcctx->sample_rate = clockrate;
int i = avcodec_open2(ret->avcctx, codec, NULL);
if (i)
goto err;


+ 1
- 1
recording-daemon/decoder.h View File

@ -5,7 +5,7 @@
#include "str.h"
decoder_t *decoder_new(unsigned int payload_type, const char *payload_str);
decoder_t *decoder_new(const char *payload_str);
int decoder_input(decoder_t *, const str *, unsigned long ts, output_t *);
void decoder_close(decoder_t *);


+ 28
- 10
recording-daemon/packet.c View File

@ -93,6 +93,7 @@ static int ssrc_tree_search(const void *testseq_p, const void *ts_p) {
// ssrc is locked and must be unlocked when returning
// XXX split up function
static void ssrc_run(ssrc_t *ssrc) {
while (1) {
// see if we have a packet with the correct seq nr in the queue
@ -128,24 +129,41 @@ static void ssrc_run(ssrc_t *ssrc) {
}
have_packet:;
dbg("processing packet seq %i", packet->seq);
g_tree_steal(ssrc->packets, GINT_TO_POINTER(packet->seq));
// determine payload type and run decoder
unsigned int payload_type = packet->rtp->m_pt & 0x7f;
metafile_t *mf = ssrc->metafile;
pthread_mutex_lock(&mf->payloads_lock);
char *payload_str = mf->payload_types[payload_type];
pthread_mutex_unlock(&mf->payloads_lock);
// check if we have a decoder for this payload type yet
if (G_UNLIKELY(!ssrc->decoders[payload_type])) {
metafile_t *mf = ssrc->metafile;
pthread_mutex_lock(&mf->payloads_lock);
char *payload_str = mf->payload_types[payload_type];
pthread_mutex_unlock(&mf->payloads_lock);
if (!payload_str) {
const struct rtp_payload_type *rpt = rtp_get_rfc_payload_type(payload_type);
if (!rpt) {
ilog(LOG_WARN, "Unknown RTP payload type %u", payload_type);
goto next_packet;
}
payload_str = rpt->encoding_with_params.s;
}
dbg("processing packet seq %i, payload type is %s", packet->seq, payload_str);
g_tree_steal(ssrc->packets, GINT_TO_POINTER(packet->seq));
dbg("payload type for %u is %s", payload_type, payload_str);
// check if we have a decoder for this payload type yet
if (G_UNLIKELY(!ssrc->decoders[payload_type]))
ssrc->decoders[payload_type] = decoder_new(payload_type, payload_str);
// XXX error handling
ssrc->decoders[payload_type] = decoder_new(payload_str);
if (!ssrc->decoders[payload_type]) {
ilog(LOG_WARN, "Cannot decode RTP payload type %u (%s)",
payload_type, payload_str);
goto next_packet;
}
}
decoder_input(ssrc->decoders[payload_type], &packet->payload, ntohl(packet->rtp->timestamp),
ssrc->output);
next_packet:
ssrc->seq = (packet->seq + 1) & 0xffff;
packet_free(packet);
dbg("packets left in queue: %i", g_tree_nnodes(ssrc->packets));


Loading…
Cancel
Save