Example #1
0
OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
{
   int ret;
   OpusDecoder *st = NULL;
   if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
    || (channels!=1&&channels!=2))
   {
      if (error)
         *error = OPUS_BAD_ARG;
      return NULL;
   }
   if (STATIC_DECODER_SIZE >= opus_decoder_get_size(channels))
      st = (OpusDecoder *)s_dec;
   else
      st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));

   if (st == NULL)
   {
      if (error)
         *error = OPUS_ALLOC_FAIL;
      return NULL;
   }
   ret = opus_decoder_init(st, Fs, channels);
   if (error)
      *error = ret;
   if (ret != OPUS_OK)
   {
      opus_free(st);
      st = NULL;
   }
   return st;
}
opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
{
   int coupled_size;
   int mono_size;

   if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
   coupled_size = opus_decoder_get_size(2);
   mono_size = opus_decoder_get_size(1);
   return align(sizeof(OpusMSDecoder))
         + nb_coupled_streams * align(coupled_size)
         + (nb_streams-nb_coupled_streams) * align(mono_size);
}
Example #3
0
bool FVoiceDecoderOpus::Init(int32 InSampleRate, int32 InNumChannels)
{
	UE_LOG(LogVoiceDecode, Display, TEXT("DecoderVersion: %s"), ANSI_TO_TCHAR(opus_get_version_string()));

	SampleRate = InSampleRate;
	NumChannels = InNumChannels;

	FrameSize = SampleRate / 50;

	int32 DecSize = 0;
	int32 DecError = 0;

#if USE_UE4_MEM_ALLOC
	DecSize = opus_decoder_get_size(NumChannels);
	Decoder = (OpusDecoder*)FMemory::Malloc(DecSize);
	DecError = opus_decoder_init(Decoder, SampleRate, NumChannels);
#else
	Decoder = opus_decoder_create(SampleRate, NumChannels, &DecError);
#endif
	if (DecError != OPUS_OK)
	{
		UE_LOG(LogVoiceDecode, Warning, TEXT("Failed to init Opus Decoder: %s"), ANSI_TO_TCHAR(opus_strerror(DecError)));
		Destroy();
	}

	return DecError == OPUS_OK;
}
int opus_multistream_decoder_init(
      OpusMSDecoder *st,
      opus_int32 Fs,
      int channels,
      int streams,
      int coupled_streams,
      const unsigned char *mapping
)
{
   int coupled_size;
   int mono_size;
   int i, ret;
   char *ptr;

   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
       (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
      return OPUS_BAD_ARG;

   st->layout.nb_channels = channels;
   st->layout.nb_streams = streams;
   st->layout.nb_coupled_streams = coupled_streams;

   for (i=0;i<st->layout.nb_channels;i++)
      st->layout.mapping[i] = mapping[i];
   if (!validate_layout(&st->layout))
      return OPUS_BAD_ARG;

   ptr = (char*)st + align(sizeof(OpusMSDecoder));
   coupled_size = opus_decoder_get_size(2);
   mono_size = opus_decoder_get_size(1);

   for (i=0;i<st->layout.nb_coupled_streams;i++)
   {
      ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
      if(ret!=OPUS_OK)return ret;
      ptr += align(coupled_size);
   }
   for (;i<st->layout.nb_streams;i++)
   {
      ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
      if(ret!=OPUS_OK)return ret;
      ptr += align(mono_size);
   }
   return OPUS_OK;
}
JNIEXPORT jboolean JNICALL Java_com_score_rahasak_utils_OpusDecoder_nativeInitDecoder (JNIEnv *env, jobject obj, jint samplingRate, jint numberOfChannels, jint frameSize)
{
	FRAME_SIZE = frameSize;
	SAMPLING_RATE = samplingRate;
	CHANNELS = numberOfChannels;

	int size;
	int error;

	size = opus_decoder_get_size(CHANNELS);
	dec = malloc(size);
	error = opus_decoder_init(dec, SAMPLING_RATE, CHANNELS);

	sprintf(logMsg, "Initialized Decoder with ErrorCode: %d", error);
	__android_log_write(ANDROID_LOG_DEBUG, "Native Code:", logMsg);

	return error;
}
Example #6
0
int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
{
   void *silk_dec;
   CELTDecoder *celt_dec;
   int ret, silkDecSizeBytes;

   if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
    || (channels!=1&&channels!=2))
      return OPUS_BAD_ARG;

   OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
   /* Initialize SILK encoder */
   ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
   if (ret)
      return OPUS_INTERNAL_ERROR;

   silkDecSizeBytes = align(silkDecSizeBytes);
   st->silk_dec_offset = align(sizeof(OpusDecoder));
   st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;
   silk_dec = (char*)st+st->silk_dec_offset;
   celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
   st->stream_channels = st->channels = channels;

   st->Fs = Fs;
   st->DecControl.API_sampleRate = st->Fs;
   st->DecControl.nChannelsAPI      = st->channels;
   st->arch = opus_select_arch();

   /* Reset decoder */
   ret = silk_InitDecoder( silk_dec );
   if(ret)return OPUS_INTERNAL_ERROR;

   /* Initialize CELT decoder */
   ret = celt_decoder_init(celt_dec, Fs, channels);
   if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;

   celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));

   st->prev_mode = 0;
   st->frame_size = Fs/400;
   return OPUS_OK;
}
Example #7
0
int test_decoder_code0(int no_fuzz)
{
   static const opus_int32 fsv[5]={48000,24000,16000,12000,8000};
   int err,skip,plen;
   int out_samples,fec;
   int t;
   opus_int32 i;
   OpusDecoder *dec[5*2];
   opus_int32 decsize;
   OpusDecoder *decbak;
   opus_uint32 dec_final_range1,dec_final_range2,dec_final_acc;
   unsigned char *packet;
   unsigned char modes[4096];
   short *outbuf_int;
   short *outbuf;

   dec_final_range1=dec_final_range2=2;

   packet=malloc(sizeof(unsigned char)*MAX_PACKET);
   if(packet==NULL)test_failed();

   outbuf_int=malloc(sizeof(short)*(MAX_FRAME_SAMP+16)*2);
   for(i=0;i<(MAX_FRAME_SAMP+16)*2;i++)outbuf_int[i]=32749;
   outbuf=&outbuf_int[8*2];

   fprintf(stdout,"  Starting %d decoders...\n",5*2);
   for(t=0;t<5*2;t++)
   {
      int fs=fsv[t>>1];
      int c=(t&1)+1;
      err=OPUS_INTERNAL_ERROR;
      dec[t] = opus_decoder_create(fs, c, &err);
      if(err!=OPUS_OK || dec[t]==NULL)test_failed();
      fprintf(stdout,"    opus_decoder_create(%5d,%d) OK. Copy ",fs,c);
      {
         OpusDecoder *dec2;
         /*The opus state structures contain no pointers and can be freely copied*/
         dec2=(OpusDecoder *)malloc(opus_decoder_get_size(c));
         if(dec2==NULL)test_failed();
         memcpy(dec2,dec[t],opus_decoder_get_size(c));
         memset(dec[t],255,opus_decoder_get_size(c));
         opus_decoder_destroy(dec[t]);
         printf("OK.\n");
         dec[t]=dec2;
      }
   }

   decsize=opus_decoder_get_size(1);
   decbak=(OpusDecoder *)malloc(decsize);
   if(decbak==NULL)test_failed();

   for(t=0;t<5*2;t++)
   {
      int factor=48000/fsv[t>>1];
      for(fec=0;fec<2;fec++)
      {
         opus_int32 dur;
         /*Test PLC on a fresh decoder*/
         out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);
         if(out_samples!=120/factor)test_failed();
         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
         if(dur!=120/factor)test_failed();

         /*Test on a size which isn't a multiple of 2.5ms*/
         out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor+2, fec);
         if(out_samples!=OPUS_BAD_ARG)test_failed();

         /*Test null pointer input*/
         out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec);
         if(out_samples!=120/factor)test_failed();
         out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec);
         if(out_samples!=120/factor)test_failed();
         out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec);
         if(out_samples!=120/factor)test_failed();
         out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec);
         if(out_samples!=120/factor)test_failed();
         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
         if(dur!=120/factor)test_failed();

         /*Zero lengths*/
         out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec);
         if(out_samples!=120/factor)test_failed();

         /*Zero buffer*/
         outbuf[0]=32749;
         out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec);
         if(out_samples>0)test_failed();
#if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull"
#endif
         out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);
#if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
#pragma GCC diagnostic pop
#endif
         if(out_samples>0)test_failed();
         if(outbuf[0]!=32749)test_failed();

         /*Invalid lengths*/
         out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec);
         if(out_samples>=0)test_failed();
         out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec);
         if(out_samples>=0)test_failed();
         out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec);
         if(out_samples>=0)test_failed();

         /*Crazy FEC values*/
         out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2);
         if(out_samples>=0)test_failed();

         /*Reset the decoder*/
         if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
      }
   }
   fprintf(stdout,"  dec[all] initial frame PLC OK.\n");

   /*Count code 0 tests*/
   for(i=0;i<64;i++)
   {
      opus_int32 dur;
      int j,expected[5*2];
      packet[0]=i<<2;
      packet[1]=255;
      packet[2]=255;
      err=opus_packet_get_nb_channels(packet);
      if(err!=(i&1)+1)test_failed();

      for(t=0;t<5*2;t++){
         expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
         if(expected[t]>2880)test_failed();
      }

      for(j=0;j<256;j++)
      {
         packet[1]=j;
         for(t=0;t<5*2;t++)
         {
            out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
            if(out_samples!=expected[t])test_failed();
            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
            if(dur!=out_samples)test_failed();
            opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
            if(t==0)dec_final_range2=dec_final_range1;
            else if(dec_final_range1!=dec_final_range2)test_failed();
         }
      }

      for(t=0;t<5*2;t++){
         int factor=48000/fsv[t>>1];
         /* The PLC is run for 6 frames in order to get better PLC coverage. */
         for(j=0;j<6;j++)
         {
            out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);
            if(out_samples!=expected[t])test_failed();
            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
            if(dur!=out_samples)test_failed();
         }
         /* Run the PLC once at 2.5ms, as a simulation of someone trying to
            do small drift corrections. */
         if(expected[t]!=120/factor)
         {
            out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
            if(out_samples!=120/factor)test_failed();
            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
            if(dur!=out_samples)test_failed();
         }
         out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
         if(out_samples>0)test_failed();
      }
   }
   fprintf(stdout,"  dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n");

   if(no_fuzz)
   {
      fprintf(stdout,"  Skipping many tests which fuzz the decoder as requested.\n");
      free(decbak);
      for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
      printf("  Decoders stopped.\n");

      err=0;
      for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
      for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
      if(err)test_failed();

      free(outbuf_int);
      free(packet);
      return 0;
   }

   {
     /*We only test a subset of the modes here simply because the longer
       durations end up taking a long time.*/
      static const int cmodes[4]={16,20,24,28};
      static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u};
      static const opus_uint32 lres[3]={3285687739u,1481572662,694350475};
      static const int lmodes[3]={0,4,8};
      int mode=fast_rand()%4;

      packet[0]=cmodes[mode]<<3;
      dec_final_acc=0;
      t=fast_rand()%10;

      for(i=0;i<65536;i++)
      {
         int factor=48000/fsv[t>>1];
         packet[1]=i>>8;
         packet[2]=i&255;
         packet[3]=255;
         out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
         if(out_samples!=120/factor)test_failed();
         opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
         dec_final_acc+=dec_final_range1;
      }
      if(dec_final_acc!=cres[mode])test_failed();
      fprintf(stdout,"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]);

      mode=fast_rand()%3;
      packet[0]=lmodes[mode]<<3;
      dec_final_acc=0;
      t=fast_rand()%10;
      for(i=0;i<65536;i++)
      {
         int factor=48000/fsv[t>>1];
         packet[1]=i>>8;
         packet[2]=i&255;
         packet[3]=255;
         out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
         if(out_samples!=480/factor)test_failed();
         opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
         dec_final_acc+=dec_final_range1;
      }
      if(dec_final_acc!=lres[mode])test_failed();
      fprintf(stdout,"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]);
   }

   skip=fast_rand()%7;
   for(i=0;i<64;i++)
   {
      int j,expected[5*2];
      packet[0]=i<<2;
      for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
      for(j=2+skip;j<1275;j+=4)
      {
         int jj;
         for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255;
         for(t=0;t<5*2;t++)
         {
            out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0);
            if(out_samples!=expected[t])test_failed();
            opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
            if(t==0)dec_final_range2=dec_final_range1;
            else if(dec_final_range1!=dec_final_range2)test_failed();
         }
      }
   }
   fprintf(stdout,"  dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\n",2+skip);

   debruijn2(64,modes);
   plen=(fast_rand()%18+3)*8+skip+3;
   for(i=0;i<4096;i++)
   {
      int j,expected[5*2];
      packet[0]=modes[i]<<2;
      for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
      for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
      memcpy(decbak,dec[0],decsize);
      if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();
      memcpy(decbak,dec[0],decsize);
      if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
      memcpy(decbak,dec[0],decsize);
      if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
      for(t=0;t<5*2;t++)
      {
         opus_int32 dur;
         out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
         if(out_samples!=expected[t])test_failed();
         if(t==0)dec_final_range2=dec_final_range1;
         else if(dec_final_range1!=dec_final_range2)test_failed();
         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
         if(dur!=out_samples)test_failed();
      }
   }
   fprintf(stdout,"  dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);

   plen=(fast_rand()%18+3)*8+skip+3;
   t=rand()&3;
   for(i=0;i<4096;i++)
   {
      int count,j,expected;
      packet[0]=modes[i]<<2;
      expected=opus_decoder_get_nb_samples(dec[t],packet,plen);
      for(count=0;count<10;count++)
      {
         for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
         out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
         if(out_samples!=expected)test_failed();
      }
   }
   fprintf(stdout,"  dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\n",t,plen+1);

   {
      int tmodes[1]={25<<2};
      opus_uint32 tseeds[1]={140441};
      int tlen[1]={157};
      opus_int32 tret[1]={480};
      t=fast_rand()&1;
      for(i=0;i<1;i++)
      {
         int j;
         packet[0]=tmodes[i];
         Rw=Rz=tseeds[i];
         for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255;
         out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0);
         if(out_samples!=tret[i])test_failed();
      }
      fprintf(stdout,"  dec[%3d] pre-selected random packets OK.\n",t);
   }

   free(decbak);
   for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
   printf("  Decoders stopped.\n");

   err=0;
   for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
   for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
   if(err)test_failed();

   free(outbuf_int);
   free(packet);
   return 0;
}
Example #8
0
/*
 * Open codec.
 */
static pj_status_t  codec_open( pjmedia_codec *codec,
				pjmedia_codec_param *attr )
{
    struct opus_data *opus_data = (struct opus_data *)codec->codec_data;
    int idx, err;

    PJ_ASSERT_RETURN(codec && attr && opus_data, PJ_EINVAL);

    pj_mutex_lock (opus_data->mutex);

    TRACE_((THIS_FILE, "%s:%d: - TRACE", __FUNCTION__, __LINE__));

    opus_data->cfg.sample_rate = attr->info.clock_rate;
    opus_data->cfg.channel_cnt = attr->info.channel_cnt;
    opus_data->ptime       = attr->info.frm_ptime;

    /* Allocate memory used by the codec */
    if (!opus_data->enc) {
	/* Allocate memory for max 2 channels */
	opus_data->enc = pj_pool_zalloc(opus_data->pool,
					opus_encoder_get_size(2));
    }
    if (!opus_data->dec) {
	/* Allocate memory for max 2 channels */
	opus_data->dec = pj_pool_zalloc(opus_data->pool,
					opus_decoder_get_size(2));
    }
    if (!opus_data->enc_packer) {
	opus_data->enc_packer = pj_pool_zalloc(opus_data->pool,
					       opus_repacketizer_get_size());
    }
    if (!opus_data->dec_packer) {
	opus_data->dec_packer = pj_pool_zalloc(opus_data->pool,
					       opus_repacketizer_get_size());
    }
    if (!opus_data->enc || !opus_data->dec ||
	!opus_data->enc_packer || !opus_data->dec_packer)
    {
	PJ_LOG(2, (THIS_FILE, "Unable to allocate memory for the codec"));
        pj_mutex_unlock (opus_data->mutex);
	return PJ_ENOMEM;
    }

    /* Check max average bit rate */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_MAX_BIT_RATE, PJ_FALSE);
    if (idx >= 0) {
	unsigned rate;
	rate = (unsigned)pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	if (rate < attr->info.avg_bps)
	    attr->info.avg_bps = rate;
    }

    /* Check plc */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_INBAND_FEC, PJ_FALSE);
    if (idx >= 0) {
	unsigned plc;
	plc = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	attr->setting.plc = plc > 0? PJ_TRUE: PJ_FALSE;
    }

    /* Check vad */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_DTX, PJ_FALSE);
    if (idx >= 0) {
	unsigned vad;
	vad = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	attr->setting.vad = vad > 0? PJ_TRUE: PJ_FALSE;
    }

    /* Check cbr */
    idx = find_fmtp(&attr->setting.enc_fmtp, &STR_CBR, PJ_FALSE);
    if (idx >= 0) {
	unsigned cbr;
	cbr = (unsigned) pj_strtoul(&attr->setting.enc_fmtp.param[idx].val);
	opus_data->cfg.cbr = cbr > 0? PJ_TRUE: PJ_FALSE;
    }
    
    /* Check max average bit rate */
    idx = find_fmtp(&attr->setting.dec_fmtp, &STR_MAX_BIT_RATE, PJ_FALSE);
    if (idx >= 0) {
	unsigned rate;
	rate = (unsigned) pj_strtoul(&attr->setting.dec_fmtp.param[idx].val);
	if (rate < attr->info.avg_bps)
	    attr->info.avg_bps = rate;
    }

    TRACE_((THIS_FILE, "%s:%d: sample_rate: %u",
	    __FUNCTION__, __LINE__, opus_data->cfg.sample_rate));

    /* Initialize encoder */
    err = opus_encoder_init(opus_data->enc,
			    opus_data->cfg.sample_rate,
			    attr->info.channel_cnt,
			    OPUS_APPLICATION_VOIP);
    if (err != OPUS_OK) {
	PJ_LOG(2, (THIS_FILE, "Unable to create encoder"));
	return PJMEDIA_CODEC_EFAILED;
    }
    
    /* Set signal type */
    opus_encoder_ctl(opus_data->enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
    /* Set bitrate */
    opus_encoder_ctl(opus_data->enc, OPUS_SET_BITRATE(attr->info.avg_bps));
    /* Set VAD */
    opus_encoder_ctl(opus_data->enc, OPUS_SET_DTX(attr->setting.vad ? 1 : 0));
    /* Set PLC */
    opus_encoder_ctl(opus_data->enc,
    		     OPUS_SET_INBAND_FEC(attr->setting.plc ? 1 : 0));
    /* Set bandwidth */
    opus_encoder_ctl(opus_data->enc,
    		     OPUS_SET_MAX_BANDWIDTH(get_opus_bw_constant(
    					    opus_data->cfg.sample_rate)));
    /* Set expected packet loss */
    opus_encoder_ctl(opus_data->enc,
    		OPUS_SET_PACKET_LOSS_PERC(opus_data->cfg.packet_loss));
    /* Set complexity */
    opus_encoder_ctl(opus_data->enc,
		     OPUS_SET_COMPLEXITY(opus_data->cfg.complexity));
    /* Set constant bit rate */
    opus_encoder_ctl(opus_data->enc,
    		     OPUS_SET_VBR(opus_data->cfg.cbr ? 0 : 1));

    PJ_LOG(5, (THIS_FILE, "Initialize Opus encoder, sample rate: %d, "
    			  "avg bitrate: %d, vad: %d, plc: %d, pkt loss: %d, "
    			  "complexity: %d, constant bit rate: %d",
               		  opus_data->cfg.sample_rate,
               		  attr->info.avg_bps, attr->setting.vad?1:0,
               		  attr->setting.plc?1:0,
               		  opus_data->cfg.packet_loss,
               		  opus_data->cfg.complexity,
               		  opus_data->cfg.cbr?1:0));

    /* Initialize decoder */
    err = opus_decoder_init (opus_data->dec,
			     opus_data->cfg.sample_rate,
			     attr->info.channel_cnt);
    if (err != OPUS_OK) {
	PJ_LOG(2, (THIS_FILE, "Unable to initialize decoder"));
	return PJMEDIA_CODEC_EFAILED;
    }

    /* Initialize temporary decode frames used for FEC */
    opus_data->dec_frame[0].type = PJMEDIA_FRAME_TYPE_NONE;
    opus_data->dec_frame[0].buf  = pj_pool_zalloc(opus_data->pool,                                   
        	(opus_data->cfg.sample_rate / 1000)
                * 60 * attr->info.channel_cnt * 2 /* bytes per sample */);
    opus_data->dec_frame[1].type = PJMEDIA_FRAME_TYPE_NONE;
    opus_data->dec_frame[1].buf  = pj_pool_zalloc(opus_data->pool,
		(opus_data->cfg.sample_rate / 1000)
                * 60 * attr->info.channel_cnt * 2 /* bytes per sample */);
    opus_data->dec_frame_index = -1;

    /* Initialize the repacketizers */
    opus_repacketizer_init(opus_data->enc_packer);
    opus_repacketizer_init(opus_data->dec_packer);

    pj_mutex_unlock (opus_data->mutex);
    return PJ_SUCCESS;
}
Example #9
0
/*
 * Open codec.
 */
static pj_status_t opus_codec_open(pjmedia_codec *codec,
                                   pjmedia_codec_param *attr) {
  pj_status_t status;
  struct opus_private *opus;
  int id, ret = 0;
  unsigned i;
  int structSizeBytes;
  int tmpFmtpVal = 0;
  unsigned max_nsamples;
  const pj_str_t STR_FMTP_USE_INBAND_FEC = {"useinbandfec", 12};
  const pj_str_t STR_FMTP_MAX_AVERAGE_BITRATE = {"maxaveragebitrate", 17};
  const pj_str_t STR_FMTP_MAX_CODED_AUDIO_BANDWIDTH = {"maxplaybackrate", 15};
  const pj_str_t STR_FMTP_USE_DTX = {"usedtx", 6};

  opus = (struct opus_private *)codec->codec_data;

  pj_assert(opus != NULL);
  pj_assert(opus->enc_ready == PJ_FALSE && opus->dec_ready == PJ_FALSE);

  PJ_LOG(4, (THIS_FILE, "Clock rate is %d ", attr->info.clock_rate));
  opus->externalFs = attr->info.clock_rate;

  /* Create Encoder */
  structSizeBytes = opus_encoder_get_size(attr->info.channel_cnt);
  opus->psEnc = pj_pool_zalloc(opus->pool, structSizeBytes);
  ret = opus_encoder_init(opus->psEnc, opus->externalFs, attr->info.channel_cnt,
                          OPUS_APPLICATION_VOIP);
  if (ret) {
    PJ_LOG(1, (THIS_FILE, "Unable to init encoder : %d", ret));
    return PJ_EINVAL;
  }

  /*
   * Set Encoder parameters
   * TODO : have it configurable
   */
  opus_encoder_ctl(opus->psEnc, OPUS_SET_COMPLEXITY(2));
  opus_encoder_ctl(opus->psEnc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));

  /* Apply fmtp params to Encoder */
  for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
    if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name,
                   &STR_FMTP_USE_INBAND_FEC) == 0) {
      tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));
      opus_encoder_ctl(opus->psEnc, OPUS_SET_INBAND_FEC(tmpFmtpVal));
      break;
    } else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name,
                          &STR_FMTP_MAX_AVERAGE_BITRATE) == 0) {
      tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));
      if (tmpFmtpVal >= 6000 && tmpFmtpVal <= 510000) {
        opus_encoder_ctl(opus->psEnc, OPUS_SET_BITRATE(tmpFmtpVal));
      }
    } else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name,
                          &STR_FMTP_MAX_CODED_AUDIO_BANDWIDTH) == 0) {
      tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));
      if (tmpFmtpVal <= 8000) {
        opus_encoder_ctl(opus->psEnc,
                         OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
      } else if (tmpFmtpVal <= 12000) {
        opus_encoder_ctl(opus->psEnc,
                         OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND));
      } else if (tmpFmtpVal <= 16000) {
        opus_encoder_ctl(opus->psEnc,
                         OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
      } else if (tmpFmtpVal <= 24000) {
        opus_encoder_ctl(opus->psEnc,
                         OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
      } else if (tmpFmtpVal <= 48000) {
        opus_encoder_ctl(opus->psEnc,
                         OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
      }
    } else if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name,
                          &STR_FMTP_USE_DTX) == 0) {
      tmpFmtpVal = (int)(pj_strtoul(&attr->setting.enc_fmtp.param[i].val));
      opus_encoder_ctl(opus->psEnc, OPUS_SET_DTX(tmpFmtpVal));
    }
  }

  opus->enc_ready = PJ_TRUE;

  /* Decoder buffer */
  opus->pcm_bytes_per_sample = attr->info.pcm_bits_per_sample / 8;
  max_nsamples = 120 * OPUS_CLOCK_RATE / 1000; /* 120ms is max frame time */
  opus->dec_buf_max_size = max_nsamples * opus->pcm_bytes_per_sample;
  opus->dec_buf = pj_pool_alloc(opus->pool, opus->dec_buf_max_size);

  /* Create decoder */
  structSizeBytes = opus_decoder_get_size(attr->info.channel_cnt);
  opus->psDec = pj_pool_zalloc(opus->pool, structSizeBytes);
  ret =
      opus_decoder_init(opus->psDec, opus->externalFs, attr->info.channel_cnt);
  if (ret) {
    PJ_LOG(1, (THIS_FILE, "Unable to init decoder : %d", ret));
    return PJ_EINVAL;
  }

  opus->dec_ready = PJ_TRUE;

  return PJ_SUCCESS;
}
int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
{
   va_list ap;
   int coupled_size, mono_size;
   char *ptr;
   int ret = OPUS_OK;

   va_start(ap, request);

   coupled_size = opus_decoder_get_size(2);
   mono_size = opus_decoder_get_size(1);
   ptr = (char*)st + align(sizeof(OpusMSDecoder));
   switch (request)
   {
       case OPUS_GET_BANDWIDTH_REQUEST:
       case OPUS_GET_SAMPLE_RATE_REQUEST:
       case OPUS_GET_GAIN_REQUEST:
       case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
       {
          OpusDecoder *dec;
          /* For int32* GET params, just query the first stream */
          opus_int32 *value = va_arg(ap, opus_int32*);
          dec = (OpusDecoder*)ptr;
          ret = opus_decoder_ctl(dec, request, value);
       }
       break;
       case OPUS_GET_FINAL_RANGE_REQUEST:
       {
          int s;
          opus_uint32 *value = va_arg(ap, opus_uint32*);
          opus_uint32 tmp;
          *value = 0;
          for (s=0;s<st->layout.nb_streams;s++)
          {
             OpusDecoder *dec;
             dec = (OpusDecoder*)ptr;
             if (s < st->layout.nb_coupled_streams)
                ptr += align(coupled_size);
             else
                ptr += align(mono_size);
             ret = opus_decoder_ctl(dec, request, &tmp);
             if (ret != OPUS_OK) break;
             *value ^= tmp;
          }
       }
       break;
       case OPUS_RESET_STATE:
       {
          int s;
          for (s=0;s<st->layout.nb_streams;s++)
          {
             OpusDecoder *dec;

             dec = (OpusDecoder*)ptr;
             if (s < st->layout.nb_coupled_streams)
                ptr += align(coupled_size);
             else
                ptr += align(mono_size);
             ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
             if (ret != OPUS_OK)
                break;
          }
       }
       break;
       case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
       {
          int s;
          opus_int32 stream_id;
          OpusDecoder **value;
          stream_id = va_arg(ap, opus_int32);
          if (stream_id<0 || stream_id >= st->layout.nb_streams)
             ret = OPUS_BAD_ARG;
          value = va_arg(ap, OpusDecoder**);
          for (s=0;s<stream_id;s++)
          {
             if (s < st->layout.nb_coupled_streams)
                ptr += align(coupled_size);
             else
                ptr += align(mono_size);
          }
          *value = (OpusDecoder*)ptr;
       }
       break;
       case OPUS_SET_GAIN_REQUEST:
       {
          int s;
          /* This works for int32 params */
          opus_int32 value = va_arg(ap, opus_int32);
          for (s=0;s<st->layout.nb_streams;s++)
          {
             OpusDecoder *dec;

             dec = (OpusDecoder*)ptr;
             if (s < st->layout.nb_coupled_streams)
                ptr += align(coupled_size);
             else
                ptr += align(mono_size);
             ret = opus_decoder_ctl(dec, request, value);
             if (ret != OPUS_OK)
                break;
          }
       }
       break;
       default:
          ret = OPUS_UNIMPLEMENTED;
       break;
   }

   va_end(ap);
   return ret;
}
static int opus_multistream_decode_native(
      OpusMSDecoder *st,
      const unsigned char *data,
      opus_int32 len,
      void *pcm,
      opus_copy_channel_out_func copy_channel_out,
      int frame_size,
      int decode_fec,
      int soft_clip
)
{
   opus_int32 Fs;
   int coupled_size;
   int mono_size;
   int s, c;
   char *ptr;
   int do_plc=0;
   VARDECL(opus_val16, buf);
   ALLOC_STACK;

   /* Limit frame_size to avoid excessive stack allocations. */
   opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
   frame_size = IMIN(frame_size, Fs/25*3);
   ALLOC(buf, 2*frame_size, opus_val16);
   ptr = (char*)st + align(sizeof(OpusMSDecoder));
   coupled_size = opus_decoder_get_size(2);
   mono_size = opus_decoder_get_size(1);

   if (len==0)
      do_plc = 1;
   if (len < 0)
      return OPUS_BAD_ARG;
   if (!do_plc && len < 2*st->layout.nb_streams-1)
      return OPUS_INVALID_PACKET;
   for (s=0;s<st->layout.nb_streams;s++)
   {
      OpusDecoder *dec;
      int packet_offset, ret;

      dec = (OpusDecoder*)ptr;
      ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);

      if (!do_plc && len<=0)
      {
         RESTORE_STACK;
         return OPUS_INVALID_PACKET;
      }
      packet_offset = 0;
      ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);
      data += packet_offset;
      len -= packet_offset;
      if (ret > frame_size)
      {
         RESTORE_STACK;
         return OPUS_BUFFER_TOO_SMALL;
      }
      if (s>0 && ret != frame_size)
      {
         RESTORE_STACK;
         return OPUS_INVALID_PACKET;
      }
      if (ret <= 0)
      {
         RESTORE_STACK;
         return ret;
      }
      frame_size = ret;
      if (s < st->layout.nb_coupled_streams)
      {
         int chan, prev;
         prev = -1;
         /* Copy "left" audio to the channel(s) where it belongs */
         while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
         {
            (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
               buf, 2, frame_size);
            prev = chan;
         }
         prev = -1;
         /* Copy "right" audio to the channel(s) where it belongs */
         while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
         {
            (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
               buf+1, 2, frame_size);
            prev = chan;
         }
      } else {
         int chan, prev;
         prev = -1;
         /* Copy audio to the channel(s) where it belongs */
         while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
         {
            (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
               buf, 1, frame_size);
            prev = chan;
         }
      }
   }
   /* Handle muted channels */
   for (c=0;c<st->layout.nb_channels;c++)
   {
      if (st->layout.mapping[c] == 255)
      {
         (*copy_channel_out)(pcm, st->layout.nb_channels, c,
            NULL, 0, frame_size);
      }
   }
   RESTORE_STACK;
   return frame_size;
}
Example #12
0
static int opus_multistream_decode_native(
      OpusMSDecoder *st,
      const unsigned char *data,
      opus_int32 len,
      opus_val16 *pcm,
      int frame_size,
      int decode_fec
)
{
   int coupled_size;
   int mono_size;
   int s, i, c;
   char *ptr;
   int do_plc=0;
   VARDECL(opus_val16, buf);
   ALLOC_STACK;

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

   if (len==0)
      do_plc = 1;
   if (len < 0)
      return OPUS_BAD_ARG;
   if (!do_plc && len < 2*st->layout.nb_streams-1)
      return OPUS_INVALID_PACKET;
   for (s=0;s<st->layout.nb_streams;s++)
   {
      OpusDecoder *dec;
      int packet_offset, ret;

      dec = (OpusDecoder*)ptr;
      ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);

      if (!do_plc && len<=0)
      {
         RESTORE_STACK;
         return OPUS_INVALID_PACKET;
      }
      packet_offset = 0;
      ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset);
      data += packet_offset;
      len -= packet_offset;
      if (ret > frame_size)
      {
         RESTORE_STACK;
         return OPUS_BUFFER_TOO_SMALL;
      }
      if (s>0 && ret != frame_size)
      {
         RESTORE_STACK;
         return OPUS_INVALID_PACKET;
      }
      if (ret <= 0)
      {
         RESTORE_STACK;
         return ret;
      }
      frame_size = ret;
      if (s < st->layout.nb_coupled_streams)
      {
         int chan, prev;
         prev = -1;
         /* Copy "left" audio to the channel(s) where it belongs */
         while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
         {
            for (i=0;i<frame_size;i++)
               pcm[st->layout.nb_channels*i+chan] = buf[2*i];
            prev = chan;
         }
         prev = -1;
         /* Copy "right" audio to the channel(s) where it belongs */
         while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
         {
            for (i=0;i<frame_size;i++)
               pcm[st->layout.nb_channels*i+chan] = buf[2*i+1];
            prev = chan;
         }
      } else {
         int chan, prev;
         prev = -1;
         /* Copy audio to the channel(s) where it belongs */
         while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
         {
            for (i=0;i<frame_size;i++)
               pcm[st->layout.nb_channels*i+chan] = buf[i];
            prev = chan;
         }
      }
   }
   /* Handle muted channels */
   for (c=0;c<st->layout.nb_channels;c++)
   {
      if (st->layout.mapping[c] == 255)
      {
         for (i=0;i<frame_size;i++)
            pcm[st->layout.nb_channels*i+c] = 0;
      }
   }
   RESTORE_STACK;
   return frame_size;
}
JNIEXPORT jint JNICALL
Java_org_jitsi_impl_neomedia_codec_audio_opus_Opus_decoder_1get_1size
    (JNIEnv *env, jclass clazz, jint channels)
{
    return opus_decoder_get_size(channels);
}