Exemple #1
0
static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited)
{
   unsigned char tmp_toc;
   int curr_nb_frames,ret;
   /* Set of check ToC */
   if (len<1) return OPUS_INVALID_PACKET;
   if (rp->nb_frames == 0)
   {
      rp->toc = data[0];
      rp->framesize = opus_packet_get_samples_per_frame(data, 8000);
   } else if ((rp->toc&0xFC) != (data[0]&0xFC))
   {
      /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/
      return OPUS_INVALID_PACKET;
   }
   curr_nb_frames = opus_packet_get_nb_frames(data, len);
   if(curr_nb_frames<1) return OPUS_INVALID_PACKET;

   /* Check the 120 ms maximum packet size */
   if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960)
   {
      return OPUS_INVALID_PACKET;
   }

   ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL);
   if(ret<1)return ret;

   rp->nb_frames += curr_nb_frames;
   return OPUS_OK;
}
Exemple #2
0
int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams)
{
   int s;
   int count;
   unsigned char toc;
   opus_int16 size[48];
   opus_int32 packet_offset;
   opus_int32 amount;

   if (len < 1)
      return OPUS_BAD_ARG;
   if (len==new_len)
      return OPUS_OK;
   else if (len > new_len)
      return OPUS_BAD_ARG;
   amount = new_len - len;
   /* Seek to last stream */
   for (s=0;s<nb_streams-1;s++)
   {
      if (len<=0)
         return OPUS_INVALID_PACKET;
      count = opus_packet_parse_impl(data, len, 1, &toc, NULL,
                                     size, NULL, &packet_offset);
      if (count<0)
         return count;
      data += packet_offset;
      len -= packet_offset;
   }
   return opus_packet_pad(data, len, len+amount);
}
Exemple #3
0
int opus_packet_parse(const unsigned char *data, opus_int32 len,
      unsigned char *out_toc, const unsigned char *frames[48],
      opus_int16 size[48], int *payload_offset)
{
   return opus_packet_parse_impl(data, len, 0, out_toc,
                                 frames, size, payload_offset);
}
static int opus_multistream_packet_validate(const unsigned char *data,
      opus_int32 len, int nb_streams, opus_int32 Fs)
{
   int s;
   int count;
   unsigned char toc;
   opus_int16 size[48];
   int samples=0;
   opus_int32 packet_offset;

   for (s=0;s<nb_streams;s++)
   {
      int tmp_samples;
      if (len<=0)
         return OPUS_INVALID_PACKET;
      count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL,
                                     size, NULL, &packet_offset);
      if (count<0)
         return count;
      tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs);
      if (s!=0 && samples != tmp_samples)
         return OPUS_INVALID_PACKET;
      samples = tmp_samples;
      data += packet_offset;
      len -= packet_offset;
   }
   return samples;
}
void save_range(FILE *frange, int frame_size, unsigned char *packet, int nbBytes, opus_uint32 *rngs, int nb_streams){
  int i, parsed_size;
  const unsigned char *subpkt;
  static const char *bw_strings[5]={"NB","MB","WB","SWB","FB"};
  static const char *mode_strings[3]={"LP","HYB","MDCT"};
  fprintf(frange,"%d, %d, ",frame_size,nbBytes);
  subpkt=packet;
  parsed_size=nbBytes;
  for(i=0;i<nb_streams;i++){
    int j,payload_offset,nf;
    const unsigned char *frames[48];
    unsigned char toc;
    short size[48];
    payload_offset=0;
    nf=opus_packet_parse_impl(subpkt,parsed_size,i+1!=nb_streams,
      &toc,frames,size,&payload_offset);
    fprintf(frange,"[[%d",(int)(frames[0]-subpkt));
    for(j=0;j<nf;j++)fprintf(frange,", %d",size[j]);
    fprintf(frange,"], %s, %s, %c, %d",
       mode_strings[((((subpkt[0]>>3)+48)&92)+4)>>5],
       bw_strings[opus_packet_get_bandwidth(subpkt)-OPUS_BANDWIDTH_NARROWBAND],
       subpkt[0]&4?'S':'M',opus_packet_get_samples_per_frame(subpkt,48000));
    fprintf(frange,", %" I64uFORMAT "]%s",(unsigned long long)rngs[i],i+1==nb_streams?"\n":", ");
    parsed_size-=payload_offset;
    subpkt+=payload_offset;
  }
}
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;
}
Exemple #7
0
opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams)
{
   int s;
   unsigned char toc;
   opus_int16 size[48];
   opus_int32 packet_offset;
   OpusRepacketizer rp;
   unsigned char *dst;
   opus_int32 dst_len;

   if (len < 1)
      return OPUS_BAD_ARG;
   dst = data;
   dst_len = 0;
   /* Unpad all frames */
   for (s=0;s<nb_streams;s++)
   {
      opus_int32 ret;
      int self_delimited = s!=nb_streams-1;
      if (len<=0)
         return OPUS_INVALID_PACKET;
      opus_repacketizer_init(&rp);
      ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
                                     size, NULL, &packet_offset);
      if (ret<0)
         return ret;
      ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited);
      if (ret < 0)
         return ret;
      ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, self_delimited, 0);
      if (ret < 0)
         return ret;
      else
         dst_len += ret;
      dst += ret;
      data += packet_offset;
      len -= packet_offset;
   }
   return dst_len;
}
Exemple #8
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;
}
Exemple #9
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;
}