Remove useless code in alloc_trim_analysis()
[opus.git] / src / opus_multistream_decoder.c
index ebec6a7..a05fa1e 100644 (file)
@@ -152,6 +152,35 @@ typedef void (*opus_copy_channel_out_func)(
   int frame_size
 );
 
+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;
+}
+
 static int opus_multistream_decode_native(
       OpusMSDecoder *st,
       const unsigned char *data,
@@ -183,9 +212,28 @@ static int opus_multistream_decode_native(
    if (len==0)
       do_plc = 1;
    if (len < 0)
+   {
+      RESTORE_STACK;
       return OPUS_BAD_ARG;
+   }
    if (!do_plc && len < 2*st->layout.nb_streams-1)
+   {
+      RESTORE_STACK;
       return OPUS_INVALID_PACKET;
+   }
+   if (!do_plc)
+   {
+      int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs);
+      if (ret < 0)
+      {
+         RESTORE_STACK;
+         return ret;
+      } else if (ret > frame_size)
+      {
+         RESTORE_STACK;
+         return OPUS_BUFFER_TOO_SMALL;
+      }
+   }
    for (s=0;s<st->layout.nb_streams;s++)
    {
       OpusDecoder *dec;
@@ -197,22 +245,12 @@ static int opus_multistream_decode_native(
       if (!do_plc && len<=0)
       {
          RESTORE_STACK;
-         return OPUS_INVALID_PACKET;
+         return OPUS_INTERNAL_ERROR;
       }
       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;
@@ -400,7 +438,8 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
           int s;
           opus_uint32 *value = va_arg(ap, opus_uint32*);
           opus_uint32 tmp;
-          if (!value) {
+          if (!value)
+          {
              goto bad_arg;
           }
           *value = 0;
@@ -445,7 +484,8 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
           if (stream_id<0 || stream_id >= st->layout.nb_streams)
              ret = OPUS_BAD_ARG;
           value = va_arg(ap, OpusDecoder**);
-          if (!value) {
+          if (!value)
+          {
              goto bad_arg;
           }
           for (s=0;s<stream_id;s++)