Example #1
0
int opus_decode_native(OpusDecoder *st, const unsigned char *data,
      int len, opus_val16 *pcm, int frame_size, int decode_fec,
      int self_delimited, int *packet_offset)
{
   int i, nb_samples;
   int count, offset;
   unsigned char toc;
   int tot_offset;
   /* 48 x 2.5 ms = 120 ms */
   short size[48];
   if (decode_fec<0 || decode_fec>1)
      return OPUS_BAD_ARG;
   if (len==0 || data==NULL)
      return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
   else if (len<0)
      return OPUS_BAD_ARG;

   tot_offset = 0;
   st->mode = opus_packet_get_mode(data);
   st->bandwidth = opus_packet_get_bandwidth(data);
   st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
   st->stream_channels = opus_packet_get_nb_channels(data);

   count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset);
   if (count < 0)
      return count;

   data += offset;
   tot_offset += offset;

   if (count*st->frame_size > frame_size)
      return OPUS_BUFFER_TOO_SMALL;
   nb_samples=0;
   for (i=0;i<count;i++)
   {
      int ret;
      ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec);
      if (ret<0)
         return ret;
      data += size[i];
      tot_offset += size[i];
      pcm += ret*st->channels;
      nb_samples += ret;
   }
   if (packet_offset != NULL)
      *packet_offset = tot_offset;
   return nb_samples;
}
Example #2
0
int opus_decode_native(OpusDecoder *st, const unsigned char *data,
                       opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
                       int self_delimited, opus_int32 *packet_offset, int soft_clip)
{
    int i, nb_samples;
    int count, offset;
    unsigned char toc;
    int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
    /* 48 x 2.5 ms = 120 ms */
    opus_int16 size[48];
    if (decode_fec<0 || decode_fec>1)
        return OPUS_BAD_ARG;
    /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
    if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
        return OPUS_BAD_ARG;
    if (len==0 || data==NULL)
    {
        int pcm_count=0;
        do {
            int ret;
            ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0);
            if (ret<0)
                return ret;
            pcm_count += ret;
        } while (pcm_count < frame_size);
        celt_assert(pcm_count == frame_size);
        if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels))
            OPUS_PRINT_INT(pcm_count);
        st->last_packet_duration = pcm_count;
        return pcm_count;
    } else if (len<0)
        return OPUS_BAD_ARG;

    packet_mode = opus_packet_get_mode(data);
    packet_bandwidth = opus_packet_get_bandwidth(data);
    packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
    packet_stream_channels = opus_packet_get_nb_channels(data);

    count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
                                   size, &offset, packet_offset);
    if (count<0)
        return count;

    data += offset;

    if (decode_fec)
    {
        int duration_copy;
        int ret;
        /* If no FEC can be present, run the PLC (recursive call) */
        if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)
            return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip);
        /* Otherwise, run the PLC on everything except the size for which we might have FEC */
        duration_copy = st->last_packet_duration;
        if (frame_size-packet_frame_size!=0)
        {
            ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip);
            if (ret<0)
            {
                st->last_packet_duration = duration_copy;
                return ret;
            }
            celt_assert(ret==frame_size-packet_frame_size);
        }
        /* Complete with FEC */
        st->mode = packet_mode;
        st->bandwidth = packet_bandwidth;
        st->frame_size = packet_frame_size;
        st->stream_channels = packet_stream_channels;
        ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),
                                packet_frame_size, 1);
        if (ret<0)
            return ret;
        else {
            if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels))
                OPUS_PRINT_INT(frame_size);
            st->last_packet_duration = frame_size;
            return frame_size;
        }
    }

    if (count*packet_frame_size > frame_size)
        return OPUS_BUFFER_TOO_SMALL;

    /* Update the state as the last step to avoid updating it on an invalid packet */
    st->mode = packet_mode;
    st->bandwidth = packet_bandwidth;
    st->frame_size = packet_frame_size;
    st->stream_channels = packet_stream_channels;

    nb_samples=0;
    for (i=0; i<count; i++)
    {
        int ret;
        ret = opus_decode_frame(st, data, size[i], pcm+nb_samples*st->channels, frame_size-nb_samples, 0);
        if (ret<0)
            return ret;
        celt_assert(ret==packet_frame_size);
        data += size[i];
        nb_samples += ret;
    }
    st->last_packet_duration = nb_samples;
    if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels))
        OPUS_PRINT_INT(nb_samples);
#ifndef FIXED_POINT
    if (soft_clip)
        opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem);
    else
        st->softclip_mem[0]=st->softclip_mem[1]=0;
#endif
    return nb_samples;
}
Example #3
0
int opus_decode_native(OpusDecoder *st, const unsigned char *data,
      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
      int self_delimited, int *packet_offset)
{
   int i, nb_samples;
   int count, offset;
   unsigned char toc;
   int tot_offset;
   int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
   /* 48 x 2.5 ms = 120 ms */
   short size[48];
   if (decode_fec<0 || decode_fec>1)
      return OPUS_BAD_ARG;
   /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
   if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
      return OPUS_BAD_ARG;
   if (len==0 || data==NULL)
   {
      int pcm_count=0;
      do {
         int ret;
         ret = opus_decode_frame(st, NULL, 0, pcm, frame_size-pcm_count, 0);
         if (ret<0)
            return ret;
         pcm += st->channels*ret;
         pcm_count += ret;
      } while (pcm_count < frame_size);
      st->last_packet_duration = pcm_count;
      return pcm_count;
   } else if (len<0)
      return OPUS_BAD_ARG;

   packet_mode = opus_packet_get_mode(data);
   packet_bandwidth = opus_packet_get_bandwidth(data);
   packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
   packet_stream_channels = opus_packet_get_nb_channels(data);

   count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset);

   data += offset;

   if (decode_fec)
   {
      int duration_copy;
      int ret;
      /* If no FEC can be present, run the PLC (recursive call) */
      if (frame_size <= packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)
         return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL);
      /* Otherwise, run the PLC on everything except the size for which we might have FEC */
      duration_copy = st->last_packet_duration;
      ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL);
      if (ret<0)
      {
         st->last_packet_duration = duration_copy;
         return ret;
      }
      /* Complete with FEC */
      st->mode = packet_mode;
      st->bandwidth = packet_bandwidth;
      st->frame_size = packet_frame_size;
      st->stream_channels = packet_stream_channels;
      ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),
            packet_frame_size, 1);
      if (ret<0)
         return ret;
      st->last_packet_duration = frame_size;
      return frame_size;
   }
   tot_offset = 0;
   if (count < 0)
      return count;

   tot_offset += offset;

   if (count*packet_frame_size > frame_size)
      return OPUS_BUFFER_TOO_SMALL;

   /* Update the state as the last step to avoid updating it on an invalid packet */
   st->mode = packet_mode;
   st->bandwidth = packet_bandwidth;
   st->frame_size = packet_frame_size;
   st->stream_channels = packet_stream_channels;

   nb_samples=0;
   for (i=0;i<count;i++)
   {
      int ret;
      ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec);
      if (ret<0)
         return ret;
      data += size[i];
      tot_offset += size[i];
      pcm += ret*st->channels;
      nb_samples += ret;
   }
   if (packet_offset != NULL)
      *packet_offset = tot_offset;
   st->last_packet_duration = nb_samples;
   return nb_samples;
}