From e8dbcb8f087c8e5568fb3942a86d09c35749ad95 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Wed, 10 Aug 2011 09:47:30 -0400 Subject: [PATCH] Adds a test_repacketizer tool and fixes a few of the bugs in the repacketizer Still more bugs to find --- Makefile.am | 6 ++- src/opus.h | 2 + src/repacketizer.c | 22 ++++++--- src/test_repacketizer.c | 102 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 src/test_repacketizer.c diff --git a/Makefile.am b/Makefile.am index cacb74f8..57fd64c0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,8 +26,12 @@ pkginclude_HEADERS = src/opus.h 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 diff --git a/src/opus.h b/src/opus.h index 5af483fc..7dd1da98 100644 --- a/src/opus.h +++ b/src/opus.h @@ -250,6 +250,8 @@ OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char 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 diff --git a/src/repacketizer.c b/src/repacketizer.c index 083f5cb1..fb99dc19 100644 --- a/src/repacketizer.c +++ b/src/repacketizer.c @@ -29,7 +29,7 @@ #include "config.h" #endif - +#include #include "string.h" #include "opus.h" @@ -80,25 +80,33 @@ int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, int l 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) { 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) diff --git a/src/test_repacketizer.c b/src/test_repacketizer.c new file mode 100644 index 00000000..bda9716b --- /dev/null +++ b/src/test_repacketizer.c @@ -0,0 +1,102 @@ + + +#include "opus.h" +#include + +#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;i1500 || 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; +}