shithub: opus

Download patch

ref: e8dbcb8f087c8e5568fb3942a86d09c35749ad95
parent: 369553f15163a517b401730c48d2b93bb1c84540
author: Jean-Marc Valin <[email protected]>
date: Wed Aug 10 05:47:30 EDT 2011

Adds a test_repacketizer tool and fixes a few of the bugs in the repacketizer

Still more bugs to find

--- a/Makefile.am
+++ b/Makefile.am
@@ -26,8 +26,12 @@
 
 noinst_HEADERS = $(OPUS_HEAD) $(SILK_HEAD) $(CELT_HEAD)
 
-noinst_PROGRAMS = test_opus
+noinst_PROGRAMS = test_opus test_repacketizer
 
 test_opus_SOURCES = src/test_opus.c
 
 test_opus_LDADD = libopus.la -lm
+
+test_repacketizer_SOURCES = src/test_repacketizer.c
+
+test_repacketizer_LDADD = libopus.la -lm
--- a/src/opus.h
+++ b/src/opus.h
@@ -250,6 +250,8 @@
 
 OPUS_EXPORT int opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, int maxlen);
 
+OPUS_EXPORT int opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, int maxlen);
+
 #ifdef __cplusplus
 }
 #endif
--- a/src/repacketizer.c
+++ b/src/repacketizer.c
@@ -29,7 +29,7 @@
 #include "config.h"
 #endif
 
-
+#include <stdio.h>
 #include "string.h"
 #include "opus.h"
 
@@ -80,16 +80,22 @@
       rp->toc = data[0];
       rp->framesize = opus_packet_get_samples_per_frame(data, 48000);
    } else if (rp->toc != data[0])
-      return 0;
-
+   {
+      /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/
+      return OPUS_CORRUPTED_DATA;
+   }
    curr_nb_frames = opus_packet_get_nb_frames(data, len);
+
    /* Check the 120 ms maximum packet size */
    if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 5760)
-      return 0;
+   {
+      return OPUS_CORRUPTED_DATA;
+   }
 
    opus_packet_parse(data, len, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL);
 
-   return 1;
+   rp->nb_frames += curr_nb_frames;
+   return OPUS_OK;
 }
 
 int opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, int maxlen)
@@ -96,9 +102,11 @@
 {
    int i, count, tot_size;
 
-   if (begin<0 || begin>=end || end>=rp->nb_frames)
+   if (begin<0 || begin>=end || end>rp->nb_frames)
+   {
+      /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/
       return OPUS_BAD_ARG;
-
+   }
    count = end-begin;
 
    switch (count)
--- /dev/null
+++ b/src/test_repacketizer.c
@@ -1,0 +1,102 @@
+
+
+#include "opus.h"
+#include <stdio.h>
+
+#define MAX_PACKETOUT 32000
+
+void usage(char *argv0)
+{
+   fprintf(stderr, "usage: %s [options] input_file output_file\n", argv0);
+}
+
+static void int_to_char(opus_uint32 i, unsigned char ch[4])
+{
+    ch[0] = i>>24;
+    ch[1] = (i>>16)&0xFF;
+    ch[2] = (i>>8)&0xFF;
+    ch[3] = i&0xFF;
+}
+
+static opus_uint32 char_to_int(unsigned char ch[4])
+{
+    return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
+         | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
+}
+
+int main(int argc, char *argv[])
+{
+   int eof=0;
+   FILE *fin, *fout;
+   unsigned char packets[48][1500];
+   int len[48];
+   int rng[48];
+   OpusRepacketizer *rp;
+   unsigned char output_packet[MAX_PACKETOUT];
+
+   if (argc < 3)
+   {
+      usage(argv[0]);
+      return 1;
+   }
+   fin = fopen(argv[argc-2], "r");
+   fout = fopen(argv[argc-1], "w");
+
+   rp = opus_repacketizer_create();
+   while (!eof)
+   {
+      int i, err;
+      int nb_packets=2;
+      opus_repacketizer_init(rp);
+      for (i=0;i<nb_packets;i++)
+      {
+         unsigned char ch[4];
+         err = fread(ch, 1, 4, fin);
+         len[i] = char_to_int(ch);
+         /*fprintf(stderr, "in len = %d\n", len[i]);*/
+         if (len[i]>1500 || len[i]<0)
+         {
+             if (feof(fin))
+                eof = 1;
+             else
+                fprintf(stderr, "Invalid payload length\n");
+             break;
+         }
+         err = fread(ch, 1, 4, fin);
+         rng[i] = char_to_int(ch);
+         err = fread(packets[i], 1, len[i], fin);
+         if (feof(fin))
+         {
+            eof = 1;
+            break;
+         }
+         err = opus_repacketizer_cat(rp, packets[i], len[i]);
+         if (err!=OPUS_OK)
+         {
+            fprintf(stderr, "opus_repacketizer_cat() failed: %s\n", opus_strerror(err));
+            break;
+         }
+      }
+      nb_packets = i;
+
+      if (eof)
+         break;
+      err = opus_repacketizer_out(rp, output_packet, MAX_PACKETOUT);
+      if (err>0) {
+          unsigned char int_field[4];
+          int_to_char(err, int_field);
+          fwrite(int_field, 1, 4, fout);
+          int_to_char(rng[nb_packets-1], int_field);
+          fwrite(int_field, 1, 4, fout);
+          fwrite(output_packet, 1, err, fout);
+          /*fprintf(stderr, "out len = %d\n", err);*/
+      } else {
+         fprintf(stderr, "opus_repacketizer_out() failed: %s\n", opus_strerror(err));
+      }
+
+   }
+
+   fclose(fin);
+   fclose(fout);
+   return 0;
+}