summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2011-11-02 07:50:44 +0000
committerNanang Izzuddin <nanang@teluu.com>2011-11-02 07:50:44 +0000
commit3b778f399fc5ada686ed4bdc9f1ee93121c702e7 (patch)
tree03fe4803fac528492cd2a578a0d068c33459f61b
parent3769278bc589f06c94487b5ee958532403a813cc (diff)
Fix #1413: Fix G722.1 encoder to handle multiple frames per packet.
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@3880 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/src/pjmedia-codec/g7221.c82
1 files changed, 46 insertions, 36 deletions
diff --git a/pjmedia/src/pjmedia-codec/g7221.c b/pjmedia/src/pjmedia-codec/g7221.c
index f1aa8ab8..ce1ebaa5 100644
--- a/pjmedia/src/pjmedia-codec/g7221.c
+++ b/pjmedia/src/pjmedia-codec/g7221.c
@@ -748,15 +748,14 @@ static pj_status_t codec_encode( pjmedia_codec *codec,
struct pjmedia_frame *output)
{
codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
- const Word16 *pcm_input;
- Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
- Word16 mag_shift;
+ unsigned nsamples, processed;
/* Check frame in & out size */
- PJ_ASSERT_RETURN((pj_uint16_t)input->size ==
- (codec_data->samples_per_frame<<1),
- PJMEDIA_CODEC_EPCMTOOSHORT);
- PJ_ASSERT_RETURN(output_buf_len >= codec_data->frame_size,
+ nsamples = input->size >> 1;
+ PJ_ASSERT_RETURN(nsamples % codec_data->samples_per_frame == 0,
+ PJMEDIA_CODEC_EPCMFRMINLEN);
+ PJ_ASSERT_RETURN(output_buf_len >= codec_data->frame_size * nsamples /
+ codec_data->samples_per_frame,
PJMEDIA_CODEC_EFRMTOOSHORT);
/* Apply silence detection if VAD is enabled */
@@ -788,41 +787,52 @@ static pj_status_t codec_encode( pjmedia_codec *codec,
}
}
- /* Encoder adjust the input signal level */
- if (codec_data->pcm_shift) {
- unsigned i;
- pcm_input = (const Word16*)input->buf;
- for (i=0; i<codec_data->samples_per_frame; ++i) {
- codec_data->enc_frame[i] =
- (pj_int16_t)(pcm_input[i] >> codec_data->pcm_shift);
+ processed = 0;
+ output->size = 0;
+ while (processed < nsamples) {
+ Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
+ Word16 mag_shift;
+ const Word16 *pcm_input;
+ pj_int8_t *out_bits;
+
+ pcm_input = (const Word16*)input->buf + processed;
+ out_bits = (pj_int8_t*)output->buf + output->size;
+
+ /* Encoder adjust the input signal level */
+ if (codec_data->pcm_shift) {
+ unsigned i;
+ for (i=0; i<codec_data->samples_per_frame; ++i) {
+ codec_data->enc_frame[i] =
+ (Word16)(pcm_input[i] >> codec_data->pcm_shift);
+ }
+ pcm_input = codec_data->enc_frame;
}
- pcm_input = codec_data->enc_frame;
- } else {
- pcm_input = (const Word16*)input->buf;
- }
- /* Convert input samples to rmlt coefs */
- mag_shift = samples_to_rmlt_coefs(pcm_input,
- codec_data->enc_old_frame,
- mlt_coefs,
- codec_data->samples_per_frame);
+ /* Convert input samples to rmlt coefs */
+ mag_shift = samples_to_rmlt_coefs(pcm_input,
+ codec_data->enc_old_frame,
+ mlt_coefs,
+ codec_data->samples_per_frame);
- /* Encode the mlt coefs. Note that encoder output stream is 16 bit array,
- * so we need to take care about endianness.
- */
- encoder(codec_data->frame_size_bits,
- codec_data->number_of_regions,
- mlt_coefs,
- mag_shift,
- output->buf);
+ /* Encode the mlt coefs. Note that encoder output stream is
+ * 16 bit array, so we need to take care about endianness.
+ */
+ encoder(codec_data->frame_size_bits,
+ codec_data->number_of_regions,
+ mlt_coefs,
+ mag_shift,
+ (Word16*)out_bits);
+
+ /* Encoder output are in native host byte order, while ITU says
+ * it must be in network byte order (MSB first).
+ */
+ swap_bytes((pj_uint16_t*)out_bits, codec_data->frame_size/2);
- /* Encoder output are in native host byte order, while ITU says
- * it must be in network byte order (MSB first).
- */
- swap_bytes((pj_uint16_t*)output->buf, codec_data->frame_size/2);
+ processed += codec_data->samples_per_frame;
+ output->size += codec_data->frame_size;
+ }
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
- output->size = codec_data->frame_size;
output->timestamp = input->timestamp;
return PJ_SUCCESS;