diff --git a/daemon/codec.c b/daemon/codec.c index 51ede04b4..1c184094f 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -140,7 +140,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); - if (!pt->codec_def) // not supported, next + if (!pt->codec_def || pt->codec_def->avcodec_id == -1) // not supported, next continue; ilog(LOG_DEBUG, "Default sink codec is " STR_FORMAT, STR_FMT(&pt->encoding)); pref_dest_codec = pt; @@ -175,9 +175,11 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink) continue; } - ilog(LOG_DEBUG, "Accepting offered codec " STR_FORMAT " due to transcoding", - STR_FMT(&pt->encoding)); - MEDIA_SET(receiver, TRANSCODE); + if (pt->codec_def->avcodec_id != -1) { + ilog(LOG_DEBUG, "Accepting offered codec " STR_FORMAT " due to transcoding", + STR_FMT(&pt->encoding)); + MEDIA_SET(receiver, TRANSCODE); + } // we need a new pt entry pt = __rtp_payload_type_copy(pt); @@ -225,6 +227,12 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink) // check our own support for this codec __ensure_codec_def(pt); + if (!pt->codec_def || pt->codec_def->avcodec_id == -1) { + // not supported, or not a real audio codec + __make_passthrough(handler); + goto next; + } + // if the sink's codec preferences are unknown (empty), or there are // no supported codecs to transcode to, then we have nothing // to do. most likely this is an initial offer without a received answer. diff --git a/lib/codeclib.c b/lib/codeclib.c index 144308f10..21ea55745 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -22,7 +22,15 @@ -#define CODEC_DEF_FULL(ref, id, mult, name, clockrate, channels) { \ +#define CODEC_DEF_FULL(ref, codec_id, mult, name, clockrate, channels) { \ + .rtpname = #ref, \ + .avcodec_id = codec_id, \ + .clockrate_mult = mult, \ + .avcodec_name = #name, \ + .default_clockrate = clockrate, \ + .default_channels = channels, \ +} +#define CODEC_DEF_AVC(ref, id, mult, name, clockrate, channels) { \ .rtpname = #ref, \ .avcodec_id = AV_CODEC_ID_ ## id, \ .clockrate_mult = mult, \ @@ -30,9 +38,9 @@ .default_clockrate = clockrate, \ .default_channels = channels, \ } -#define CODEC_DEF_MULT_NAME(ref, id, mult, name) CODEC_DEF_FULL(ref, id, mult, name, -1, -1) +#define CODEC_DEF_MULT_NAME(ref, id, mult, name) CODEC_DEF_AVC(ref, id, mult, name, -1, -1) #define CODEC_DEF_MULT_NAME_ENC(ref, id, mult, name, clockrate, channels) \ - CODEC_DEF_FULL(ref, id, mult, name, clockrate, channels) + CODEC_DEF_AVC(ref, id, mult, name, clockrate, channels) #define CODEC_DEF_MULT(ref, id, mult) CODEC_DEF_MULT_NAME(ref, id, mult, NULL) #define CODEC_DEF_MULT_ENC(ref, id, mult, clockrate, channels) \ CODEC_DEF_MULT_NAME_ENC(ref, id, mult, NULL, clockrate, channels) @@ -41,6 +49,7 @@ CODEC_DEF_MULT_NAME_ENC(ref, id, 1, name, clockrate, channels) #define CODEC_DEF(ref, id) CODEC_DEF_MULT(ref, id, 1) #define CODEC_DEF_ENC(ref, id, clockrate, channels) CODEC_DEF_MULT_ENC(ref, id, 1, clockrate, channels) +#define CODEC_DEF_STUB(ref) CODEC_DEF_FULL(ref, -1, 1, ref, -1, -1) static const struct codec_def_s codecs[] = { CODEC_DEF(PCMA, PCM_ALAW), @@ -65,6 +74,7 @@ static const struct codec_def_s codecs[] = { #endif CODEC_DEF(AMR, AMR_NB), CODEC_DEF(AMR-WB, AMR_WB), + CODEC_DEF_STUB(telephone-event), }; @@ -83,6 +93,9 @@ const codec_def_t *codec_find(const str *name) { decoder_t *decoder_new_fmt(const codec_def_t *def, int clockrate, int channels, const format_t *resample_fmt) { const char *err = NULL; + if (def->avcodec_id == -1) + return NULL; + clockrate *= def->clockrate_mult; decoder_t *ret = g_slice_alloc0(sizeof(*ret)); diff --git a/recording-daemon/decoder.c b/recording-daemon/decoder.c index e068e881e..0f9046594 100644 --- a/recording-daemon/decoder.c +++ b/recording-daemon/decoder.c @@ -46,6 +46,9 @@ decoder_t *decoder_new(const char *payload_str) { ilog(LOG_WARN, "No decoder for payload %s", payload_str); return NULL; } + if (def->avcodec_id == -1) // not a real audio codec + return NULL; + clockrate *= def->clockrate_mult; if (!resample_audio)