From 3408c959390d71b7e24307a56cc02d796228dc28 Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Wed, 7 Apr 2010 13:21:31 +0000 Subject: More ticket #1055: - Added APS codecs detection. - Minor updates in symsndtest: - added log of supported extended audio formats. - changed libraries order in symsndtest.mmp, this fixes linking error on S60 3rd MR SDK. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3135 74dad513-b988-da41-8d7b-12977e46ad98 --- build.symbian/symsndtest.mmp | 3 +- pjmedia/include/pjmedia-audiodev/config.h | 19 ++++ pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp | 133 ++++++++++++++++++++++---- pjsip-apps/src/symsndtest/app_main.cpp | 33 +++++++ 4 files changed, 171 insertions(+), 17 deletions(-) diff --git a/build.symbian/symsndtest.mmp b/build.symbian/symsndtest.mmp index c729e1c5..fb375dbc 100644 --- a/build.symbian/symsndtest.mmp +++ b/build.symbian/symsndtest.mmp @@ -29,8 +29,9 @@ SYSTEMINCLUDE \epoc32\include\libc LIBRARY charconv.lib euser.lib estlib.lib LIBRARY esock.lib insock.lib -STATICLIBRARY pjlib.lib pjmedia.lib STATICLIBRARY pjmedia_audiodev.lib +STATICLIBRARY pjmedia.lib +STATICLIBRARY pjlib.lib STATICLIBRARY libresample.lib #if SND_USE_APS diff --git a/pjmedia/include/pjmedia-audiodev/config.h b/pjmedia/include/pjmedia-audiodev/config.h index e9e13a72..15e5a149 100644 --- a/pjmedia/include/pjmedia-audiodev/config.h +++ b/pjmedia/include/pjmedia-audiodev/config.h @@ -90,6 +90,25 @@ PJ_BEGIN_DECL #endif +/** + * This setting controls whether Symbian APS should perform codec + * detection in its factory initalization. Note that codec detection + * may take few seconds and detecting more codecs will take more time. + * Possible values are: + * - 0: no codec detection, all APS codec (AMR-NB, G.711, G.729, and + * iLBC) will be assumed as supported. + * - 1: minimal codec detection, i.e: only detect for AMR-NB and G.711, + * (G.729 and iLBC are considered to be supported/unsupported when + * G.711 is supported/unsupported). + * - 2: full codec detection, i.e: detect AMR-NB, G.711, G.729, and iLBC. + * + * Default: 1 (minimal codec detection) + */ +#ifndef PJMEDIA_AUDIO_DEV_SYMB_APS_DETECTS_CODEC +# define PJMEDIA_AUDIO_DEV_SYMB_APS_DETECTS_CODEC 1 +#endif + + /** * This setting controls whether Symbian VAS support should be included. */ diff --git a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp index d259f32b..5d926cf5 100644 --- a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp +++ b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp @@ -1293,28 +1293,129 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f) af->dev_info.input_count = 1; af->dev_info.output_count = 1; - af->dev_info.ext_fmt_cnt = 5; + /* Enumerate codecs by trying to initialize each codec and examining + * the error code. Consider the following: + * - not possible to reinitialize the same APS session with + * different settings, + * - closing APS session and trying to immediately reconnect may fail, + * clients should wait ~5s before attempting to reconnect. + */ - af->dev_info.ext_fmt[0].id = PJMEDIA_FORMAT_AMR; - af->dev_info.ext_fmt[0].bitrate = 7400; - af->dev_info.ext_fmt[0].vad = PJ_TRUE; + unsigned i, fmt_cnt = 0; + pj_bool_t g711_supported = PJ_FALSE; - af->dev_info.ext_fmt[1].id = PJMEDIA_FORMAT_G729; - af->dev_info.ext_fmt[1].bitrate = 8000; - af->dev_info.ext_fmt[1].vad = PJ_FALSE; + /* Do not change the order! */ + TFourCC fourcc[] = { + TFourCC(KMCPFourCCIdAMRNB), + TFourCC(KMCPFourCCIdG711), + TFourCC(KMCPFourCCIdG729), + TFourCC(KMCPFourCCIdILBC) + }; - af->dev_info.ext_fmt[2].id = PJMEDIA_FORMAT_ILBC; - af->dev_info.ext_fmt[2].bitrate = 13333; - af->dev_info.ext_fmt[2].vad = PJ_TRUE; + for (i = 0; i < PJ_ARRAY_SIZE(fourcc); ++i) { + pj_bool_t supported = PJ_FALSE; + unsigned retry_cnt = 0; + enum { MAX_RETRY = 3 }; + +#if (PJMEDIA_AUDIO_DEV_SYMB_APS_DETECTS_CODEC == 0) + /* Codec detection is disabled */ + supported = PJ_TRUE; +#elif (PJMEDIA_AUDIO_DEV_SYMB_APS_DETECTS_CODEC == 1) + /* Minimal codec detection, AMR-NB and G.711 only */ + if (i > 1) { + /* If G.711 has been checked, skip G.729 and iLBC checks */ + retry_cnt = MAX_RETRY; + supported = g711_supported; + } +#endif + + while (!supported && ++retry_cnt <= MAX_RETRY) { + RAPSSession iSession; + TAPSInitSettings iPlaySettings; + TAPSInitSettings iRecSettings; + TInt err; - af->dev_info.ext_fmt[3].id = PJMEDIA_FORMAT_PCMU; - af->dev_info.ext_fmt[3].bitrate = 64000; - af->dev_info.ext_fmt[3].vad = PJ_FALSE; + // Recorder settings + iRecSettings.iGlobal = APP_UID; + iRecSettings.iPriority = TMdaPriority(100); + iRecSettings.iPreference = TMdaPriorityPreference(0x05210001); + iRecSettings.iSettings.iChannels = EMMFMono; + iRecSettings.iSettings.iSampleRate = EMMFSampleRate8000Hz; + + // Player settings + iPlaySettings.iGlobal = APP_UID; + iPlaySettings.iPriority = TMdaPriority(100); + iPlaySettings.iPreference = TMdaPriorityPreference(0x05220001); + iPlaySettings.iSettings.iChannels = EMMFMono; + iPlaySettings.iSettings.iSampleRate = EMMFSampleRate8000Hz; + + iRecSettings.iFourCC = iPlaySettings.iFourCC = fourcc[i]; + + err = iSession.Connect(); + if (err == KErrNone) + err = iSession.InitializePlayer(iPlaySettings); + if (err == KErrNone) + err = iSession.InitializeRecorder(iRecSettings); + iSession.Close(); + + if (err == KErrNone) { + /* All fine, stop retyring */ + supported = PJ_TRUE; + } else if (err == KErrAlreadyExists && retry_cnt < MAX_RETRY) { + /* Seems that the previous session is still arround, + * let's wait before retrying. + */ + enum { RETRY_WAIT = 3000 }; /* in msecs */ + TTime start, now; + + start.UniversalTime(); + do { + pj_symbianos_poll(-1, RETRY_WAIT); + now.UniversalTime(); + } while (now.MicroSecondsFrom(start) < RETRY_WAIT * 1000); + } else { + /* Seems that this format is not supported */ + retry_cnt = MAX_RETRY; + } + } - af->dev_info.ext_fmt[4].id = PJMEDIA_FORMAT_PCMA; - af->dev_info.ext_fmt[4].bitrate = 64000; - af->dev_info.ext_fmt[4].vad = PJ_FALSE; + if (supported) { + switch(i) { + case 0: /* AMRNB */ + af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_AMR; + af->dev_info.ext_fmt[fmt_cnt].bitrate = 7400; + af->dev_info.ext_fmt[fmt_cnt].vad = PJ_TRUE; + ++fmt_cnt; + break; + case 1: /* G.711 */ + af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_PCMU; + af->dev_info.ext_fmt[fmt_cnt].bitrate = 64000; + af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE; + ++fmt_cnt; + af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_PCMA; + af->dev_info.ext_fmt[fmt_cnt].bitrate = 64000; + af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE; + ++fmt_cnt; + g711_supported = PJ_TRUE; + break; + case 2: /* G.729 */ + af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_G729; + af->dev_info.ext_fmt[fmt_cnt].bitrate = 8000; + af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE; + ++fmt_cnt; + break; + case 3: /* iLBC */ + af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_ILBC; + af->dev_info.ext_fmt[fmt_cnt].bitrate = 13333; + af->dev_info.ext_fmt[fmt_cnt].vad = PJ_TRUE; + ++fmt_cnt; + break; + } + } + } + af->dev_info.ext_fmt_cnt = fmt_cnt; + PJ_LOG(4, (THIS_FILE, "APS initialized")); return PJ_SUCCESS; diff --git a/pjsip-apps/src/symsndtest/app_main.cpp b/pjsip-apps/src/symsndtest/app_main.cpp index c43a5566..2458e7c3 100644 --- a/pjsip-apps/src/symsndtest/app_main.cpp +++ b/pjsip-apps/src/symsndtest/app_main.cpp @@ -123,6 +123,39 @@ static pj_status_t app_init() PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz", i, info.name, info.input_count, info.output_count, info.default_samples_per_sec)); + + unsigned j; + + /* Print extended formats supported by this audio device */ + PJ_LOG(3, (THIS_FILE, " Extended formats supported:")); + for (j = 0; j < info.ext_fmt_cnt; ++j) { + const char *fmt_name = NULL; + + switch (info.ext_fmt[j].id) { + case PJMEDIA_FORMAT_PCMA: + fmt_name = "PCMA"; + break; + case PJMEDIA_FORMAT_PCMU: + fmt_name = "PCMU"; + break; + case PJMEDIA_FORMAT_AMR: + fmt_name = "AMR-NB"; + break; + case PJMEDIA_FORMAT_G729: + fmt_name = "G729"; + break; + case PJMEDIA_FORMAT_ILBC: + fmt_name = "ILBC"; + break; + case PJMEDIA_FORMAT_PCM: + fmt_name = "PCM"; + break; + default: + fmt_name = "Unknown"; + break; + } + PJ_LOG(3, (THIS_FILE, " - %s", fmt_name)); + } } /* Create pool */ -- cgit v1.2.3