コード例 #1
0
ファイル: opus.c プロジェクト: chriszeng87/pjproject
/*
 * Get frames in the packet.
 */
static pj_status_t  codec_parse( pjmedia_codec *codec,
				 void *pkt,
				 pj_size_t pkt_size,
				 const pj_timestamp *ts,
				 unsigned *frame_cnt,
				 pjmedia_frame frames[] )
{
    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
    unsigned char tmp_buf[MAX_ENCODED_PACKET_SIZE];
    int i, num_frames;
    int size, out_pos;
    unsigned samples_per_frame;
#if (USE_INCOMING_WORSE_SETTINGS)
    int bw;
#endif

    pj_mutex_lock (opus_data->mutex);

    if (pkt_size > sizeof(tmp_buf)) {
	PJ_LOG(5, (THIS_FILE, "Encoded size bigger than buffer"));
        pj_mutex_unlock (opus_data->mutex);
	return PJMEDIA_CODEC_EFRMTOOSHORT;
    }

    samples_per_frame = (opus_data->cfg.sample_rate *
			 opus_data->ptime) / 1000;

    pj_memcpy(tmp_buf, pkt, pkt_size);

    opus_repacketizer_init(opus_data->dec_packer);
    opus_repacketizer_cat(opus_data->dec_packer, tmp_buf, pkt_size);

    num_frames = opus_repacketizer_get_nb_frames(opus_data->dec_packer);
    out_pos = 0;
    for (i = 0; i < num_frames; ++i) {
	size = opus_repacketizer_out_range(opus_data->dec_packer, i, i+1,
					   ((unsigned char*)pkt) + out_pos,
					   sizeof(tmp_buf));
	if (size < 0) {
	    PJ_LOG(5, (THIS_FILE, "Parse failed! (%d)", pkt_size));
            pj_mutex_unlock (opus_data->mutex);
	    return PJMEDIA_CODEC_EFAILED;
	}
	frames[i].type = PJMEDIA_FRAME_TYPE_AUDIO;
	frames[i].buf = ((char*)pkt) + out_pos;
	frames[i].size = size;
	frames[i].timestamp.u64 = ts->u64 + i * samples_per_frame;
	out_pos += size;
    }
    *frame_cnt = num_frames;

    pj_mutex_unlock (opus_data->mutex);
    return PJ_SUCCESS;
}
コード例 #2
0
ファイル: opus.c プロジェクト: chriszeng87/pjproject
/*
 * Encode frame.
 */
static pj_status_t codec_encode( pjmedia_codec *codec, 
				 const struct pjmedia_frame *input,
				 unsigned output_buf_len, 
				 struct pjmedia_frame *output )
{
    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
    opus_int32 size  = 0;
    unsigned in_pos  = 0;
    unsigned out_pos = 0;
    unsigned frame_size;
    unsigned samples_per_frame;
    unsigned char tmp_buf[MAX_ENCODED_PACKET_SIZE];
    unsigned tmp_bytes_left = sizeof(tmp_buf);

    pj_mutex_lock (opus_data->mutex);

    samples_per_frame = (opus_data->cfg.sample_rate *
			 opus_data->ptime) / 1000;
    frame_size = samples_per_frame * opus_data->cfg.channel_cnt *
    		 sizeof(opus_int16);

    opus_repacketizer_init(opus_data->enc_packer);
    while (input->size - in_pos >= frame_size) {
	size = opus_encode(opus_data->enc,
			   (const opus_int16*)(((char*)input->buf) + in_pos),
			   samples_per_frame,
			   tmp_buf + out_pos,
			   (tmp_bytes_left < frame_size ?
			    tmp_bytes_left : frame_size));
	if (size < 0) {
	    PJ_LOG(4, (THIS_FILE, "Encode failed! (%d)", size));
            pj_mutex_unlock (opus_data->mutex);
	    return PJMEDIA_CODEC_EFAILED;
	} else if (size > 0) {
	    /* Only add packets containing more than the TOC */
	    opus_repacketizer_cat(opus_data->enc_packer,
				  tmp_buf + out_pos,
				  size);
	    out_pos += size;
	    tmp_bytes_left -= size;
	}
	in_pos += frame_size;
    }

    if (!opus_repacketizer_get_nb_frames(opus_data->enc_packer)) {
	/* Empty packet */
	output->size      = 0;
	output->type      = PJMEDIA_FRAME_TYPE_NONE;
	output->timestamp = input->timestamp;
    }

    if (size) {
	size = opus_repacketizer_out(opus_data->enc_packer,
				     output->buf,
				     output_buf_len);
	if (size < 0) {
	    PJ_LOG(4, (THIS_FILE, "Encode failed! (%d), out_size: %u",
	    			  size, output_buf_len));
	    pj_mutex_unlock (opus_data->mutex);
	    return PJMEDIA_CODEC_EFAILED;
	}
    }

    output->size      = (unsigned)size;
    output->type      = PJMEDIA_FRAME_TYPE_AUDIO;
    output->timestamp = input->timestamp;

    pj_mutex_unlock (opus_data->mutex);
    return PJ_SUCCESS;
}
コード例 #3
0
ファイル: opus_multistream.c プロジェクト: mehulsbhatt/vock
int opus_multistream_encode_float(
#endif
    OpusMSEncoder *st,
    const opus_val16 *pcm,
    int frame_size,
    unsigned char *data,
    opus_int32 max_data_bytes
)
{
   int coupled_size;
   int mono_size;
   int s, i;
   char *ptr;
   int tot_size;
   VARDECL(opus_val16, buf);
   unsigned char tmp_data[MS_FRAME_TMP];
   OpusRepacketizer rp;
   ALLOC_STACK;

   ALLOC(buf, 2*frame_size, opus_val16);
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
   coupled_size = opus_encoder_get_size(2);
   mono_size = opus_encoder_get_size(1);

   if (max_data_bytes < 4*st->layout.nb_streams-1)
   {
      RESTORE_STACK;
      return OPUS_BUFFER_TOO_SMALL;
   }
   /* Counting ToC */
   tot_size = 0;
   for (s=0;s<st->layout.nb_streams;s++)
   {
      OpusEncoder *enc;
      int len;
      int curr_max;

      opus_repacketizer_init(&rp);
      enc = (OpusEncoder*)ptr;
      if (s < st->layout.nb_coupled_streams)
      {
         int left, right;
         left = get_left_channel(&st->layout, s, -1);
         right = get_right_channel(&st->layout, s, -1);
         for (i=0;i<frame_size;i++)
         {
            buf[2*i] = pcm[st->layout.nb_channels*i+left];
            buf[2*i+1] = pcm[st->layout.nb_channels*i+right];
         }
         ptr += align(coupled_size);
      } else {
         int chan = get_mono_channel(&st->layout, s, -1);
         for (i=0;i<frame_size;i++)
            buf[i] = pcm[st->layout.nb_channels*i+chan];
         ptr += align(mono_size);
      }
      /* number of bytes left (+Toc) */
      curr_max = max_data_bytes - tot_size;
      /* Reserve three bytes for the last stream and four for the others */
      curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
      curr_max = IMIN(curr_max,MS_FRAME_TMP);
      len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max);
      if (len<0)
      {
         RESTORE_STACK;
         return len;
      }
      /* We need to use the repacketizer to add the self-delimiting lengths
         while taking into account the fact that the encoder can now return
         more than one frame at a time (e.g. 60 ms CELT-only) */
      opus_repacketizer_cat(&rp, tmp_data, len);
      len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1);
      data += len;
      tot_size += len;
   }
   RESTORE_STACK;
   return tot_size;

}