diff --git a/apps/sbc/SBCCallProfile.cpp b/apps/sbc/SBCCallProfile.cpp index 2654fd8d..5733feed 100644 --- a/apps/sbc/SBCCallProfile.cpp +++ b/apps/sbc/SBCCallProfile.cpp @@ -1391,8 +1391,9 @@ static bool read(const std::string &src, vector &codecs) if(!payload) { ERROR("Ignoring unknown payload found in call profile: '%s/%i'\n", p.encoding_name.c_str(), p.clock_rate); - } - else { + } else { + p.sdp_format_parameters = plugin->getSdpFormatParameters(payload->codec_id, true, ""); + if(payload_id < DYNAMIC_PAYLOAD_TYPE_START) p.payload_type = payload->payload_id; else diff --git a/core/AmAudio.cpp b/core/AmAudio.cpp index 43c80435..bb9f2132 100644 --- a/core/AmAudio.cpp +++ b/core/AmAudio.cpp @@ -55,7 +55,8 @@ AmAudioFormat::AmAudioFormat(int codec_id, unsigned int rate) : channels(1), codec_id(codec_id), rate(rate), - codec(NULL) + codec(NULL), + sdp_format_parameters_out(NULL) { codec = getCodec(); } @@ -103,13 +104,18 @@ bool AmAudioFormat::operator != (const AmAudioFormat& r) const void AmAudioFormat::initCodec() { - amci_codec_fmt_info_t fmt_i[4]; - fmt_i[0].id=0; + amci_codec_fmt_info_t* fmt_i = NULL; + sdp_format_parameters_out = NULL; // reset if( codec && codec->init ) { - if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(), fmt_i)) == -1) { + if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(), + &sdp_format_parameters_out, &fmt_i)) == -1) { ERROR("could not initialize codec %i\n",codec->id); - } + } else { + if (NULL != sdp_format_parameters_out) { + DBG("negotiated fmt parameters '%s'\n", sdp_format_parameters_out); + } + } } } diff --git a/core/AmAudio.h b/core/AmAudio.h index 3fa847dd..e87fe235 100644 --- a/core/AmAudio.h +++ b/core/AmAudio.h @@ -139,6 +139,7 @@ public: int channels; string sdp_format_parameters; + const char* sdp_format_parameters_out; AmAudioFormat(int codec_id = CODEC_PCM16, unsigned int rate = SYSTEM_SAMPLECLOCK_RATE); diff --git a/core/AmPlugIn.cpp b/core/AmPlugIn.cpp index 7664e916..a677c17a 100644 --- a/core/AmPlugIn.cpp +++ b/core/AmPlugIn.cpp @@ -400,6 +400,21 @@ amci_payload_t* AmPlugIn::payload(int payload_id) const return 0; } +string AmPlugIn::getSdpFormatParameters(int codec_id, bool is_offer, const string& fmt_params_in) { + amci_codec_t* c = codec(codec_id); + if (NULL == c) + return ""; // empty for unsupported codec + + if (NULL == c->negotiate_fmt) + return ""; // empty if codec doesn't know either + + char out_fmt[256] = { '\0' }; + if ((c->negotiate_fmt)(is_offer ? 1:0, fmt_params_in.c_str(), out_fmt, 256) >=0 ) + return string(out_fmt); + + return ""; +} + int AmPlugIn::getDynPayload(const string& name, int rate, int encoding_param) const { // find a dynamic payload by name/rate and encoding_param (channels, if > 0) for(std::map::const_iterator pl_it = payloads.begin(); diff --git a/core/AmPlugIn.h b/core/AmPlugIn.h index b8e64852..95d31522 100644 --- a/core/AmPlugIn.h +++ b/core/AmPlugIn.h @@ -199,6 +199,17 @@ class AmPlugIn : public AmPayloadProvider */ amci_codec_t* codec(int id); + /** + * get codec format parameters + * @param id Codec ID (see amci/codecs.h). + * @param is_offer for an offer? + * @param fmt_params_in input parameters for an answer + * @return fmt parameters for SDP (offer or answer) + */ + string getSdpFormatParameters(int codec_id, bool is_offer, const string& fmt_params_in); + + + /** * Application lookup function * @param app_name application name diff --git a/core/AmRtpAudio.cpp b/core/AmRtpAudio.cpp index a8cacde3..a6bd259c 100644 --- a/core/AmRtpAudio.cpp +++ b/core/AmRtpAudio.cpp @@ -62,34 +62,41 @@ int AmAudioRtpFormat::setCurrentPayload(Payload pl) void AmAudioRtpFormat::initCodec() { - amci_codec_fmt_info_t fmt_i[4]; - - fmt_i[0].id=0; + amci_codec_fmt_info_t* fmt_i = NULL; + sdp_format_parameters_out = NULL; // reset if( codec && codec->init ) { - if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(), fmt_i)) == -1) { + if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(), + &sdp_format_parameters_out, &fmt_i)) == -1) { ERROR("could not initialize codec %i\n",codec->id); } else { - string s; - int i=0; - while (fmt_i[i].id) { - switch (fmt_i[i].id) { - case AMCI_FMT_FRAME_LENGTH : { - //frame_length=fmt_i[i].value; - } break; - case AMCI_FMT_FRAME_SIZE: { - frame_size=fmt_i[i].value; - } break; - case AMCI_FMT_ENCODED_FRAME_SIZE: { - // frame_encoded_size=fmt_i[i].value; - } break; - default: { - DBG("Unknown codec format descriptor: %d\n", fmt_i[i].id); - } break; + if (NULL != sdp_format_parameters_out) { + DBG("negotiated fmt parameters '%s'\n", sdp_format_parameters_out); + log_demangled_stacktrace(L_DBG, 30); + } + + if (NULL != fmt_i) { + unsigned int i=0; + while (i<4 && fmt_i[i].id) { + switch (fmt_i[i].id) { + case AMCI_FMT_FRAME_LENGTH : { + //frame_length=fmt_i[i].value; // ignored + } break; + case AMCI_FMT_FRAME_SIZE: { + frame_size=fmt_i[i].value; + } break; + case AMCI_FMT_ENCODED_FRAME_SIZE: { + // frame_encoded_size=fmt_i[i].value; // ignored + } break; + default: { + DBG("Unknown codec format descriptor: %d\n", fmt_i[i].id); + } break; + } + + i++; } - i++; } - } + } } } diff --git a/core/amci/amci.h b/core/amci/amci.h index 39b15cb9..de6dbdbd 100644 --- a/core/amci/amci.h +++ b/core/amci/amci.h @@ -238,8 +238,10 @@ typedef void (*amci_codec_module_destroy_t)(void); /** * \brief Codec's init function pointer. * - * @param format_parameters [in] parameters as passed by fmtp tag, 0 if none - * @param format_description [out] pointer to describing block, with amci_codec_fmt_info_t array; zero-terminated. 0 if none + * @param format_parameters [in] parameters as passed by fmtp tag, NULL if none + * @param format_parameters_out [out] parameters passed back to fmtp, NULL if none + * @param format_description [out] pointer to describing block, with amci_codec_fmt_info_t array; zero-terminated. + NULL if none * * * @@ -254,7 +256,8 @@ typedef void (*amci_codec_module_destroy_t)(void); int value; } amci_codec_fmt_info_t; -typedef long (*amci_codec_init_t)(const char* format_parameters, amci_codec_fmt_info_t* format_description); + typedef long (*amci_codec_init_t)(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** fmt_info); /** * \brief Codec's destroy function pointer. @@ -272,6 +275,11 @@ typedef unsigned int (*amci_codec_bytes2samples_t)(long h_codec, unsigned int nu */ typedef unsigned int (*amci_codec_samples2bytes_t)(long h_codec, unsigned int num_samples); +/** + * \brief Codec's function for negotiating codec format; this needs to be dry-run, i.e. no codec instantiated + */ +typedef int (*amci_codec_negotiate_fmt_t)(int is_offer, const char* params_in, char* params_out, unsigned int params_out_len); + /** * \brief Codec description */ @@ -302,6 +310,9 @@ struct amci_codec_t { /** Function for calculating the number of samples from bytes. */ amci_codec_samples2bytes_t samples2bytes; + + /** function for dry-negotiating codec format - no codec instance is created */ + amci_codec_negotiate_fmt_t negotiate_fmt; }; /** \brief supported subtypes for a file */ @@ -464,7 +475,7 @@ struct amci_exports_t { * @hideinitializer */ #define END_CODECS \ - { -1, 0, 0, 0, 0, 0, 0, 0 } \ + { -1, 0, 0, 0, 0, 0, 0, 0, 0 } \ }, /** @@ -473,7 +484,14 @@ struct amci_exports_t { * @hideinitializer */ #define CODEC(id, intern2type,type2intern,plc,init,destroy,bytes2samples,samples2bytes) \ - { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes }, + { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes, 0 }, + + /** + A codec with negotiate_fmt function + @hideinitializer + */ +#define CODEC_WITH_FMT(id, intern2type,type2intern,plc,init,destroy,bytes2samples,samples2bytes,negotiate_fmt) \ + { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes, negotiate_fmt}, /** * Portable export definition macro diff --git a/core/plug-in/adpcm/adpcm.c b/core/plug-in/adpcm/adpcm.c index ae2db284..4c6fc371 100644 --- a/core/plug-in/adpcm/adpcm.c +++ b/core/plug-in/adpcm/adpcm.c @@ -40,7 +40,8 @@ /* or ATM-AAL packing -> RFC3551 has the names AAL2-G726-xy for the big-endian packing */ #define G726_PACK_RFC3551 1 -static long G726_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); +static long G726_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); static void G726_destroy(long h_inst); static int Pcm16_2_G726_16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, @@ -108,7 +109,8 @@ struct G726_twoway { struct g72x_state from_g726; }; -static long G726_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) { +static long G726_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { struct G726_twoway* cinst = calloc(1, sizeof(struct G726_twoway)); if (!cinst) return -1; @@ -116,7 +118,6 @@ static long G726_create(const char* format_parameters, amci_codec_fmt_info_t* fo g72x_init_state(&cinst->to_g726); g72x_init_state(&cinst->from_g726); - format_description[0].id = 0; return (long) cinst; } diff --git a/core/plug-in/g722/g722.c b/core/plug-in/g722/g722.c index de08f870..9ee9b63e 100644 --- a/core/plug-in/g722/g722.c +++ b/core/plug-in/g722/g722.c @@ -36,7 +36,8 @@ int Pcm16_2_G722NB( unsigned char* out_buf, unsigned char* in_buf, unsigned int int G722NB_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -long G722NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); +long G722NB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); void G722NB_destroy(long handle); static unsigned int G722NB_bytes2samples(long, unsigned int); @@ -67,7 +68,8 @@ typedef struct { } G722State; -long G722NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) +long G722NB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { G722State* gs; diff --git a/core/plug-in/g729/g729.c b/core/plug-in/g729/g729.c index 4e0131ec..d83f2709 100644 --- a/core/plug-in/g729/g729.c +++ b/core/plug-in/g729/g729.c @@ -56,12 +56,19 @@ static int pcm16_2_g729(unsigned char* out_buf, unsigned char* in_buf, unsigned static int g729_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -static long g729_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); +static long g729_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); static void g729_destroy(long h_codec); static unsigned int g729_bytes2samples(long, unsigned int); static unsigned int g729_samples2bytes(long, unsigned int); +static amci_codec_fmt_info_t[] gsm_fmt_description = { { AMCI_FMT_FRAME_LENGTH, 20 }, + { AMCI_FMT_FRAME_SIZE, 160 }, + { AMCI_FMT_ENCODED_FRAME_SIZE, 33 }, + { 0, 0 } +}; + #define G729_PAYLOAD_ID 18 #define G729_BYTES_PER_FRAME 10 #define G729_SAMPLES_PER_FRAME 10 @@ -176,7 +183,8 @@ stream_destroy(struct stream *st) } -long g729_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) +long g729_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { USC_CodecInfo pInfo; struct G729_codec *codec; diff --git a/core/plug-in/gsm/gsm.c b/core/plug-in/gsm/gsm.c index cf779c1b..b8a5f677 100644 --- a/core/plug-in/gsm/gsm.c +++ b/core/plug-in/gsm/gsm.c @@ -39,13 +39,18 @@ static int pcm16_2_gsm(unsigned char* out_buf, unsigned char* in_buf, unsigned i static int gsm_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -static long gsm_create_if(const char* format_parameters, amci_codec_fmt_info_t* format_description); +static long gsm_create_if(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); static void gsm_destroy_if(long h_codec); static unsigned int gsm_bytes2samples(long, unsigned int); static unsigned int gsm_samples2bytes(long, unsigned int); +static amci_codec_fmt_info_t gsm_fmt_description[] = { {AMCI_FMT_FRAME_LENGTH, 20}, + {AMCI_FMT_FRAME_SIZE, 160}, + {AMCI_FMT_ENCODED_FRAME_SIZE, 33}, {0,0}}; + BEGIN_EXPORTS( "gsm", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY ) BEGIN_CODECS @@ -126,7 +131,8 @@ static int gsm_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned i } -static long gsm_create_if(const char* format_parameters, amci_codec_fmt_info_t* format_description) +static long gsm_create_if(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { gsm* h_codec=0; @@ -139,15 +145,8 @@ static long gsm_create_if(const char* format_parameters, amci_codec_fmt_info_t* h_codec[0] = gsm_create(); h_codec[1] = gsm_create(); - format_description[0].id = AMCI_FMT_FRAME_LENGTH ; - format_description[0].value = 20; - format_description[1].id = AMCI_FMT_FRAME_SIZE; - format_description[1].value = 160; - format_description[2].id = AMCI_FMT_ENCODED_FRAME_SIZE; - format_description[2].value = 33; - format_description[3].id = 0; + *format_description = gsm_fmt_description; - return (long)h_codec; } diff --git a/core/plug-in/ilbc/ilbc.c b/core/plug-in/ilbc/ilbc.c index bc60978d..7f5eca95 100644 --- a/core/plug-in/ilbc/ilbc.c +++ b/core/plug-in/ilbc/ilbc.c @@ -73,7 +73,8 @@ static int iLBC_PLC( unsigned char* out_buf, unsigned int size, static int Pcm16_2_iLBC( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -static long iLBC_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); +static long iLBC_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); static void iLBC_destroy(long h_inst); static int iLBC_open(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec); static int iLBC_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec, struct amci_codec_t *codec); @@ -81,6 +82,14 @@ static int iLBC_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, static unsigned int ilbc_bytes2samples(long, unsigned int); static unsigned int ilbc_samples2bytes(long, unsigned int); +static amci_codec_fmt_info_t ilbc_fmt_description_30[] = { {AMCI_FMT_FRAME_LENGTH, 30}, + {AMCI_FMT_FRAME_SIZE, 240}, + {AMCI_FMT_ENCODED_FRAME_SIZE, 50}, {0,0}}; + +static amci_codec_fmt_info_t ilbc_fmt_description_20[] = { {AMCI_FMT_FRAME_LENGTH, 20}, + {AMCI_FMT_FRAME_SIZE, 160}, + {AMCI_FMT_ENCODED_FRAME_SIZE, 38}, {0,0}}; + BEGIN_EXPORTS( "ilbc" , AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY ) BEGIN_CODECS @@ -129,7 +138,8 @@ static unsigned int ilbc_samples2bytes(long h_codec, unsigned int num_samples) return (num_samples / 160) * 38; } -long iLBC_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) { +long iLBC_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { iLBC_Codec_Inst_t* codec_inst; int mode; @@ -156,14 +166,9 @@ long iLBC_create(const char* format_parameters, amci_codec_fmt_info_t* format_de } } } - format_description[0].id = AMCI_FMT_FRAME_LENGTH ; - format_description[0].value = mode; - format_description[1].id = AMCI_FMT_FRAME_SIZE; - format_description[1].value = mode==30 ? 240 : 160; - format_description[2].id = AMCI_FMT_ENCODED_FRAME_SIZE; - format_description[2].value = mode==30 ? 50 : 38; - format_description[3].id = 0; - + + *format_description = (mode == 30) ? ilbc_fmt_description_30 : ilbc_fmt_description_20; + if (format_parameters) { DBG("ilbc with format parameters : '%s', mode=%d.\n", format_parameters, mode); } diff --git a/core/plug-in/isac/isac.c b/core/plug-in/isac/isac.c index 36c110f0..9c771aef 100644 --- a/core/plug-in/isac/isac.c +++ b/core/plug-in/isac/isac.c @@ -33,13 +33,15 @@ int Pcm16_2_iSAC( unsigned char* out_buf, unsigned char* in_buf, unsigned int si int iSAC_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -static long iSAC_create(const char* format_parameters, - amci_codec_fmt_info_t* format_description); +static long iSAC_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); static void iSAC_destroy(long handle); static unsigned int iSAC_bytes2samples(long, unsigned int); static unsigned int iSAC_samples2bytes(long, unsigned int); +static amci_codec_fmt_info_t isac_fmt_description[] = {{AMCI_FMT_FRAME_SIZE, iSAC_FRAME_MS * iSAC_SAMPLE_RATE / 1000}, {0,0}}; + BEGIN_EXPORTS("isac", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY) BEGIN_CODECS @@ -62,8 +64,8 @@ END_FILE_FORMATS END_EXPORTS -static long iSAC_create(const char* format_parameters, - amci_codec_fmt_info_t* format_description) +static long iSAC_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { ISACStruct *iSAC_st=NULL; int err = WebRtcIsac_Create(&iSAC_st); @@ -85,11 +87,7 @@ static long iSAC_create(const char* format_parameters, return 0; } - format_description[0].id = AMCI_FMT_FRAME_SIZE; - format_description[0].value = iSAC_FRAME_MS * iSAC_SAMPLE_RATE / 1000; - DBG("set AMCI_FMT_FRAME_SIZE to %d\n", format_description[0].value); - - format_description[1].id = 0; + *format_description = isac_fmt_description; return (long)iSAC_st; } diff --git a/core/plug-in/opus/opus.c b/core/plug-in/opus/opus.c index 8cb6f391..57a92bc4 100644 --- a/core/plug-in/opus/opus.c +++ b/core/plug-in/opus/opus.c @@ -84,7 +84,8 @@ static int opus_plc( unsigned char* out_buf, unsigned int size, static int pcm16_2_opus( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -static long opus_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); +static long opus_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); static void opus_destroy(long h_inst); #if SYSTEM_SAMPLECLOCK_RATE >= 48000 @@ -99,6 +100,9 @@ static void opus_destroy(long h_inst); #error Minimal sample rate for OPUS codec is 8000. #endif +static amci_codec_fmt_info_t opus_fmt_description[] = { {AMCI_FMT_FRAME_LENGTH, 20}, + {AMCI_FMT_FRAME_SIZE, 20 * _OPUS_RATE / 1000}, {0,0}}; + BEGIN_EXPORTS( "opus" , AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY ) BEGIN_CODECS @@ -122,19 +126,14 @@ typedef struct { OpusDecoder* opus_dec; } opus_state_t; -long opus_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) { +long opus_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { opus_state_t* codec_inst; int error; if (format_parameters) { DBG("OPUS params: >>%s<<.\n", format_parameters); } - - format_description[0].id = AMCI_FMT_FRAME_LENGTH ; - format_description[0].value = 20; - format_description[1].id = AMCI_FMT_FRAME_SIZE; - format_description[1].value = 20 * _OPUS_RATE / 1000; - format_description[2].id = 0; codec_inst = (opus_state_t*)malloc(sizeof(opus_state_t)); @@ -161,6 +160,8 @@ long opus_create(const char* format_parameters, amci_codec_fmt_info_t* format_de return -1; } + *format_description = opus_fmt_description; + return (long)codec_inst; } diff --git a/core/plug-in/silk/silk.c b/core/plug-in/silk/silk.c index 7bfd3ce0..30326f88 100644 --- a/core/plug-in/silk/silk.c +++ b/core/plug-in/silk/silk.c @@ -35,10 +35,14 @@ int Pcm16_2_SILK( unsigned char* out_buf, unsigned char* in_buf, unsigned int si int SILK_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -long SILK_NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); -long SILK_MB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); -long SILK_WB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); -long SILK_UB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); +long SILK_NB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); +long SILK_MB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); +long SILK_WB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); +long SILK_UB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); void SILK_destroy(long handle); static unsigned int SILK_bytes2samples(long, unsigned int); @@ -169,9 +173,7 @@ static int create_SILK_decoder(SILK_state* st, } static long SILK_create(unsigned int rtp_Hz, - unsigned int avg_bit_rate, - const char* format_parameters, - amci_codec_fmt_info_t* format_description) + unsigned int avg_bit_rate) { SILK_state* st = malloc(sizeof(SILK_state)); if(st == NULL) { @@ -195,24 +197,28 @@ static long SILK_create(unsigned int rtp_Hz, return 0; } -long SILK_NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) +long SILK_NB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { - return SILK_create(8000,20000,format_parameters,format_description); + return SILK_create(8000,20000); } -long SILK_MB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) +long SILK_MB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { - return SILK_create(12000,25000,format_parameters,format_description); + return SILK_create(12000,25000); } -long SILK_WB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) +long SILK_WB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { - return SILK_create(16000,30000,format_parameters,format_description); + return SILK_create(16000,30000); } -long SILK_UB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) +long SILK_UB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { - return SILK_create(24000,40000,format_parameters,format_description); + return SILK_create(24000,40000); } void SILK_destroy(long handle) diff --git a/core/plug-in/speex/speex.c b/core/plug-in/speex/speex.c index 2917b175..992c841e 100644 --- a/core/plug-in/speex/speex.c +++ b/core/plug-in/speex/speex.c @@ -79,9 +79,12 @@ int Pcm16_2_Speex( unsigned char* out_buf, unsigned char* in_buf, unsigned int s int Speex_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ); -long speexNB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); -long speexWB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); -long speexUB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description); +long speexNB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); +long speexWB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); +long speexUB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description); void speex_destroy(long handle); /* static unsigned int speex_bytes2samples(long, unsigned int); */ @@ -130,9 +133,10 @@ typedef struct { unsigned int frames_per_packet; /* in samples */ unsigned int frame_size; + amci_codec_fmt_info_t fmt_info[3]; } SpeexState; -#if 0 +#if 0 /* SDP parameters ignored ? */ /* Search for a parameter assignement in input string. @@ -145,7 +149,7 @@ static char* read_param(char* input, const char *param, char** param_value) int param_size; /* Eat spaces and semi-colons */ - while (*input && *input==' ' && *input==';' && *input!='"') + while (*input && (*input==' ' || *input==';' || *input=='"')) input++; *param_value = NULL; @@ -222,7 +226,7 @@ void decode_format_parameters(const char* format_parameters, SpeexState* ss) { long speex_create(unsigned int sample_rate, const char* format_parameters, - amci_codec_fmt_info_t* format_description) + amci_codec_fmt_info_t** format_description) { int speex_mode = 0, on=1, quality=0; SpeexState* ss=NULL; @@ -272,17 +276,19 @@ long speex_create(unsigned int sample_rate, ss->decoder.state = speex_decoder_init(speex_lib_get_mode(speex_mode)); speex_decoder_ctl(ss->decoder.state, SPEEX_SET_ENH, &on); - format_description[0].id = AMCI_FMT_FRAME_LENGTH; - format_description[0].value = SPEEX_FRAME_MS * ss->frames_per_packet; + ss->fmt_info[0].id = AMCI_FMT_FRAME_LENGTH; + ss->fmt_info[0].value = SPEEX_FRAME_MS * ss->frames_per_packet; ss->frame_size = SPEEX_FRAME_MS * (sample_rate / 1000); - format_description[1].id = AMCI_FMT_FRAME_SIZE; - format_description[1].value = ss->frame_size * ss->frames_per_packet; + ss->fmt_info[1].id = AMCI_FMT_FRAME_SIZE; + ss->fmt_info[1].value = ss->frame_size * ss->frames_per_packet; - format_description[2].id = 0; + ss->fmt_info[2].id = 0; - DBG("set AMCI_FMT_FRAME_LENGTH to %d\n", format_description[0].value); - DBG("set AMCI_FMT_FRAME_SIZE to %d\n", format_description[1].value); + *format_description = ss->fmt_info; + + DBG("set AMCI_FMT_FRAME_LENGTH to %d\n", ss->fmt_info[0].value); + DBG("set AMCI_FMT_FRAME_SIZE to %d\n", ss->fmt_info[1].value); DBG("SpeexState %p inserted with %d frames per packet,\n", ss, ss->frames_per_packet); @@ -290,20 +296,20 @@ long speex_create(unsigned int sample_rate, return (long)ss; } -long speexNB_create(const char* format_parameters, - amci_codec_fmt_info_t* format_description) +long speexNB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { return speex_create(8000,format_parameters,format_description); } -long speexWB_create(const char* format_parameters, - amci_codec_fmt_info_t* format_description) +long speexWB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { return speex_create(16000,format_parameters,format_description); } -long speexUB_create(const char* format_parameters, - amci_codec_fmt_info_t* format_description) +long speexUB_create(const char* format_parameters, const char** format_parameters_out, + amci_codec_fmt_info_t** format_description) { return speex_create(32000,format_parameters,format_description); }
keyvalue
AMCI_FMT_FRAME_LENGTH (1) frame length in ms (for framed codecs; must be multiple of 10)
AMCI_FMT_FRAME_SIZE (2) frame size in samples