From 13ce01f16a2cac2fbb988c5115342eb30e323c0d Mon Sep 17 00:00:00 2001 From: paulc Date: Fri, 30 Sep 2005 22:46:16 +0000 Subject: [PATCH] Preparation for iLBC support. git-svn-id: http://yate.null.ro/svn/yate/trunk@532 acf43c95-373e-0410-b603-e72c3f656dc1 --- configure.in | 7 +++--- modules/iaxchan.cpp | 2 +- modules/wavefile.cpp | 60 ++++++++++++++++++++++++++++++++++++-------- modules/yrtpchan.cpp | 3 +++ modules/ysipchan.cpp | 21 ++++++++++++++++ 5 files changed, 78 insertions(+), 15 deletions(-) diff --git a/configure.in b/configure.in index 707763c1..814d0461 100644 --- a/configure.in +++ b/configure.in @@ -216,19 +216,20 @@ AC_SUBST(HAVE_GSM) AC_SUBST(GSM_INC) HAVE_ILBC=no +ILBC_INC="" AC_ARG_ENABLE(ilbc,AC_HELP_STRING([--enable-ilbc],[Enable iLBC codec]),want_ilbc=$enableval,want_ilbc=yes) if [[ "x$want_ilbc" = "xyes" ]]; then - HAVE_ILBC=yes -fi AC_MSG_CHECKING([for iLBC in contrib]) inci10="contrib/ilbc" if [[ -f "$basedir/$inci10/iLBC_encode.h" ]]; then HAVE_ILBC=yes ILBC_INC="-I$basedir/$inci2" - ILBC_DEP="../$inci2/libiax.a" + ILBC_DEP="../$inci2/libilbc.a" fi AC_MSG_RESULT([$HAVE_ILBC]) +fi AC_SUBST(HAVE_ILBC) +AC_SUBST(ILBC_INC) HAVE_PWLIB=no PWLIB_RTTI=none diff --git a/modules/iaxchan.cpp b/modules/iaxchan.cpp index 7d76edcf..aaa599da 100644 --- a/modules/iaxchan.cpp +++ b/modules/iaxchan.cpp @@ -44,7 +44,7 @@ using namespace TelEngine; static TokenDict dict_iaxformats[] = { // audio formats { "gsm", AST_FORMAT_GSM }, - { "ilbc", AST_FORMAT_ILBC }, + { "ilbc30", AST_FORMAT_ILBC }, { "speex", AST_FORMAT_SPEEX }, { "lpc10", AST_FORMAT_LPC10 }, { "mulaw", AST_FORMAT_ULAW }, diff --git a/modules/wavefile.cpp b/modules/wavefile.cpp index bb828c0d..d247658f 100644 --- a/modules/wavefile.cpp +++ b/modules/wavefile.cpp @@ -44,6 +44,8 @@ public: private: void detectAuFormat(); void detectWavFormat(); + void detectIlbcFormat(); + bool computeDataRate(); CallEndpoint* m_chan; DataBlock m_data; int m_fd; @@ -117,7 +119,7 @@ private: INIT_PLUGIN(WaveFileDriver); WaveSource::WaveSource(const String& file, CallEndpoint* chan, bool autoclose) - : m_chan(chan), m_fd(-1), m_swap(false), m_brate(16000), + : m_chan(chan), m_fd(-1), m_swap(false), m_brate(0), m_total(0), m_time(0), m_autoclose(autoclose) { Debug(&__plugin,DebugAll,"WaveSource::WaveSource(\"%s\",%p) [%p]",file.c_str(),chan,this); @@ -132,25 +134,28 @@ WaveSource::WaveSource(const String& file, CallEndpoint* chan, bool autoclose) m_format.clear(); return; } - if (file.endsWith(".gsm")) { + if (file.endsWith(".gsm")) m_format = "gsm"; - m_brate = 1650; - } - else if (file.endsWith(".alaw") || file.endsWith(".A")) { + else if (file.endsWith(".alaw") || file.endsWith(".A")) m_format = "alaw"; - m_brate = 8000; - } - else if (file.endsWith(".mulaw") || file.endsWith(".u")) { + else if (file.endsWith(".mulaw") || file.endsWith(".u")) m_format = "mulaw"; - m_brate = 8000; - } + else if (file.endsWith(".ilbc20")) + m_format = "ilbc20"; + else if (file.endsWith(".ilbc30")) + m_format = "ilbc30"; else if (file.endsWith(".au")) detectAuFormat(); else if (file.endsWith(".wav")) detectWavFormat(); + else if (file.endsWith(".lbc")) + detectIlbcFormat(); else if (!file.endsWith(".slin")) Debug(DebugMild,"Unknown format for file '%s', assuming signed linear",file.c_str()); - start("WaveSource"); + if (computeDataRate()) + start("WaveSource"); + else + Debug(DebugWarn,"Unable to compute data rate for file '%s'",file.c_str()); } WaveSource::~WaveSource() @@ -217,6 +222,35 @@ void WaveSource::detectWavFormat() Debug(DebugMild,".wav not supported yet, assuming raw signed linear"); } +#define ILBC_HEADER_LEN 9 +void WaveSource::detectIlbcFormat() +{ + char header[ILBC_HEADER_LEN+1]; + if (::read(m_fd,&header,ILBC_HEADER_LEN) == ILBC_HEADER_LEN) { + header[ILBC_HEADER_LEN] = '\0'; + if (::strcmp(header,"#!iLBC20\n") == 0) { + m_format = "ilbc20"; + return; + } + else if (::strcmp(header,"#!iLBC30\n") == 0) { + m_format = "ilbc30"; + return; + } + } + Debug(DebugMild,"Invalid iLBC file, assuming raw signed linear"); +} + +bool WaveSource::computeDataRate() +{ + if (m_brate) + return true; + const FormatInfo* info = m_format.getInfo(); + if (!info) + return false; + m_brate = info->dataRate(); + return (m_brate != 0); +} + void WaveSource::run() { unsigned long ts = 0; @@ -293,6 +327,10 @@ WaveConsumer::WaveConsumer(const String& file, CallEndpoint* chan, unsigned maxl m_format = "alaw"; else if (file.endsWith(".mulaw") || file.endsWith(".u")) m_format = "mulaw"; + else if (file.endsWith(".ilbc20")) + m_format = "ilbc20"; + else if (file.endsWith(".ilbc30")) + m_format = "ilbc30"; m_fd = ::creat(file.safe(),S_IRUSR|S_IWUSR); if (m_fd < 0) Debug(DebugGoOn,"Creating '%s': error %d: %s", diff --git a/modules/yrtpchan.cpp b/modules/yrtpchan.cpp index 4bc28257..aef227dc 100644 --- a/modules/yrtpchan.cpp +++ b/modules/yrtpchan.cpp @@ -44,6 +44,9 @@ static TokenDict dict_payloads[] = { { "g723", 4 }, { "g728", 15 }, { "g729", 18 }, + { "ilbc", 98 }, + { "ilbc20", 98 }, + { "ilbc30", 98 }, { "h261", 31 }, { "h263", 34 }, { "mpv", 32 }, diff --git a/modules/ysipchan.cpp b/modules/ysipchan.cpp index 18405651..0ce7abd4 100644 --- a/modules/ysipchan.cpp +++ b/modules/ysipchan.cpp @@ -42,6 +42,9 @@ static TokenDict dict_payloads[] = { { "g723", 4 }, { "g728", 15 }, { "g729", 18 }, + { "ilbc", 98 }, + { "ilbc20", 98 }, + { "ilbc30", 98 }, { "h261", 31 }, { "h263", 34 }, { "mpv", 32 }, @@ -60,6 +63,7 @@ static TokenDict dict_rtpmap[] = { { "G723/8000", 4 }, { "G728/8000", 15 }, { "G729/8000", 18 }, + { "iLBC/8000", 98 }, { "H261/90000", 31 }, { "H263/90000", 34 }, { "MPV/90000", 32 }, @@ -1663,10 +1667,16 @@ SDPBody* YateSIPConnection::createSDP(const char* addr, ObjList* mediaList) frm = *m; frm << " " << m->localPort() << " RTP/AVP"; ObjList rtpmap; + int ptime = 0; ObjList* f = l; for (; f; f = f->next()) { String* s = static_cast(f->get()); if (s) { + int mode = 0; + if (*s == "ilbc20") + ptime = mode = 20; + else if (*s == "ilbc30") + ptime = mode = 30; int payload = s->toInteger(dict_payloads,-1); if (payload >= 0) { const char* map = lookup(payload,dict_rtpmap); @@ -1675,6 +1685,11 @@ SDPBody* YateSIPConnection::createSDP(const char* addr, ObjList* mediaList) String* temp = new String("rtpmap:"); *temp << payload << " " << map; rtpmap.append(temp); + if (mode) { + temp = new String("fmtp:"); + *temp << payload << " mode=" << mode; + rtpmap.append(temp); + } } } } @@ -1687,6 +1702,12 @@ SDPBody* YateSIPConnection::createSDP(const char* addr, ObjList* mediaList) rtpmap.append(new String("rtpmap:101 telephone-event/8000")); } + if (ptime) { + String* temp = new String("ptime:"); + *temp << ptime; + rtpmap.append(temp); + } + sdp->addLine("m",frm); for (f = rtpmap.skipNull(); f; f = f->skipNext()) { String* s = static_cast(f->get());