|
|
|
|
@ -106,6 +106,13 @@ static const codec_type_t codec_type_cn = {
|
|
|
|
|
.decoder_close = avc_decoder_close,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const dtx_method_t dtx_method_silence = {
|
|
|
|
|
.do_dtx = generic_silence_dtx,
|
|
|
|
|
};
|
|
|
|
|
static const dtx_method_t dtx_method_amr = {
|
|
|
|
|
.do_dtx = amr_dtx,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_BCG729
|
|
|
|
|
static packetizer_f packetizer_g729; // aggregate some frames into packets
|
|
|
|
|
|
|
|
|
|
@ -142,7 +149,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.bits_per_sample = 8,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "PCMU",
|
|
|
|
|
@ -155,7 +164,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.bits_per_sample = 8,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "G723",
|
|
|
|
|
@ -168,7 +179,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "G722",
|
|
|
|
|
@ -181,7 +194,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.bits_per_sample = 8,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "QCELP",
|
|
|
|
|
@ -191,7 +206,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
#ifndef HAVE_BCG729
|
|
|
|
|
{
|
|
|
|
|
@ -204,7 +221,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "G729a",
|
|
|
|
|
@ -216,7 +235,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
#else
|
|
|
|
|
{
|
|
|
|
|
@ -231,7 +252,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.bits_per_sample = 1, // 10 ms frame has 80 samples and encodes as (max) 10 bytes = 80 bits
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_bcg729,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "G729a",
|
|
|
|
|
@ -244,7 +267,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.bits_per_sample = 1, // 10 ms frame has 80 samples and encodes as (max) 10 bytes = 80 bits
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_bcg729,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
@ -257,7 +282,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "GSM",
|
|
|
|
|
@ -269,7 +296,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "iLBC",
|
|
|
|
|
@ -299,7 +328,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.init = opus_init,
|
|
|
|
|
.set_enc_options = opus_set_enc_options,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "vorbis",
|
|
|
|
|
@ -310,7 +341,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "ac3",
|
|
|
|
|
@ -319,7 +352,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "eac3",
|
|
|
|
|
@ -328,7 +363,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "ATRAC3",
|
|
|
|
|
@ -337,7 +374,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "ATRAC-X",
|
|
|
|
|
@ -346,7 +385,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 0, 0)
|
|
|
|
|
{
|
|
|
|
|
@ -356,7 +397,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "EVRC0",
|
|
|
|
|
@ -366,7 +409,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "EVRC1",
|
|
|
|
|
@ -376,7 +421,9 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.packetizer = packetizer_passthrough,
|
|
|
|
|
.media_type = MT_AUDIO,
|
|
|
|
|
.codec_type = &codec_type_avcodec,
|
|
|
|
|
.dtx = generic_silence_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
@ -395,7 +442,10 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.codec_type = &codec_type_amr,
|
|
|
|
|
.set_enc_options = amr_set_enc_options,
|
|
|
|
|
.set_dec_options = amr_set_dec_options,
|
|
|
|
|
.dtx = amr_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_NATIVE] = &dtx_method_amr,
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "AMR-WB",
|
|
|
|
|
@ -413,7 +463,10 @@ static codec_def_t __codec_defs[] = {
|
|
|
|
|
.codec_type = &codec_type_amr,
|
|
|
|
|
.set_enc_options = amr_set_enc_options,
|
|
|
|
|
.set_dec_options = amr_set_dec_options,
|
|
|
|
|
.dtx = amr_dtx,
|
|
|
|
|
.dtx_methods = {
|
|
|
|
|
[DTX_NATIVE] = &dtx_method_amr,
|
|
|
|
|
[DTX_SILENCE] = &dtx_method_silence,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.rtpname = "telephone-event",
|
|
|
|
|
@ -559,6 +612,15 @@ decoder_t *decoder_new_fmtp(const codec_def_t *def, int clockrate, int channels,
|
|
|
|
|
else
|
|
|
|
|
ret->ptime = def->default_ptime;
|
|
|
|
|
|
|
|
|
|
// init with first supported DTX method
|
|
|
|
|
enum dtx_method dm = -1;
|
|
|
|
|
for (int i = 0; i < NUM_DTX_METHODS; i++) {
|
|
|
|
|
if (def->dtx_methods[i]) {
|
|
|
|
|
dm = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = def->codec_type->decoder_init(ret, fmtp, extra_opts);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err;
|
|
|
|
|
@ -568,6 +630,8 @@ decoder_t *decoder_new_fmtp(const codec_def_t *def, int clockrate, int channels,
|
|
|
|
|
ret->pts = (uint64_t) -1LL;
|
|
|
|
|
ret->rtp_ts = (unsigned long) -1L;
|
|
|
|
|
|
|
|
|
|
decoder_switch_dtx(ret, dm);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
@ -579,6 +643,33 @@ err:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int decoder_switch_dtx(decoder_t *dec, enum dtx_method dm) {
|
|
|
|
|
if (dec->dtx.cleanup)
|
|
|
|
|
dec->dtx.cleanup(dec);
|
|
|
|
|
ZERO(dec->dtx);
|
|
|
|
|
unsigned int i = dm;
|
|
|
|
|
if (i >= NUM_DTX_METHODS)
|
|
|
|
|
return -1;
|
|
|
|
|
const dtx_method_t *dmp = dec->def->dtx_methods[i];
|
|
|
|
|
if (!dmp)
|
|
|
|
|
return -1;
|
|
|
|
|
dec->dtx = *dmp;
|
|
|
|
|
if (dmp->init) {
|
|
|
|
|
if (dmp->init(dec)) {
|
|
|
|
|
ilog(LOG_ERR, "Failed to initialise DTX (%u)", i);
|
|
|
|
|
decoder_switch_dtx(dec, -1);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gboolean decoder_has_dtx(decoder_t *dec) {
|
|
|
|
|
return dec->dtx.do_dtx == NULL ? FALSE : TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void avc_decoder_close(decoder_t *dec) {
|
|
|
|
|
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 1, 0)
|
|
|
|
|
avcodec_free_context(&dec->u.avc.avcctx);
|
|
|
|
|
@ -597,6 +688,8 @@ void decoder_close(decoder_t *dec) {
|
|
|
|
|
if (dec->def && dec->def->codec_type && dec->def->codec_type->decoder_close)
|
|
|
|
|
dec->def->codec_type->decoder_close(dec);
|
|
|
|
|
|
|
|
|
|
decoder_switch_dtx(dec, -1);
|
|
|
|
|
|
|
|
|
|
resample_shutdown(&dec->resampler);
|
|
|
|
|
g_slice_free1(sizeof(*dec), dec);
|
|
|
|
|
}
|
|
|
|
|
@ -712,7 +805,7 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t
|
|
|
|
|
if (G_UNLIKELY(!dec))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
if (!data && !dec->def->dtx)
|
|
|
|
|
if (!data && !dec->dtx.do_dtx)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ts *= dec->def->clockrate_mult;
|
|
|
|
|
@ -741,7 +834,7 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t
|
|
|
|
|
if (data)
|
|
|
|
|
dec->def->codec_type->decoder_input(dec, data, &frames);
|
|
|
|
|
else
|
|
|
|
|
dec->def->dtx(dec, &frames, ptime);
|
|
|
|
|
dec->dtx.do_dtx(dec, &frames, ptime);
|
|
|
|
|
|
|
|
|
|
AVFrame *frame;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|