summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2010-03-04 15:47:25 +0000
committerNanang Izzuddin <nanang@teluu.com>2010-03-04 15:47:25 +0000
commitac131cb38e62d9b73fc857e270430c0f9ecab27c (patch)
tree075ec44e2b62212c128e4bdd9999e21bc922fb49
parentc2d852485b8591782c9b371f6b277d4a4d0cd35f (diff)
Ticket #1008:
- Applied VAS AMR playback solution from Forum Nokia. - Fixed AMR playback for VAS and APS in composing DTX/NO_DATA (frame type 15) frame header. - Modified symbsndtest test application to support non-PCM audio. - Minor check fix in pjmedia_codec_mgr_destroy(), caught assertion when VAS factory init failed and media endpoint tried to destroy codec manager (codec mgr hasn't been init-ed). git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3116 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp12
-rw-r--r--pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp37
-rw-r--r--pjmedia/src/pjmedia/codec.c6
-rw-r--r--pjsip-apps/src/symsndtest/app_main.cpp56
4 files changed, 84 insertions, 27 deletions
diff --git a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
index b544f9cd..1d818b7e 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
@@ -1034,14 +1034,20 @@ static void PlayCb(TAPSCommBuffer &buf, void *user_data)
buf.iBuffer.Append((TUint8*)sf->data, len);
} else {
- buf.iBuffer.Append(0);
+ enum {NO_DATA_FT = 15 };
+ pj_uint8_t amr_header = 4 || (NO_DATA_FT << 3);
+
+ buf.iBuffer.Append(amr_header);
}
pjmedia_frame_ext_pop_subframes(frame, 1);
} else { /* PJMEDIA_FRAME_TYPE_NONE */
- buf.iBuffer.Append(0);
-
+ enum {NO_DATA_FT = 15 };
+ pj_uint8_t amr_header = 4 || (NO_DATA_FT << 3);
+
+ buf.iBuffer.Append(amr_header);
+
frame->samples_cnt = 0;
frame->subframe_cnt = 0;
}
diff --git a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
index ae9b43c6..08e36fe9 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
@@ -415,7 +415,7 @@ TInt CPjAudioEngine::InitRec()
TInt CPjAudioEngine::StartPlay()
{
- TInt err;
+ TInt err = KErrNone;
pj_assert(iVoIPDnlink);
pj_assert(dn_state_ == STATE_READY);
@@ -428,7 +428,6 @@ TInt CPjAudioEngine::StartPlay()
dec_fmt_if;
err = g711dec_if->SetMode((CVoIPFormatIntfc::TG711CodecMode)
setting_.mode);
- pj_assert(err == KErrNone);
}
break;
@@ -438,20 +437,28 @@ TInt CPjAudioEngine::StartPlay()
dec_fmt_if;
err = ilbcdec_if->SetMode((CVoIPFormatIntfc::TILBCCodecMode)
setting_.mode);
- pj_assert(err == KErrNone);
}
break;
+ case EAMR_NB:
+ /* Ticket #1008: AMR playback issue on few devices, e.g: E72, E52 */
+ err = dec_fmt_if->SetFrameMode(ETrue);
+ break;
+
default:
break;
}
+
+ if (err != KErrNone)
+ goto on_return;
/* Configure audio routing */
ActivateSpeaker(setting_.loudspk);
/* Start player */
err = iVoIPDnlink->Start();
-
+
+on_return:
if (err == KErrNone) {
dn_state_ = STATE_STREAMING;
TRACE_((THIS_FILE, "Downlink started"));
@@ -464,7 +471,7 @@ TInt CPjAudioEngine::StartPlay()
TInt CPjAudioEngine::StartRec()
{
- TInt err;
+ TInt err = KErrNone;
pj_assert(iVoIPUplink);
pj_assert(up_state_ == STATE_READY);
@@ -477,7 +484,6 @@ TInt CPjAudioEngine::StartRec()
enc_fmt_if;
err = g711enc_if->SetMode((CVoIPFormatIntfc::TG711CodecMode)
setting_.mode);
- pj_assert(err == KErrNone);
}
break;
@@ -487,24 +493,27 @@ TInt CPjAudioEngine::StartRec()
enc_fmt_if;
err = ilbcenc_if->SetMode((CVoIPFormatIntfc::TILBCCodecMode)
setting_.mode);
- pj_assert(err == KErrNone);
}
break;
case EAMR_NB:
- enc_fmt_if->SetBitRate(setting_.mode);
+ err = enc_fmt_if->SetBitRate(setting_.mode);
break;
default:
break;
}
+ if (err != KErrNone)
+ goto on_return;
+
/* Configure general codec setting */
enc_fmt_if->SetVAD(setting_.vad);
/* Start recorder */
err = iVoIPUplink->Start();
-
+
+on_return:
if (err == KErrNone) {
up_state_ = STATE_STREAMING;
TRACE_((THIS_FILE, "Uplink started"));
@@ -1112,13 +1121,19 @@ static void PlayCb(CVoIPDataBuffer *buf, void *user_data)
buffer.Append((TUint8*)sf->data, len);
} else {
- buffer.Append(0);
+ enum {NO_DATA_FT = 15 };
+ pj_uint8_t amr_header = 4 || (NO_DATA_FT << 3);
+
+ buffer.Append(amr_header);
}
pjmedia_frame_ext_pop_subframes(frame, 1);
} else { /* PJMEDIA_FRAME_TYPE_NONE */
- buffer.Append(0);
+ enum {NO_DATA_FT = 15 };
+ pj_uint8_t amr_header = 4 || (NO_DATA_FT << 3);
+
+ buffer.Append(amr_header);
frame->samples_cnt = 0;
frame->subframe_cnt = 0;
diff --git a/pjmedia/src/pjmedia/codec.c b/pjmedia/src/pjmedia/codec.c
index d65ede4e..39d77834 100644
--- a/pjmedia/src/pjmedia/codec.c
+++ b/pjmedia/src/pjmedia/codec.c
@@ -85,10 +85,12 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_destroy (pjmedia_codec_mgr *mgr)
}
/* Destroy mutex */
- pj_mutex_destroy(mgr->mutex);
+ if (mgr->mutex)
+ pj_mutex_destroy(mgr->mutex);
/* Release pool */
- pj_pool_release(mgr->pool);
+ if (mgr->pool)
+ pj_pool_release(mgr->pool);
/* Just for safety, set codec manager states to zero */
pj_bzero(mgr, sizeof(pjmedia_codec_mgr));
diff --git a/pjsip-apps/src/symsndtest/app_main.cpp b/pjsip-apps/src/symsndtest/app_main.cpp
index e58be081..c43a5566 100644
--- a/pjsip-apps/src/symsndtest/app_main.cpp
+++ b/pjsip-apps/src/symsndtest/app_main.cpp
@@ -40,9 +40,27 @@ static pj_caching_pool cp;
static pjmedia_aud_stream *strm;
static unsigned rec_cnt, play_cnt;
static pj_time_val t_start;
+static pjmedia_aud_param param;
+static pj_pool_t *pool;
+static pjmedia_delay_buf *delaybuf;
+static char frame_buf[256];
-pj_pool_t *pool;
-pjmedia_delay_buf *delaybuf;
+static void copy_frame_ext(pjmedia_frame_ext *f_dst,
+ const pjmedia_frame_ext *f_src)
+{
+ pj_bzero(f_dst, sizeof(*f_dst));
+ if (f_src->subframe_cnt) {
+ f_dst->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
+ for (unsigned i = 0; i < f_src->subframe_cnt; ++i) {
+ pjmedia_frame_ext_subframe *sf;
+ sf = pjmedia_frame_ext_get_subframe(f_src, i);
+ pjmedia_frame_ext_append_subframe(f_dst, sf->data, sf->bitlen,
+ param.samples_per_frame);
+ }
+ } else {
+ f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;
+ }
+}
/* Logging callback */
static void log_writer(int level, const char *buf, unsigned len)
@@ -137,11 +155,18 @@ static pj_status_t rec_cb(void *user_data,
{
PJ_UNUSED_ARG(user_data);
- pjmedia_delay_buf_put(delaybuf, (pj_int16_t*)frame->buf);
-
- if (frame->size != SAMPLES_PER_FRAME*2) {
- PJ_LOG(3, (THIS_FILE, "Size captured = %u",
- frame->size));
+ if (param.ext_fmt.id == PJMEDIA_FORMAT_PCM) {
+ pjmedia_delay_buf_put(delaybuf, (pj_int16_t*)frame->buf);
+
+ if (frame->size != SAMPLES_PER_FRAME*2) {
+ PJ_LOG(3, (THIS_FILE, "Size captured = %u",
+ frame->size));
+ }
+ } else {
+ pjmedia_frame_ext *f_src = (pjmedia_frame_ext*)frame;
+ pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame_buf;
+
+ copy_frame_ext(f_dst, f_src);
}
++rec_cnt;
@@ -154,9 +179,16 @@ static pj_status_t play_cb(void *user_data,
{
PJ_UNUSED_ARG(user_data);
- pjmedia_delay_buf_get(delaybuf, (pj_int16_t*)frame->buf);
- frame->size = SAMPLES_PER_FRAME*2;
- frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+ if (param.ext_fmt.id == PJMEDIA_FORMAT_PCM) {
+ pjmedia_delay_buf_get(delaybuf, (pj_int16_t*)frame->buf);
+ frame->size = SAMPLES_PER_FRAME*2;
+ frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+ } else {
+ pjmedia_frame_ext *f_src = (pjmedia_frame_ext*)frame_buf;
+ pjmedia_frame_ext *f_dst = (pjmedia_frame_ext*)frame;
+
+ copy_frame_ext(f_dst, f_src);
+ }
++play_cnt;
return PJ_SUCCESS;
@@ -165,7 +197,6 @@ static pj_status_t play_cb(void *user_data,
/* Start sound */
static pj_status_t snd_start(unsigned flag)
{
- pjmedia_aud_param param;
pj_status_t status;
if (strm != NULL) {
@@ -178,6 +209,9 @@ static pj_status_t snd_start(unsigned flag)
param.clock_rate = CLOCK_RATE;
param.samples_per_frame = SAMPLES_PER_FRAME;
param.dir = (pjmedia_dir) flag;
+ param.ext_fmt.id = PJMEDIA_FORMAT_AMR;
+ param.ext_fmt.bitrate = 12200;
+ param.output_route = PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
status = pjmedia_aud_stream_create(&param, &rec_cb, &play_cb, NULL, &strm);
if (status != PJ_SUCCESS) {