From 0587ac61e8c2fa56f854d6898a1576ba7c583893 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Tue, 21 May 2024 13:22:23 +0700 Subject: [PATCH] Modification based on comments - Add comments - Add compile time setting to enable certain samplerate - Get decoder bitrate from SDP - More lenient on codec parse --- pjmedia/include/pjmedia-codec/config.h | 40 ++++++++++++++ pjmedia/include/pjmedia-codec/lyra.h | 6 ++- pjmedia/src/pjmedia-codec/lyra.cpp | 72 +++++++++++++++----------- pjsip/include/pjsua2/media.hpp | 3 +- 4 files changed, 88 insertions(+), 33 deletions(-) diff --git a/pjmedia/include/pjmedia-codec/config.h b/pjmedia/include/pjmedia-codec/config.h index 69b7311e6f..5d7a15b43f 100644 --- a/pjmedia/include/pjmedia-codec/config.h +++ b/pjmedia/include/pjmedia-codec/config.h @@ -569,6 +569,46 @@ # define PJMEDIA_CODEC_LYRA_DEFAULT_MODEL_PATH "model_coeffs" #endif +/** + * Settings to enable Lyra codec 8KHz. This option is only used + * when PJMEDIA_HAS_LYRA_CODEC is enabled. + * + * Default: 0 + */ +#ifndef PJMEDIA_CODEC_LYRA_HAS_8KHZ +# define PJMEDIA_CODEC_LYRA_HAS_8KHZ 0 +#endif + +/** + * Settings to enable Lyra codec 16KHz. This option is only used + * when PJMEDIA_HAS_LYRA_CODEC is enabled. + * + * Default: 1 + */ +#ifndef PJMEDIA_CODEC_LYRA_HAS_16KHZ +# define PJMEDIA_CODEC_LYRA_HAS_16KHZ 1 +#endif + +/** + * Settings to enable Lyra codec 32KHz. This option is only used + * when PJMEDIA_HAS_LYRA_CODEC is enabled. + * + * Default: 0 + */ +#ifndef PJMEDIA_CODEC_LYRA_HAS_32KHZ +# define PJMEDIA_CODEC_LYRA_HAS_32KHZ 0 +#endif + +/** + * Settings to enable Lyra codec 48KHz. This option is only used + * when PJMEDIA_HAS_LYRA_CODEC is enabled. + * + * Default: 0 + */ +#ifndef PJMEDIA_CODEC_LYRA_HAS_48KHZ +# define PJMEDIA_CODEC_LYRA_HAS_48KHZ 0 +#endif + /** * Specify if FFMPEG codecs are available. * diff --git a/pjmedia/include/pjmedia-codec/lyra.h b/pjmedia/include/pjmedia-codec/lyra.h index ca1acadfdd..70e6941215 100755 --- a/pjmedia/include/pjmedia-codec/lyra.h +++ b/pjmedia/include/pjmedia-codec/lyra.h @@ -35,6 +35,9 @@ * factory to the codec manager. After the codec factory has been registered, * application can use @ref PJMEDIA_CODEC API to manipulate the codec. * + * Lyra codec supports 16-bit PCM audio signal with sampling rate of (8000Hz, + * 16000Hz, 32000Hz and 48000Hz), frame length 20ms, and resulting in + * bitrate 3200bps, 6000bps and 9200bps. */ PJ_BEGIN_DECL @@ -50,7 +53,8 @@ typedef struct pjmedia_codec_lyra_config * the local endpoint might be set to a bitrate of 3200, while * the remote endpoint is set to 6000. In this scenario, the remote * endpoint will send data at 3200 bitrate, while the local endpoint - * will send data at 6000 bitrate. + * will send data at 6000 bitrate. Valid bitrate: 3200, 6000, 9200. + * By default it is set to PJMEDIA_CODEC_LYRA_DEFAULT_BIT_RATE. */ unsigned bit_rate; diff --git a/pjmedia/src/pjmedia-codec/lyra.cpp b/pjmedia/src/pjmedia-codec/lyra.cpp index e1de3411e3..6bcdb86d00 100755 --- a/pjmedia/src/pjmedia-codec/lyra.cpp +++ b/pjmedia/src/pjmedia-codec/lyra.cpp @@ -170,19 +170,19 @@ PJ_DEF(pj_status_t) pjmedia_codec_lyra_init(pjmedia_endpt *endpt) PJ_LOG(2, (THIS_FILE, "Unable to create memory pool for Lyra codec")); return PJ_ENOMEM; } - lyra_factory.param[0].enabled = 0; + lyra_factory.param[0].enabled = PJMEDIA_CODEC_LYRA_HAS_8KHZ; lyra_factory.param[0].pt = PJMEDIA_RTP_PT_LYRA_8; lyra_factory.param[0].clock_rate = 8000; - lyra_factory.param[1].enabled = 1; + lyra_factory.param[1].enabled = PJMEDIA_CODEC_LYRA_HAS_16KHZ; lyra_factory.param[1].pt = PJMEDIA_RTP_PT_LYRA_16; lyra_factory.param[1].clock_rate = 16000; - lyra_factory.param[2].enabled = 0; + lyra_factory.param[2].enabled = PJMEDIA_CODEC_LYRA_HAS_32KHZ; lyra_factory.param[2].pt = PJMEDIA_RTP_PT_LYRA_32; lyra_factory.param[2].clock_rate = 32000; - lyra_factory.param[3].enabled = 0; + lyra_factory.param[3].enabled = PJMEDIA_CODEC_LYRA_HAS_48KHZ; lyra_factory.param[3].pt = PJMEDIA_RTP_PT_LYRA_48; lyra_factory.param[3].clock_rate = 48000; @@ -433,37 +433,50 @@ static pj_status_t lyra_codec_init(pjmedia_codec *codec, return PJ_SUCCESS; } -static pj_status_t lyra_codec_open(pjmedia_codec *codec, - pjmedia_codec_param *attr) +static unsigned get_bit_rate_from_fmtp(pj_bool_t is_enc, + pjmedia_codec_param *attr) { - ghc::filesystem::path model_path = lyra_cfg.model_path.ptr; - struct lyra_data *lyra_data = (struct lyra_data*)codec->codec_data; - - pj_mutex_lock(lyra_data->mutex); - - PJ_LOG(4, (THIS_FILE, "Codec opening, model_path=%.*s", - (int)lyra_cfg.model_path.slen, lyra_cfg.model_path.ptr)); + unsigned bit_rate = 0; - /* Get encoder bit_rate */ - for (unsigned i = 0; i < attr->setting.enc_fmtp.cnt; ++i) { - if (pj_strcmp2(&attr->setting.enc_fmtp.param[i].name, - BIT_RATE_STR) == 0) + pjmedia_codec_fmtp *fmtp = (is_enc?&attr->setting.enc_fmtp: + &attr->setting.dec_fmtp); + /* Get bit_rate from fmpt */ + for (unsigned i = 0; i < fmtp->cnt; ++i) { + if (pj_strcmp2(&fmtp->param[i].name, BIT_RATE_STR) == 0) { - lyra_data->enc_bit_rate = (pj_uint16_t) - pj_strtoul(&attr->setting.enc_fmtp.param[i].val); + bit_rate = (pj_uint16_t) pj_strtoul(&fmtp->param[i].val); break; } } - if (lyra_data->enc_bit_rate == 0 || - (lyra_data->enc_bit_rate != 3200 && lyra_data->enc_bit_rate != 6000 && - lyra_data->enc_bit_rate != 9200)) + if (bit_rate == 0 || + (bit_rate != 3200 && bit_rate != 6000 && bit_rate != 9200)) { - lyra_data->enc_bit_rate = PJMEDIA_CODEC_LYRA_DEFAULT_BIT_RATE; + bit_rate = PJMEDIA_CODEC_LYRA_DEFAULT_BIT_RATE; } + return bit_rate; +} + +static pj_status_t lyra_codec_open(pjmedia_codec *codec, + pjmedia_codec_param *attr) +{ + ghc::filesystem::path model_path = lyra_cfg.model_path.ptr; + struct lyra_data *lyra_data = (struct lyra_data*)codec->codec_data; + + pj_mutex_lock(lyra_data->mutex); + + lyra_data->enc_bit_rate = get_bit_rate_from_fmtp(PJ_TRUE, attr); + lyra_data->dec_bit_rate = get_bit_rate_from_fmtp(PJ_FALSE, attr); lyra_data->vad_enabled = (attr->setting.vad != 0); lyra_data->plc_enabled = (attr->setting.plc != 0); + PJ_LOG(4, (THIS_FILE, "Opening codec, model_path=%.*s, chan_cnt=%d, " + "enc_bit_rate=%d, dec_bit_rate=%d, clockrate=%d, vad=%d", + (int)lyra_cfg.model_path.slen, lyra_cfg.model_path.ptr, + attr->info.channel_cnt, lyra_data->enc_bit_rate, + lyra_data->dec_bit_rate, attr->info.clock_rate, + lyra_data->vad_enabled)); + lyra_data->enc = LyraEncoder::Create(attr->info.clock_rate, attr->info.channel_cnt, lyra_data->enc_bit_rate, @@ -486,14 +499,7 @@ static pj_status_t lyra_codec_open(pjmedia_codec *codec, lyra_data->samples_per_frame = attr->info.clock_rate / lyra_data->enc->frame_rate(); - PJ_LOG(4, (THIS_FILE, "Codec opened, model_path=%.*s, chan_cnt=%d, " - "enc_bit_rate=%d, dec_bit_rate=%d, clockrate=%d, vad=%d, " - "frame_rate=%d, samples_per_frame=%d", - (int)lyra_cfg.model_path.slen, lyra_cfg.model_path.ptr, - attr->info.channel_cnt, lyra_data->enc_bit_rate, - lyra_data->dec_bit_rate, attr->info.clock_rate, - lyra_data->vad_enabled, lyra_data->enc->frame_rate(), - lyra_data->samples_per_frame)); + PJ_LOG(4, (THIS_FILE, "Done opening codec")); pj_mutex_unlock(lyra_data->mutex); return PJ_SUCCESS; @@ -537,6 +543,7 @@ static pj_status_t lyra_codec_parse(pjmedia_codec *codec, unsigned count = 0; struct lyra_data* lyra_data = (struct lyra_data*)codec->codec_data; unsigned frm_size = lyra_data->dec_bit_rate / (50 * 8); + pj_size_t orig_pkt_size = pkt_size; PJ_UNUSED_ARG(codec); @@ -554,6 +561,9 @@ static pj_status_t lyra_codec_parse(pjmedia_codec *codec, ++count; } + if (pkt_size != 0 && count == 1) { + frames[0].size = orig_pkt_size; + } *frame_cnt = count; pj_mutex_unlock(lyra_data->mutex); diff --git a/pjsip/include/pjsua2/media.hpp b/pjsip/include/pjsua2/media.hpp index 85075a031a..0d1631908f 100644 --- a/pjsip/include/pjsua2/media.hpp +++ b/pjsip/include/pjsua2/media.hpp @@ -2652,7 +2652,8 @@ struct CodecLyraConfig * the local endpoint might be set to a bitrate of 3200, while * the remote endpoint is set to 6000. In this scenario, the remote * endpoint will send data at 3200 bitrate, while the local endpoint - * will send data at 6000 bitrate. + * will send data at 6000 bitrate. Valid bitrate: 3200, 6000, 9200. + * By default it is set to PJMEDIA_CODEC_LYRA_DEFAULT_BIT_RATE. */ unsigned bitRate;