Ejemplo n.º 1
0
/*
 * Encode frame.
 */
static pj_status_t ilbc_codec_encode(pjmedia_codec *codec, 
				     const struct pjmedia_frame *input,
				     unsigned output_buf_len, 
				     struct pjmedia_frame *output)
{
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
    pj_int16_t *pcm_in;
    unsigned nsamples;
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
    UInt32 npackets;
    OSStatus err;
    AudioBufferList theABL;
#endif

    pj_assert(ilbc_codec && input && output);

    pcm_in = (pj_int16_t*)input->buf;
    nsamples = input->size >> 1;

    PJ_ASSERT_RETURN(nsamples % ilbc_codec->enc_samples_per_frame == 0, 
		     PJMEDIA_CODEC_EPCMFRMINLEN);
    PJ_ASSERT_RETURN(output_buf_len >= ilbc_codec->enc_frame_size * nsamples /
		     ilbc_codec->enc_samples_per_frame,
		     PJMEDIA_CODEC_EFRMTOOSHORT);

    /* Detect silence */
    if (ilbc_codec->vad_enabled) {
	pj_bool_t is_silence;
	pj_int32_t silence_period;

	silence_period = pj_timestamp_diff32(&ilbc_codec->last_tx,
					      &input->timestamp);

	is_silence = pjmedia_silence_det_detect(ilbc_codec->vad, 
					        (const pj_int16_t*)input->buf,
						(input->size >> 1),
						NULL);
	if (is_silence &&
	    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
	     silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))
	{
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->buf = NULL;
	    output->size = 0;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	} else {
	    ilbc_codec->last_tx = input->timestamp;
	}
    }
Ejemplo n.º 2
0
/*
 * Encode frame.
 */
static pj_status_t codec2_codec_encode( pjmedia_codec *codec,
				     const struct pjmedia_frame *input,
				     unsigned output_buf_len, 
				     struct pjmedia_frame *output)
{
    struct codec2_data *codec2_data = (struct codec2_data*) codec->codec_data;
    pj_int16_t *pcm_in;
    unsigned in_size;

  //  PJ_LOG(4, (THIS_FILE, "codec2 encode ...."));
    pj_assert(codec2_data && input && output);
    
    pcm_in = (pj_int16_t*)input->buf;
    in_size = input->size;
  //  PJ_LOG(4, (THIS_FILE, "codec2 encode %d ", input->size));

    PJ_ASSERT_RETURN(in_size % (CODEC2_SAMPLES_PER_FRAME*2) == 0, PJMEDIA_CODEC_EPCMFRMINLEN);
    //PJ_ASSERT_RETURN(output_buf_len >= BYTES_PER_FRAME * in_size/(CODEC2_SAMPLES_PER_FRAME*2),
	//	     PJMEDIA_CODEC_EFRMTOOSHORT);

    /* Detect silence */
    if (codec2_data->vad_enabled) {
	pj_bool_t is_silence;
	pj_int32_t silence_duration;

	silence_duration = pj_timestamp_diff32(&codec2_data->last_tx,
					       &input->timestamp);

	is_silence = pjmedia_silence_det_detect(codec2_data->vad,
					        (const pj_int16_t*) input->buf,
						(input->size >> 1),
						NULL);
	if (is_silence &&
	    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
	     silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))
	{
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->buf = NULL;
	    output->size = 0;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	} else {
		codec2_data->last_tx = input->timestamp;
	}
    }
Ejemplo n.º 3
0
static pj_status_t  g729_encode(pjmedia_codec *codec,
				const struct pjmedia_frame *input,
				unsigned output_buf_len,
				struct pjmedia_frame *output)
{
    struct g729_private *priv = (struct g729_private*) codec->codec_data;
    pj_int16_t *pcm_in;
    unsigned in_size;
 //   UWord8 bitstream[L_PACKED_G729A];
    int nb;

  pj_assert(priv && input && output);

  pcm_in = (pj_int16_t*)input->buf;
  in_size = input->size;

  PJ_ASSERT_RETURN(in_size % 160 == 0, PJMEDIA_CODEC_EPCMFRMINLEN);
  PJ_ASSERT_RETURN(output_buf_len >= L_PACKED_G729A * in_size/160,
                   PJMEDIA_CODEC_EFRMTOOSHORT);

    /* Detect silence if VAD is enabled */
    if (priv->vad_enabled) {
	pj_bool_t is_silence;
	pj_int32_t silence_period;

	silence_period = pj_timestamp_diff32(&priv->last_tx,
					     &input->timestamp);

	is_silence = pjmedia_silence_det_detect(priv->vad,
						(const pj_int16_t*) input->buf,
						(input->size >> 1), NULL);
	if (is_silence &&
	    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
	     silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))
	{
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->buf = NULL;
	    output->size = 0;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	} else {
	    priv->last_tx = input->timestamp;
	}
    }
Ejemplo n.º 4
0
/*
 * Encode frame.
 */
static pj_status_t gsm_codec_encode( pjmedia_codec *codec, 
				     const struct pjmedia_frame *input,
				     unsigned output_buf_len, 
				     struct pjmedia_frame *output)
{
    struct gsm_data *gsm_data = (struct gsm_data*) codec->codec_data;
    pj_int16_t *pcm_in;
    pj_size_t in_size;

    pj_assert(gsm_data && input && output);
    
    pcm_in = (pj_int16_t*)input->buf;
    in_size = input->size;

    PJ_ASSERT_RETURN(in_size % 320 == 0, PJMEDIA_CODEC_EPCMFRMINLEN);
    PJ_ASSERT_RETURN(output_buf_len >= 33 * in_size/320, 
		     PJMEDIA_CODEC_EFRMTOOSHORT);

    /* Detect silence */
    if (gsm_data->vad_enabled) {
	pj_bool_t is_silence;
	pj_int32_t silence_duration;

	silence_duration = pj_timestamp_diff32(&gsm_data->last_tx, 
					       &input->timestamp);

	is_silence = pjmedia_silence_det_detect(gsm_data->vad, 
					        (const pj_int16_t*) input->buf,
						(input->size >> 1),
						NULL);
	if (is_silence &&
	    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
	     silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))
	{
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->buf = NULL;
	    output->size = 0;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	} else {
	    gsm_data->last_tx = input->timestamp;
	}
    }
Ejemplo n.º 5
0
static pj_status_t l16_encode(pjmedia_codec *codec, 
			      const struct pjmedia_frame *input,
			      unsigned output_buf_len, 
			      struct pjmedia_frame *output)
{
    struct l16_data *data = (struct l16_data*) codec->codec_data;
    const pj_int16_t *samp = (const pj_int16_t*) input->buf;
    const pj_int16_t *samp_end = samp + input->size/sizeof(pj_int16_t);
    pj_int16_t *samp_out = (pj_int16_t*) output->buf;    

    pj_assert(data && input && output);

    /* Check output buffer length */
    if (output_buf_len < input->size)
	return PJMEDIA_CODEC_EFRMTOOSHORT;

    /* Detect silence */
    if (data->vad_enabled) {
	pj_bool_t is_silence;
	pj_int32_t silence_duration;

	silence_duration = pj_timestamp_diff32(&data->last_tx, 
					       &input->timestamp);

	is_silence = pjmedia_silence_det_detect(data->vad, 
					        (const pj_int16_t*) input->buf,
						(input->size >> 1),
						NULL);
	if (is_silence &&
	    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
	     silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*
			        (int)data->clock_rate/1000))
	{
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->buf = NULL;
	    output->size = 0;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	} else {
	    data->last_tx = input->timestamp;
	}
    }
Ejemplo n.º 6
0
/*
 * Encode frame.
 */
static pj_status_t ilbc_codec_encode(pjmedia_codec *codec, 
				     const struct pjmedia_frame *input,
				     unsigned output_buf_len, 
				     struct pjmedia_frame *output)
{
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
    unsigned i;

    pj_assert(ilbc_codec != NULL);
    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);

    if (output_buf_len < ilbc_codec->enc_frame_size)
	return PJMEDIA_CODEC_EFRMTOOSHORT;

    if (input->size != (ilbc_codec->enc_samples_per_frame << 1))
	return PJMEDIA_CODEC_EPCMFRMINLEN;

    /* Detect silence */
    if (ilbc_codec->vad_enabled) {
	pj_bool_t is_silence;
	pj_int32_t silence_period;

	silence_period = pj_timestamp_diff32(&ilbc_codec->last_tx,
					      &input->timestamp);

	is_silence = pjmedia_silence_det_detect(ilbc_codec->vad, 
					        input->buf,
						(input->size >> 1),
						NULL);
	if (is_silence &&
	    PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 &&
	    silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD)
	{
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->buf = NULL;
	    output->size = 0;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	} else {
	    ilbc_codec->last_tx = input->timestamp;
	}
    }
Ejemplo n.º 7
0
/*
 * Encode frame.
 */
static pj_status_t g726_codec_encode( pjmedia_codec *codec, 
				      const struct pjmedia_frame *input,
				      unsigned output_buf_len, 
				      struct pjmedia_frame *output)
{
    struct g726_private *priv = (struct g726_private*) codec->codec_data;
    unsigned samples, i;
    pj_uint8_t *dst;
    pj_int16_t *src;
    unsigned code;
    unsigned int out_buffer = 0;
    int out_bits = 0;

    /* Check output buffer length */
    if (output_buf_len < priv->encoded_frame_size)
	return PJMEDIA_CODEC_EFRMTOOSHORT;

    /* Detect silence if VAD is enabled */
    if (priv->vad_enabled) {
	pj_bool_t is_silence;
	pj_int32_t silence_period;

	silence_period = pj_timestamp_diff32(&priv->last_tx,
					     &input->timestamp);

	is_silence = pjmedia_silence_det_detect(priv->vad, 
						(const pj_int16_t*) input->buf, 
						(input->size >> 1), NULL);
	if (is_silence && 
	    (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
	     silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*SAMPLE_RATE/1000))
	{
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->buf = NULL;
	    output->size = 0;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	} else {
	    priv->last_tx = input->timestamp;
	}
    }
Ejemplo n.º 8
0
/*
 * Encode frame.
 */
static pj_status_t amr_codec_encode( pjmedia_codec *codec, 
				     const struct pjmedia_frame *input,
				     unsigned output_buf_len, 
				     struct pjmedia_frame *output)
{
    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
    unsigned char *bitstream;
    pj_int16_t *speech;
    unsigned nsamples, samples_per_frame;
    enum {MAX_FRAMES_PER_PACKET = 16};
    pjmedia_frame frames[MAX_FRAMES_PER_PACKET];
    pj_uint8_t *p;
    unsigned i, out_size = 0, nframes = 0;
    pj_size_t payload_len;
    unsigned dtx_cnt, sid_cnt;
    pj_status_t status;

    pj_assert(amr_data != NULL);
    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);

    nsamples = input->size >> 1;
    samples_per_frame = amr_data->clock_rate * FRAME_LENGTH_MS / 1000;
    PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0, 
		     PJMEDIA_CODEC_EPCMFRMINLEN);

    nframes = nsamples / samples_per_frame;
    PJ_ASSERT_RETURN(nframes <= MAX_FRAMES_PER_PACKET, 
		     PJMEDIA_CODEC_EFRMTOOSHORT);

    /* Encode the frames */
    speech = (pj_int16_t*)input->buf;
    bitstream = (unsigned char*)output->buf;
    while (nsamples >= samples_per_frame) {
	int size;
        if (amr_data->enc_setting.amr_nb) {
#ifdef USE_AMRNB
            size = Encoder_Interface_Encode (amr_data->encoder,
                                             amr_data->enc_mode,
                                             speech, bitstream, 0);
#else
            size = 0;
#endif
        } else {
#ifdef USE_AMRWB
            size = E_IF_encode (amr_data->encoder, amr_data->enc_mode,
                                speech, bitstream, 0);
#else
            size = 0;
#endif
        }
	if (size == 0) {
	    output->size = 0;
	    output->buf = NULL;
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    TRACE_((THIS_FILE, "AMR encode() failed"));
	    return PJMEDIA_CODEC_EFAILED;
	}
	nsamples -= samples_per_frame;
	speech += samples_per_frame;
	bitstream += size;
	out_size += size;
	TRACE_((THIS_FILE, "AMR encode(): mode=%d, size=%d",
		amr_data->enc_mode, out_size));
    }

    /* Pack payload */
    p = (pj_uint8_t*)output->buf + output_buf_len - out_size;
    pj_memmove(p, output->buf, out_size);
    dtx_cnt = sid_cnt = 0;
    for (i = 0; i < nframes; ++i) {
	pjmedia_codec_amr_bit_info *info = (pjmedia_codec_amr_bit_info*)
					   &frames[i].bit_info;
	info->frame_type = (pj_uint8_t)((*p >> 3) & 0x0F);
	info->good_quality = (pj_uint8_t)((*p >> 2) & 0x01);
	info->mode = (pj_int8_t)amr_data->enc_mode;
	info->start_bit = 0;
	frames[i].buf = p + 1;
        if (amr_data->enc_setting.amr_nb) {
            frames[i].size = (info->frame_type <= 8)?
                             pjmedia_codec_amrnb_framelen[info->frame_type] : 0;
        } else {
            frames[i].size = (info->frame_type <= 9)?
                             pjmedia_codec_amrwb_framelen[info->frame_type] : 0;
        }
	p += frames[i].size + 1;

	/* Count the number of SID and DTX frames */
	if (info->frame_type == 15) /* DTX*/
	    ++dtx_cnt;
	else if (info->frame_type == 8) /* SID */
	    ++sid_cnt;
    }

    /* VA generates DTX frames as DTX+SID frames switching quickly and it
     * seems that the SID frames occur too often (assuming the purpose is 
     * only for keeping NAT alive?). So let's modify the behavior a bit.
     * Only an SID frame will be sent every PJMEDIA_CODEC_MAX_SILENCE_PERIOD
     * milliseconds.
     */
    if (sid_cnt + dtx_cnt == nframes) {
	pj_int32_t dtx_duration;

	dtx_duration = pj_timestamp_diff32(&amr_data->last_tx, 
					   &input->timestamp);
	if (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
	    dtx_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*
                           amr_data->clock_rate/1000)
	{
	    output->size = 0;
	    output->type = PJMEDIA_FRAME_TYPE_NONE;
	    output->timestamp = input->timestamp;
	    return PJ_SUCCESS;
	}
    }

    payload_len = output_buf_len;

    status = pjmedia_codec_amr_pack(frames, nframes, &amr_data->enc_setting,
				    output->buf, &payload_len);
    if (status != PJ_SUCCESS) {
	output->size = 0;
	output->buf = NULL;
	output->type = PJMEDIA_FRAME_TYPE_NONE;
	TRACE_((THIS_FILE, "Failed to pack AMR payload, status=%d", status));
	return status;
    }

    output->size = payload_len;
    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
    output->timestamp = input->timestamp;

    amr_data->last_tx = input->timestamp;

    return PJ_SUCCESS;
}