|
|
|
|
@ -37,10 +37,8 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.rtpname = "PCMA",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_PCM_ALAW,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_samplestream,
|
|
|
|
|
.bits_per_sample = 8,
|
|
|
|
|
@ -49,10 +47,8 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.rtpname = "PCMU",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_PCM_MULAW,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_samplestream,
|
|
|
|
|
.bits_per_sample = 8,
|
|
|
|
|
@ -61,22 +57,17 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.rtpname = "G723",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_G723_1,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 30,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "G722",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_ADPCM_G722,
|
|
|
|
|
.clockrate_mult = 2,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_samplestream,
|
|
|
|
|
.bits_per_sample = 8,
|
|
|
|
|
@ -85,207 +76,152 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.rtpname = "QCELP",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_QCELP,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
.decode_only_ok = 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "G729",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_G729,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "speex",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_SPEEX,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 16000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 11000,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "GSM",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_GSM,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "iLBC",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_ILBC,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "opus",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_OPUS,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = "libopus",
|
|
|
|
|
.default_clockrate = 48000,
|
|
|
|
|
.default_channels = 2,
|
|
|
|
|
.default_bitrate = 32000,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "vorbis",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_VORBIS,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = "libvorbis",
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "ac3",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_AC3,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "eac3",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_EAC3,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "ATRAC3",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_ATRAC3,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
.decode_only_ok = 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "ATRAC-X",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_ATRAC3P,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
.decode_only_ok = 1,
|
|
|
|
|
},
|
|
|
|
|
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "EVRC",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_EVRC,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = 0,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
.decode_only_ok = 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "EVRC0",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_EVRC,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = -1,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
.decode_only_ok = 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "EVRC1",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_EVRC,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = -1,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
.decode_only_ok = 1,
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "AMR",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_AMR_NB,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 8000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 6600,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "AMR-WB",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_AMR_NB,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = 16000,
|
|
|
|
|
.default_channels = 1,
|
|
|
|
|
.default_bitrate = 14250,
|
|
|
|
|
.default_ptime = 20,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
// pseudo-codecs
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "telephone-event",
|
|
|
|
|
.avcodec_id = -1,
|
|
|
|
|
.clockrate_mult = 1,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.default_clockrate = -1,
|
|
|
|
|
.default_channels = -1,
|
|
|
|
|
.default_bitrate = -1,
|
|
|
|
|
.default_ptime = -1,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.bits_per_sample = 0,
|
|
|
|
|
},
|
|
|
|
|
// for file writing
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "PCM-S16LE",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_PCM_S16LE,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "MP3",
|
|
|
|
|
.avcodec_id = AV_CODEC_ID_MP3,
|
|
|
|
|
.avcodec_name = NULL,
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -321,11 +257,14 @@ decoder_t *decoder_new_fmt(const codec_def_t *def, int clockrate, int channels,
|
|
|
|
|
ret->out_format = *resample_fmt;
|
|
|
|
|
// sample format to be determined later when decoded frames arrive
|
|
|
|
|
|
|
|
|
|
AVCodec *codec = NULL;
|
|
|
|
|
if (def->avcodec_name)
|
|
|
|
|
codec = avcodec_find_decoder_by_name(def->avcodec_name);
|
|
|
|
|
if (!codec)
|
|
|
|
|
codec = avcodec_find_decoder(def->avcodec_id);
|
|
|
|
|
AVCodec *codec = def->decoder;
|
|
|
|
|
// AVCodec *codec = NULL;
|
|
|
|
|
// if (def->decoder)
|
|
|
|
|
// codec = def->decoder;
|
|
|
|
|
// if (!codec && def->avcodec_name)
|
|
|
|
|
// codec = avcodec_find_decoder_by_name(def->avcodec_name);
|
|
|
|
|
// if (!codec && def->avcodec_id >= 0)
|
|
|
|
|
// codec = avcodec_find_decoder(def->avcodec_id);
|
|
|
|
|
if (!codec) {
|
|
|
|
|
ilog(LOG_WARN, "Codec '%s' not supported", def->rtpname);
|
|
|
|
|
goto err;
|
|
|
|
|
@ -553,16 +492,53 @@ void codeclib_init() {
|
|
|
|
|
codecs_ht = g_hash_table_new(str_hash, str_equal);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < G_N_ELEMENTS(__codec_defs); i++) {
|
|
|
|
|
// add to hash table
|
|
|
|
|
codec_def_t *def = &__codec_defs[i];
|
|
|
|
|
str_init(&def->rtpname_str, (char *) def->rtpname);
|
|
|
|
|
assert(g_hash_table_lookup(codecs_ht, &def->rtpname_str) == NULL);
|
|
|
|
|
g_hash_table_insert(codecs_ht, &def->rtpname_str, def);
|
|
|
|
|
|
|
|
|
|
// init undefined member vars
|
|
|
|
|
if (!def->clockrate_mult)
|
|
|
|
|
def->clockrate_mult = 1;
|
|
|
|
|
if (!def->default_ptime)
|
|
|
|
|
def->default_ptime = -1;
|
|
|
|
|
if (!def->default_clockrate)
|
|
|
|
|
def->default_clockrate = -1;
|
|
|
|
|
if (!def->default_channels)
|
|
|
|
|
def->default_channels = -1;
|
|
|
|
|
|
|
|
|
|
// init RFC-related info
|
|
|
|
|
const struct rtp_payload_type *pt = rtp_get_rfc_codec(&def->rtpname_str);
|
|
|
|
|
if (pt)
|
|
|
|
|
def->rfc_payload_type = pt->payload_type;
|
|
|
|
|
else
|
|
|
|
|
def->rfc_payload_type = -1;
|
|
|
|
|
|
|
|
|
|
// look up AVCodec structs
|
|
|
|
|
if (def->avcodec_name) {
|
|
|
|
|
def->encoder = avcodec_find_encoder_by_name(def->avcodec_name);
|
|
|
|
|
def->decoder = avcodec_find_decoder_by_name(def->avcodec_name);
|
|
|
|
|
}
|
|
|
|
|
if (def->avcodec_id >= 0) {
|
|
|
|
|
if (!def->encoder)
|
|
|
|
|
def->encoder = avcodec_find_encoder(def->avcodec_id);
|
|
|
|
|
if (!def->decoder)
|
|
|
|
|
def->decoder = avcodec_find_decoder(def->avcodec_id);
|
|
|
|
|
}
|
|
|
|
|
// 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",
|
|
|
|
|
def->rtpname);
|
|
|
|
|
}
|
|
|
|
|
else if (!def->decoder)
|
|
|
|
|
ilog(LOG_INFO, "Codec %s is only supported for encoding by codec library",
|
|
|
|
|
def->rtpname);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -707,7 +683,7 @@ encoder_t *encoder_new() {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int encoder_config(encoder_t *enc, int codec_id, int bitrate, int ptime,
|
|
|
|
|
int encoder_config(encoder_t *enc, const codec_def_t *def, int bitrate, int ptime,
|
|
|
|
|
const format_t *requested_format, format_t *actual_format)
|
|
|
|
|
{
|
|
|
|
|
const char *err;
|
|
|
|
|
@ -721,10 +697,16 @@ int encoder_config(encoder_t *enc, int codec_id, int bitrate, int ptime,
|
|
|
|
|
enc->requested_format = *requested_format;
|
|
|
|
|
|
|
|
|
|
err = "output codec not found";
|
|
|
|
|
enc->codec = avcodec_find_encoder(codec_id);
|
|
|
|
|
enc->codec = def->encoder;
|
|
|
|
|
// if (codec_name)
|
|
|
|
|
// enc->codec = avcodec_find_encoder_by_name(codec_name);
|
|
|
|
|
// if (!enc->codec)
|
|
|
|
|
// enc->codec = avcodec_find_encoder(codec_id);
|
|
|
|
|
if (!enc->codec)
|
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
|
|
ptime /= def->clockrate_mult;
|
|
|
|
|
|
|
|
|
|
err = "failed to alloc codec context";
|
|
|
|
|
enc->avcctx = avcodec_alloc_context3(enc->codec);
|
|
|
|
|
if (!enc->avcctx)
|
|
|
|
|
@ -793,6 +775,7 @@ void encoder_close(encoder_t *enc) {
|
|
|
|
|
avcodec_free_context(&enc->avcctx);
|
|
|
|
|
}
|
|
|
|
|
enc->avcctx = NULL;
|
|
|
|
|
enc->codec = NULL;
|
|
|
|
|
format_init(&enc->requested_format);
|
|
|
|
|
format_init(&enc->actual_format);
|
|
|
|
|
av_audio_fifo_free(enc->fifo);
|
|
|
|
|
|