TT#31408 distinguish between codec types

Change-Id: I8c7331908fe4a105d9f9139a5f9867b6ae43a646
changes/75/18775/6
Richard Fuchs 8 years ago
parent 2e43b47305
commit a4a0e34ded

@ -683,6 +683,7 @@ static struct call_media *__get_media(struct call_monologue *ml, GList **it, con
med->call = ml->call; med->call = ml->call;
med->index = sp->index; med->index = sp->index;
call_str_cpy(ml->call, &med->type, &sp->type); call_str_cpy(ml->call, &med->type, &sp->type);
med->type_id = codec_get_type(&med->type);
med->codecs_recv = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL); med->codecs_recv = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
med->codecs_send = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL); med->codecs_send = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
med->codec_names_recv = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free); med->codec_names_recv = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free);

@ -19,6 +19,7 @@
#include "media_socket.h" #include "media_socket.h"
#include "recording.h" #include "recording.h"
#include "statistics.h" #include "statistics.h"
#include "codeclib.h"
#define UNDEFINED ((unsigned int) -1) #define UNDEFINED ((unsigned int) -1)
@ -310,6 +311,7 @@ struct call_media {
unsigned int index; /* RO */ unsigned int index; /* RO */
unsigned int unique_id; /* RO */ unsigned int unique_id; /* RO */
str type; /* RO */ str type; /* RO */
enum media_type type_id; // RO
const struct transport_protocol *protocol; const struct transport_protocol *protocol;
sockfamily_t *desired_family; sockfamily_t *desired_family;
const struct logical_intf *logical_intf; const struct logical_intf *logical_intf;

@ -109,11 +109,11 @@ reset:
STR_FMT(&dest->encoding), dest->clock_rate, dest->channels); STR_FMT(&dest->encoding), dest->clock_rate, dest->channels);
} }
static void __ensure_codec_def(struct rtp_payload_type *pt) { static void __ensure_codec_def(struct rtp_payload_type *pt, struct call_media *media) {
if (pt->codec_def) if (pt->codec_def)
return; return;
pt->codec_def = codec_find(&pt->encoding); pt->codec_def = codec_find(&pt->encoding, media->type_id);
if (!pt->codec_def) if (!pt->codec_def)
return; return;
if (!pt->codec_def->encoder || !pt->codec_def->decoder) if (!pt->codec_def->encoder || !pt->codec_def->decoder)
@ -148,7 +148,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink)
struct rtp_payload_type *pref_dest_codec = NULL; struct rtp_payload_type *pref_dest_codec = NULL;
for (GList *l = sink->codecs_prefs_send.head; l; l = l->next) { for (GList *l = sink->codecs_prefs_send.head; l; l = l->next) {
struct rtp_payload_type *pt = l->data; struct rtp_payload_type *pt = l->data;
__ensure_codec_def(pt); __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->avcodec_id == -1) // not supported, next
continue; continue;
@ -171,7 +171,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink)
GList *insert_pos = NULL; GList *insert_pos = NULL;
for (GList *l = receiver->codecs_prefs_send.head; l; l = l->next) { for (GList *l = receiver->codecs_prefs_send.head; l; l = l->next) {
struct rtp_payload_type *pt = l->data; struct rtp_payload_type *pt = l->data;
__ensure_codec_def(pt); __ensure_codec_def(pt, receiver);
if (!pt->codec_def) if (!pt->codec_def)
continue; continue;
if (g_hash_table_lookup(receiver->codecs_recv, &pt->payload_type)) { if (g_hash_table_lookup(receiver->codecs_recv, &pt->payload_type)) {
@ -242,7 +242,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink)
} }
// check our own support for this codec // check our own support for this codec
__ensure_codec_def(pt); __ensure_codec_def(pt, receiver);
if (!pt->codec_def || pt->codec_def->avcodec_id == -1) { if (!pt->codec_def || pt->codec_def->avcodec_id == -1) {
// not supported, or not a real audio codec // not supported, or not a real audio codec
@ -624,8 +624,9 @@ static struct rtp_payload_type *codec_make_dynamic_payload_type(const codec_def_
// XXX allow specifying codec params (e.g. "transcode=opus/16000/1") // XXX allow specifying codec params (e.g. "transcode=opus/16000/1")
static struct rtp_payload_type *codec_make_payload_type(const str *codec, struct call *call) { static struct rtp_payload_type *codec_make_payload_type(const str *codec, struct call_media *media) {
const codec_def_t *dec = codec_find(codec); struct call *call = media->call;
const codec_def_t *dec = codec_find(codec, media->type_id);
if (!dec) if (!dec)
return NULL; return NULL;
// we must support both encoding and decoding // we must support both encoding and decoding
@ -648,7 +649,7 @@ static struct rtp_payload_type *codec_make_payload_type(const str *codec, struct
static struct rtp_payload_type *codec_add_payload_type(const str *codec, struct call_media *media) { static struct rtp_payload_type *codec_add_payload_type(const str *codec, struct call_media *media) {
struct rtp_payload_type *pt = codec_make_payload_type(codec, media->call); struct rtp_payload_type *pt = codec_make_payload_type(codec, media);
if (!pt) { if (!pt) {
ilog(LOG_WARN, "Codec '" STR_FORMAT "' requested for transcoding is not supported", ilog(LOG_WARN, "Codec '" STR_FORMAT "' requested for transcoding is not supported",
STR_FMT(codec)); STR_FMT(codec));

@ -42,6 +42,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_samplestream, .packetizer = packetizer_samplestream,
.bits_per_sample = 8, .bits_per_sample = 8,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "PCMU", .rtpname = "PCMU",
@ -52,6 +53,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_samplestream, .packetizer = packetizer_samplestream,
.bits_per_sample = 8, .bits_per_sample = 8,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "G723", .rtpname = "G723",
@ -61,6 +63,7 @@ static codec_def_t __codec_defs[] = {
.default_channels = 1, .default_channels = 1,
.default_ptime = 30, .default_ptime = 30,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "G722", .rtpname = "G722",
@ -71,6 +74,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_samplestream, .packetizer = packetizer_samplestream,
.bits_per_sample = 8, .bits_per_sample = 8,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "QCELP", .rtpname = "QCELP",
@ -79,6 +83,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.decode_only_ok = 1, .decode_only_ok = 1,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "G729", .rtpname = "G729",
@ -88,6 +93,7 @@ static codec_def_t __codec_defs[] = {
.default_channels = 1, .default_channels = 1,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "speex", .rtpname = "speex",
@ -97,6 +103,7 @@ static codec_def_t __codec_defs[] = {
.default_bitrate = 11000, .default_bitrate = 11000,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "GSM", .rtpname = "GSM",
@ -105,12 +112,14 @@ static codec_def_t __codec_defs[] = {
.default_channels = 1, .default_channels = 1,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "iLBC", .rtpname = "iLBC",
.avcodec_id = AV_CODEC_ID_ILBC, .avcodec_id = AV_CODEC_ID_ILBC,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "opus", .rtpname = "opus",
@ -121,6 +130,7 @@ static codec_def_t __codec_defs[] = {
.default_bitrate = 32000, .default_bitrate = 32000,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "vorbis", .rtpname = "vorbis",
@ -128,18 +138,21 @@ static codec_def_t __codec_defs[] = {
.avcodec_name = "libvorbis", .avcodec_name = "libvorbis",
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "ac3", .rtpname = "ac3",
.avcodec_id = AV_CODEC_ID_AC3, .avcodec_id = AV_CODEC_ID_AC3,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "eac3", .rtpname = "eac3",
.avcodec_id = AV_CODEC_ID_EAC3, .avcodec_id = AV_CODEC_ID_EAC3,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "ATRAC3", .rtpname = "ATRAC3",
@ -147,6 +160,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.decode_only_ok = 1, .decode_only_ok = 1,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "ATRAC-X", .rtpname = "ATRAC-X",
@ -154,6 +168,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.decode_only_ok = 1, .decode_only_ok = 1,
.type = MT_AUDIO,
}, },
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0) #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
{ {
@ -163,6 +178,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.decode_only_ok = 1, .decode_only_ok = 1,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "EVRC0", .rtpname = "EVRC0",
@ -172,6 +188,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.decode_only_ok = 1, .decode_only_ok = 1,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "EVRC1", .rtpname = "EVRC1",
@ -181,6 +198,7 @@ static codec_def_t __codec_defs[] = {
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.decode_only_ok = 1, .decode_only_ok = 1,
.type = MT_AUDIO,
}, },
#endif #endif
{ {
@ -192,6 +210,7 @@ static codec_def_t __codec_defs[] = {
.default_bitrate = 6600, .default_bitrate = 6600,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "AMR-WB", .rtpname = "AMR-WB",
@ -202,6 +221,7 @@ static codec_def_t __codec_defs[] = {
.default_bitrate = 14250, .default_bitrate = 14250,
.default_ptime = 20, .default_ptime = 20,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
// pseudo-codecs // pseudo-codecs
{ {
@ -209,6 +229,7 @@ static codec_def_t __codec_defs[] = {
.avcodec_id = -1, .avcodec_id = -1,
.avcodec_name = NULL, .avcodec_name = NULL,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
// for file writing // for file writing
{ {
@ -216,12 +237,14 @@ static codec_def_t __codec_defs[] = {
.avcodec_id = AV_CODEC_ID_PCM_S16LE, .avcodec_id = AV_CODEC_ID_PCM_S16LE,
.avcodec_name = NULL, .avcodec_name = NULL,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
{ {
.rtpname = "MP3", .rtpname = "MP3",
.avcodec_id = AV_CODEC_ID_MP3, .avcodec_id = AV_CODEC_ID_MP3,
.avcodec_name = NULL, .avcodec_name = NULL,
.packetizer = packetizer_passthrough, .packetizer = packetizer_passthrough,
.type = MT_AUDIO,
}, },
}; };
@ -231,11 +254,27 @@ static GHashTable *codecs_ht;
const codec_def_t *codec_find(const str *name) { const codec_def_t *codec_find(const str *name, enum media_type type) {
codec_def_t *ret = g_hash_table_lookup(codecs_ht, name); codec_def_t *ret = g_hash_table_lookup(codecs_ht, name);
if (!ret)
return NULL;
if (type && type != ret->type)
return NULL;
return ret; return ret;
} }
enum media_type codec_get_type(const str *type) {
if (!type || !type->len)
return MT_UNKNOWN;
if (!str_cmp(type, "audio"))
return MT_AUDIO;
if (!str_cmp(type, "video"))
return MT_VIDEO;
if (!str_cmp(type, "image"))
return MT_IMAGE;
return MT_OTHER;
}
decoder_t *decoder_new_fmt(const codec_def_t *def, int clockrate, int channels, const format_t *resample_fmt) { decoder_t *decoder_new_fmt(const codec_def_t *def, int clockrate, int channels, const format_t *resample_fmt) {

@ -29,6 +29,14 @@ typedef int packetizer_f(AVPacket *, GString *, str *);
enum media_type {
MT_UNKNOWN = 0,
MT_AUDIO,
MT_VIDEO,
MT_IMAGE,
MT_OTHER,
};
struct codec_def_s { struct codec_def_s {
const char * const rtpname; const char * const rtpname;
int clockrate_mult; int clockrate_mult;
@ -41,6 +49,7 @@ struct codec_def_s {
packetizer_f * const packetizer; packetizer_f * const packetizer;
const int bits_per_sample; const int bits_per_sample;
const int decode_only_ok; const int decode_only_ok;
const enum media_type type;
// filled in by codeclib_init() // filled in by codeclib_init()
str rtpname_str; str rtpname_str;
@ -101,7 +110,8 @@ struct packet_sequencer_s {
void codeclib_init(void); void codeclib_init(void);
const codec_def_t *codec_find(const str *name); const codec_def_t *codec_find(const str *name, enum media_type);
enum media_type codec_get_type(const str *type);
decoder_t *decoder_new_fmt(const codec_def_t *def, int clockrate, int channels, const format_t *resample_fmt); decoder_t *decoder_new_fmt(const codec_def_t *def, int clockrate, int channels, const format_t *resample_fmt);

@ -41,7 +41,7 @@ decoder_t *decoder_new(const char *payload_str) {
channels = 1; channels = 1;
} }
const codec_def_t *def = codec_find(&name); const codec_def_t *def = codec_find(&name, MT_AUDIO);
if (!def) { if (!def) {
ilog(LOG_WARN, "No decoder for payload %s", payload_str); ilog(LOG_WARN, "No decoder for payload %s", payload_str);
return NULL; return NULL;

@ -229,6 +229,6 @@ void output_init(const char *format) {
else else
die("Unknown output format '%s'", format); die("Unknown output format '%s'", format);
output_codec = codec_find(&codec); output_codec = codec_find(&codec, MT_AUDIO);
assert(output_codec != NULL); assert(output_codec != NULL);
} }

Loading…
Cancel
Save