mirror of
https://github.com/xiph/opus.git
synced 2025-05-14 15:38:32 +00:00
Fixup extensions implementation and add unit tests
Add unit tests for opus_packet_extensions_count, opus_packet_extensions_parse, and opus_packet_extensions_generate. Add various assertions for NULL buffers or negative length arguments. Add explicit check for invalid length in opus_packet_extensions_count. Check for extension id >127 in opus_packet_extensions_generate. Check for invalid length input in opus_packet_extensions_generate. Signed-off-by: Jean-Marc Valin <jmvalin@amazon.com>
This commit is contained in:
parent
df2f98f809
commit
4b9c620a8d
13 changed files with 383 additions and 8 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -49,6 +49,7 @@ tests/*test
|
|||
tests/test_opus_api
|
||||
tests/test_opus_decode
|
||||
tests/test_opus_encode
|
||||
tests/test_opus_extensions
|
||||
tests/test_opus_padding
|
||||
tests/test_opus_projection
|
||||
celt/arm/armopts.s
|
||||
|
|
|
@ -81,6 +81,7 @@ cmake:
|
|||
apt-get install -y cmake ninja-build git
|
||||
- !reference [.snippets, git_prep]
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- mkdir build
|
||||
- cmake -S . -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_TESTING=ON -DOPUS_BUILD_PROGRAMS=ON
|
||||
- cmake --build build
|
||||
|
|
|
@ -274,6 +274,7 @@ target_include_directories(
|
|||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/opus>
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lpcnet/include
|
||||
celt
|
||||
silk)
|
||||
|
||||
|
@ -351,6 +352,7 @@ endif()
|
|||
|
||||
add_sources_group(opus silk ${silk_headers} ${silk_sources})
|
||||
add_sources_group(opus celt ${celt_headers} ${celt_sources})
|
||||
add_sources_group(opus lpcnet ${lpcnet_headers} ${lpcnet_sources})
|
||||
|
||||
if(OPUS_FIXED_POINT)
|
||||
add_sources_group(opus silk ${silk_sources_fixed})
|
||||
|
@ -643,4 +645,14 @@ if(BUILD_TESTING AND NOT BUILD_SHARED_LIBS)
|
|||
-DTEST_EXECUTABLE=$<TARGET_FILE:test_opus_encode>
|
||||
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
|
||||
-P "${PROJECT_SOURCE_DIR}/cmake/RunTest.cmake")
|
||||
|
||||
add_executable(test_opus_extensions ${test_opus_extensions_sources})
|
||||
target_include_directories(test_opus_extensions
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR} celt)
|
||||
target_link_libraries(test_opus_extensions PRIVATE opus)
|
||||
target_compile_definitions(test_opus_extensions PRIVATE OPUS_BUILD)
|
||||
add_test(NAME test_opus_extensions COMMAND ${CMAKE_COMMAND}
|
||||
-DTEST_EXECUTABLE=$<TARGET_FILE:test_opus_extensions>
|
||||
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
|
||||
-P "${PROJECT_SOURCE_DIR}/cmake/RunTest.cmake")
|
||||
endif()
|
||||
|
|
|
@ -113,6 +113,7 @@ noinst_PROGRAMS = celt/tests/test_unit_cwrs32 \
|
|||
tests/test_opus_api \
|
||||
tests/test_opus_decode \
|
||||
tests/test_opus_encode \
|
||||
tests/test_opus_extensions \
|
||||
tests/test_opus_padding \
|
||||
tests/test_opus_projection \
|
||||
trivial_example
|
||||
|
@ -129,6 +130,7 @@ TESTS = celt/tests/test_unit_cwrs32 \
|
|||
tests/test_opus_api \
|
||||
tests/test_opus_decode \
|
||||
tests/test_opus_encode \
|
||||
tests/test_opus_extensions \
|
||||
tests/test_opus_padding \
|
||||
tests/test_opus_projection
|
||||
|
||||
|
@ -152,6 +154,9 @@ tests_test_opus_api_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
|
|||
tests_test_opus_encode_SOURCES = tests/test_opus_encode.c tests/opus_encode_regressions.c tests/test_opus_common.h
|
||||
tests_test_opus_encode_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
|
||||
|
||||
tests_test_opus_extensions_SOURCES = tests/test_opus_extensions.c tests/test_opus_common.h
|
||||
tests_test_opus_extensions_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
|
||||
|
||||
tests_test_opus_decode_SOURCES = tests/test_opus_decode.c tests/test_opus_common.h
|
||||
tests_test_opus_decode_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
|
||||
|
||||
|
|
|
@ -102,13 +102,16 @@ TESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C))
|
|||
TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c tests/opus_encode_regressions.c
|
||||
TESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C))
|
||||
|
||||
TESTOPUSEXTENSIONS_SRCS_C = tests/test_opus_extensions.c
|
||||
TESTOPUSEXTENSIONS_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSEXTENSIONS_SRCS_C))
|
||||
|
||||
TESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c
|
||||
TESTOPUSPADDING_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSPADDING_SRCS_C))
|
||||
|
||||
OPUSCOMPARE_SRCS_C = src/opus_compare.c
|
||||
OPUSCOMPARE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSCOMPARE_SRCS_C))
|
||||
|
||||
TESTS := test_opus_api test_opus_decode test_opus_encode test_opus_padding
|
||||
TESTS := test_opus_api test_opus_decode test_opus_encode test_opus_extensions test_opus_padding
|
||||
|
||||
# Rules
|
||||
all: lib opus_demo opus_compare $(TESTS)
|
||||
|
@ -133,6 +136,9 @@ test_opus_decode$(EXESUFFIX): $(TESTOPUSDECODE_OBJS) $(TARGET)
|
|||
test_opus_encode$(EXESUFFIX): $(TESTOPUSENCODE_OBJS) $(TARGET)
|
||||
$(LINK.o.cmdline)
|
||||
|
||||
test_opus_extensions$(EXESUFFIX): $(TESTOPUSEXTENSIONS_OBJS) $(TARGET)
|
||||
$(LINK.o.cmdline)
|
||||
|
||||
test_opus_padding$(EXESUFFIX): $(TESTOPUSPADDING_OBJS) $(TARGET)
|
||||
$(LINK.o.cmdline)
|
||||
|
||||
|
@ -154,8 +160,10 @@ force:
|
|||
clean:
|
||||
rm -f opus_demo$(EXESUFFIX) opus_compare$(EXESUFFIX) $(TARGET) \
|
||||
test_opus_api$(EXESUFFIX) test_opus_decode$(EXESUFFIX) \
|
||||
test_opus_encode$(EXESUFFIX) test_opus_padding$(EXESUFFIX) \
|
||||
test_opus_encode$(EXESUFFIX) test_opus_extensions$(EXESUFFIX) \
|
||||
test_opus_padding$(EXESUFFIX)
|
||||
$(OBJS) $(OPUSDEMO_OBJS) $(OPUSCOMPARE_OBJS) $(TESTOPUSAPI_OBJS) \
|
||||
$(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) $(TESTOPUSPADDING_OBJS)
|
||||
$(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) \
|
||||
$(TESTOPUSEXTENSIONS_OBJS) $(TESTOPUSPADDING_OBJS)
|
||||
|
||||
.PHONY: all lib clean force check
|
||||
|
|
|
@ -100,13 +100,16 @@ TESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C))
|
|||
TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c tests/opus_encode_regressions.c
|
||||
TESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C))
|
||||
|
||||
TESTOPUSEXTENSIONS_SRCS_C = tests/test_opus_extensions.c
|
||||
TESTOPUSEXTENSIONS_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSEXTENSIONS_SRCS_C))
|
||||
|
||||
TESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c
|
||||
TESTOPUSPADDING_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSPADDING_SRCS_C))
|
||||
|
||||
OPUSCOMPARE_SRCS_C = src/opus_compare.c
|
||||
OPUSCOMPARE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(OPUSCOMPARE_SRCS_C))
|
||||
|
||||
TESTS := test_opus_api test_opus_decode test_opus_encode test_opus_padding
|
||||
TESTS := test_opus_api test_opus_decode test_opus_encode test_opus_extensions test_opus_padding
|
||||
|
||||
# Rules
|
||||
all: lib opus_demo opus_compare $(TESTS)
|
||||
|
@ -131,6 +134,9 @@ test_opus_decode$(EXESUFFIX): $(TESTOPUSDECODE_OBJS) $(TARGET)
|
|||
test_opus_encode$(EXESUFFIX): $(TESTOPUSENCODE_OBJS) $(TARGET)
|
||||
$(LINK.o.cmdline)
|
||||
|
||||
test_opus_extensions$(EXESUFFIX): $(TESTOPUSEXTENSIONS_OBJS) $(TARGET)
|
||||
$(LINK.o.cmdline)
|
||||
|
||||
test_opus_padding$(EXESUFFIX): $(TESTOPUSPADDING_OBJS) $(TARGET)
|
||||
$(LINK.o.cmdline)
|
||||
|
||||
|
@ -152,8 +158,10 @@ force:
|
|||
clean:
|
||||
rm -f opus_demo$(EXESUFFIX) opus_compare$(EXESUFFIX) $(TARGET) \
|
||||
test_opus_api$(EXESUFFIX) test_opus_decode$(EXESUFFIX) \
|
||||
test_opus_encode$(EXESUFFIX) test_opus_padding$(EXESUFFIX) \
|
||||
test_opus_encode$(EXESUFFIX) test_opus_extensions$(EXESUFFIX) \
|
||||
test_opus_padding$(EXESUFFIX)
|
||||
$(OBJS) $(OPUSDEMO_OBJS) $(OPUSCOMPARE_OBJS) $(TESTOPUSAPI_OBJS) \
|
||||
$(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) $(TESTOPUSPADDING_OBJS)
|
||||
$(TESTOPUSDECODE_OBJS) $(TESTOPUSENCODE_OBJS) \
|
||||
$(TESTOPUSEXTENSIONS_OBJS) $(TESTOPUSPADDING_OBJS)
|
||||
|
||||
.PHONY: all lib clean force check
|
||||
|
|
|
@ -9,6 +9,7 @@ set -e
|
|||
srcdir=`dirname $0`
|
||||
test -n "$srcdir" && cd "$srcdir"
|
||||
|
||||
git submodule update --init
|
||||
(cd lpcnet; ./download_model.sh 9daefbb)
|
||||
|
||||
echo "Updating build configuration files, please wait...."
|
||||
|
|
|
@ -37,12 +37,17 @@ get_opus_sources(CELT_SOURCES_ARM_NEON_INTR celt_sources.mk
|
|||
celt_sources_arm_neon_intr)
|
||||
get_opus_sources(CELT_SOURCES_ARM_NE10 celt_sources.mk celt_sources_arm_ne10)
|
||||
|
||||
get_opus_sources(LPCNET_HEAD lpcnet_headers.mk lpcnet_headers)
|
||||
get_opus_sources(LPCNET_SOURCES lpcnet_sources.mk lpcnet_sources)
|
||||
|
||||
get_opus_sources(opus_demo_SOURCES Makefile.am opus_demo_sources)
|
||||
get_opus_sources(opus_custom_demo_SOURCES Makefile.am opus_custom_demo_sources)
|
||||
get_opus_sources(opus_compare_SOURCES Makefile.am opus_compare_sources)
|
||||
get_opus_sources(tests_test_opus_api_SOURCES Makefile.am test_opus_api_sources)
|
||||
get_opus_sources(tests_test_opus_encode_SOURCES Makefile.am
|
||||
test_opus_encode_sources)
|
||||
get_opus_sources(tests_test_opus_extensions_SOURCES Makefile.am
|
||||
test_opus_extensions_sources)
|
||||
get_opus_sources(tests_test_opus_decode_SOURCES Makefile.am
|
||||
test_opus_decode_sources)
|
||||
get_opus_sources(tests_test_opus_padding_SOURCES Makefile.am
|
||||
|
|
|
@ -99,15 +99,21 @@ opus_int32 opus_packet_extensions_count(const unsigned char *data, opus_int32 le
|
|||
opus_int32 curr_len;
|
||||
opus_int32 count=0;
|
||||
const unsigned char *curr_data = data;
|
||||
|
||||
celt_assert(len >= 0);
|
||||
celt_assert(data != NULL || len == 0);
|
||||
|
||||
curr_len = len;
|
||||
while (curr_len > 0)
|
||||
{
|
||||
int id;
|
||||
opus_int32 header_size;
|
||||
id = *curr_data>>1;
|
||||
curr_len = skip_extension(&curr_data, curr_len, &header_size);
|
||||
if (curr_len < 0)
|
||||
return OPUS_INVALID_PACKET;
|
||||
if (id > 1)
|
||||
count++;
|
||||
curr_len = skip_extension(&curr_data, curr_len, &header_size);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
@ -120,6 +126,11 @@ opus_int32 opus_packet_extensions_parse(const unsigned char *data, opus_int32 le
|
|||
int curr_frame=0;
|
||||
opus_int32 count=0;
|
||||
|
||||
celt_assert(len >= 0);
|
||||
celt_assert(data != NULL || len == 0);
|
||||
celt_assert(nb_extensions != NULL);
|
||||
celt_assert(extensions != NULL || *nb_extensions == 0);
|
||||
|
||||
curr_data = data;
|
||||
curr_len = len;
|
||||
while (curr_len > 0)
|
||||
|
@ -181,10 +192,14 @@ opus_int32 opus_packet_extensions_generate(unsigned char *data, opus_int32 len,
|
|||
int curr_frame = 0;
|
||||
opus_int32 pos = 0;
|
||||
opus_int32 written = 0;
|
||||
|
||||
celt_assert(len >= 0);
|
||||
celt_assert(data != NULL || len == 0);
|
||||
|
||||
for (i=0;i<nb_extensions;i++)
|
||||
{
|
||||
max_frame = IMAX(max_frame, extensions[i].frame);
|
||||
if (extensions[i].id < 2)
|
||||
if (extensions[i].id < 2 || extensions[i].id > 127)
|
||||
return OPUS_BAD_ARG;
|
||||
}
|
||||
if (max_frame >= 48) return OPUS_BAD_ARG;
|
||||
|
@ -225,6 +240,8 @@ opus_int32 opus_packet_extensions_generate(unsigned char *data, opus_int32 len,
|
|||
} else {
|
||||
int last;
|
||||
opus_int32 length_bytes;
|
||||
if (extensions[i].len < 0)
|
||||
return OPUS_BAD_ARG;
|
||||
last = (written == nb_extensions - 1);
|
||||
length_bytes = 1 + extensions[i].len/255;
|
||||
if (last)
|
||||
|
|
|
@ -214,6 +214,8 @@ opus_int32 opus_packet_extensions_parse(const unsigned char *data, opus_int32 le
|
|||
|
||||
opus_int32 opus_packet_extensions_generate(unsigned char *data, opus_int32 len, const opus_extension_data *extensions, int nb_extensions, int pad);
|
||||
|
||||
opus_int32 opus_packet_extensions_count(const unsigned char *data, opus_int32 len);
|
||||
|
||||
opus_int32 opus_packet_pad_impl(unsigned char *data, opus_int32 len, opus_int32 new_len, int pad, const opus_extension_data *extensions, int nb_extensions);
|
||||
|
||||
#endif /* OPUS_PRIVATE_H */
|
||||
|
|
|
@ -3,6 +3,7 @@ opus_tests = [
|
|||
['test_opus_api'],
|
||||
['test_opus_decode', [], 60],
|
||||
['test_opus_encode', 'opus_encode_regressions.c', 120],
|
||||
['test_opus_extensions'],
|
||||
['test_opus_padding'],
|
||||
['test_opus_projection'],
|
||||
]
|
||||
|
|
|
@ -82,4 +82,5 @@ static OPUS_INLINE void _test_failed(const char *file, int line)
|
|||
}
|
||||
#define test_failed() _test_failed(__FILE__, __LINE__);
|
||||
#define opus_test_assert(cond) {if (!(cond)) {test_failed();}}
|
||||
#define expect_true(cond, msg) {if (!(cond)) {fprintf(stderr, "FAIL - %s\n", msg); test_failed();}}
|
||||
void regression_test(void);
|
||||
|
|
313
tests/test_opus_extensions.c
Normal file
313
tests/test_opus_extensions.c
Normal file
|
@ -0,0 +1,313 @@
|
|||
/* Copyright (c) 2023 Amazon
|
||||
Written by Michael Klingbeil */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
/* including sources directly to test internal APIs */
|
||||
#define CELT_C /* to make celt_assert work */
|
||||
#include "../src/extensions.c"
|
||||
#include "test_opus_common.h"
|
||||
|
||||
void test_extensions_generate_success(void)
|
||||
{
|
||||
static const opus_extension_data ext[] = {
|
||||
{2, 0, (const unsigned char *)"a", 1},
|
||||
{32, 10, (const unsigned char *)"DRED", 4},
|
||||
{33, 1, (const unsigned char *)"NOT DRED", 8},
|
||||
{3, 4, (const unsigned char *)NULL, 0}
|
||||
};
|
||||
|
||||
int result;
|
||||
unsigned char packet[32];
|
||||
const unsigned char *p = packet;
|
||||
result = opus_packet_extensions_generate(packet, 23+4, ext, 4, 1);
|
||||
expect_true(result == 23+4, "expected length 23+4");
|
||||
|
||||
/* expect padding */
|
||||
expect_true(p[0] == 1 && p[1] == 1 && p[2] == 1 && p[3] == 1, "expected padding");
|
||||
p += 4;
|
||||
|
||||
/* extension ID=2 */
|
||||
expect_true((p[0] >> 1) == 2, "expected extension id 2");
|
||||
/* For extension IDs 1 through 31, L=0 means that no data follows the
|
||||
extension, whereas L=1 means that exactly one byte of extension data follows. */
|
||||
expect_true((p[0] & 0x01) == 1, "expected L-bit set");
|
||||
/* content */
|
||||
expect_true(p[1] == 'a', "expected extension content");
|
||||
p += 2;
|
||||
|
||||
/* next byte should increment the frame count, ID=1, L=0 */
|
||||
expect_true(p[0] == 0x02, "bad frame separator");
|
||||
p += 1;
|
||||
/* extension ID=33 */
|
||||
expect_true((p[0] >> 1) == 33, "expected extension id 33");
|
||||
/* For IDs 32 to 127, L=0 signals that the extension data takes up the
|
||||
rest of the padding, and L=1 signals that a length indicator follows. */
|
||||
expect_true((p[0] & 0x01) == 1, "expected L-bit set");
|
||||
/* content */
|
||||
expect_true(p[1] == ext[2].len, "expected length");
|
||||
p += 2;
|
||||
expect_true(0 == memcmp(p, ext[2].data, ext[2].len), "expected extension content");
|
||||
p += ext[2].len;
|
||||
|
||||
/* advance to frame 4, increment by 3 */
|
||||
/* next byte should increment the frame count, ID=1, L=1 */
|
||||
expect_true(p[0] == 0x03, "bad frame separator");
|
||||
expect_true(p[1] == 0x03, "bad frame increment");
|
||||
p += 2;
|
||||
/* extension ID=3 */
|
||||
expect_true((p[0] >> 1) == 3, "expected extension id 3");
|
||||
/* For extension IDs 1 through 31, L=0 means that no data follows the
|
||||
extension, whereas L=1 means that exactly one byte of extension data follows. */
|
||||
expect_true((p[0] & 0x01) == 0, "expected L-bit unset");
|
||||
p += 1;
|
||||
|
||||
/* advance to frame 10, increment by 6 */
|
||||
/* next byte should increment the frame count, ID=1, L=1 */
|
||||
expect_true(p[0] == 0x03, "bad frame separator");
|
||||
expect_true(p[1] == 0x06, "bad frame increment");
|
||||
p += 2;
|
||||
/* extension ID=32 */
|
||||
expect_true((p[0] >> 1) == 32, "expected extension id 32");
|
||||
/* For IDs 32 to 127, L=0 signals that the extension data takes up the
|
||||
rest of the padding */
|
||||
expect_true((p[0] & 0x01) == 0, "expected L-bit unset");
|
||||
p += 1;
|
||||
expect_true(0 == memcmp(p, ext[3].data, ext[3].len), "expected extension content");
|
||||
}
|
||||
|
||||
void test_extensions_generate_zero(void)
|
||||
{
|
||||
int result;
|
||||
unsigned char packet[32];
|
||||
|
||||
/* zero length packet, zero extensions */
|
||||
result = opus_packet_extensions_generate(packet, 0, NULL, 0, 1);
|
||||
expect_true(result == 0, "expected length 0");
|
||||
}
|
||||
|
||||
void test_extensions_generate_no_padding(void)
|
||||
{
|
||||
static const opus_extension_data ext[] = {
|
||||
{2, 0, (const unsigned char *)"a", 1},
|
||||
{32, 10, (const unsigned char *)"DRED", 4},
|
||||
{33, 1, (const unsigned char *)"NOT DRED", 8},
|
||||
{3, 4, (const unsigned char *)NULL, 0}
|
||||
};
|
||||
|
||||
int result;
|
||||
unsigned char packet[32];
|
||||
result = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
|
||||
expect_true(result == 23, "expected length 23");
|
||||
}
|
||||
|
||||
void test_extensions_generate_fail(void)
|
||||
{
|
||||
static const opus_extension_data ext[] = {
|
||||
{2, 0, (const unsigned char *)"a", 1},
|
||||
{32, 10, (const unsigned char *)"DRED", 4},
|
||||
{33, 1, (const unsigned char *)"NOT DRED", 8},
|
||||
{3, 4, (const unsigned char *)NULL, 0}
|
||||
};
|
||||
|
||||
int result;
|
||||
unsigned char packet[100];
|
||||
|
||||
/* buffer too small */
|
||||
result = opus_packet_extensions_generate(packet, 4, ext, 4, 1);
|
||||
expect_true(result == OPUS_BUFFER_TOO_SMALL, "expected OPUS_BUFFER_TOO_SMALL");
|
||||
|
||||
/* invalid id */
|
||||
{
|
||||
static const opus_extension_data id_too_big[] = {
|
||||
{256, 0, (const unsigned char *)"a", 1},
|
||||
};
|
||||
result = opus_packet_extensions_generate(packet, sizeof(packet), id_too_big, 1, 1);
|
||||
expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
|
||||
}
|
||||
|
||||
/* invalid id */
|
||||
{
|
||||
static const opus_extension_data id_too_small[] = {
|
||||
{1, 0, (const unsigned char *)"a", 1},
|
||||
};
|
||||
result = opus_packet_extensions_generate(packet, sizeof(packet), id_too_small, 1, 1);
|
||||
expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
|
||||
}
|
||||
|
||||
/* frame index too big */
|
||||
{
|
||||
static const opus_extension_data frame_too_big[] = {
|
||||
{33, 48, (const unsigned char *)"a", 1},
|
||||
};
|
||||
result = opus_packet_extensions_generate(packet, sizeof(packet), frame_too_big, 1, 1);
|
||||
expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
|
||||
}
|
||||
|
||||
/* size too big for extension IDs 1 through 31 */
|
||||
{
|
||||
static const opus_extension_data size_too_big[] = {
|
||||
{2, 0, (const unsigned char *)"abcd", 4},
|
||||
};
|
||||
result = opus_packet_extensions_generate(packet, sizeof(packet), size_too_big, 1, 1);
|
||||
expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
|
||||
}
|
||||
|
||||
/* negative size for extension IDs 1 through 31 */
|
||||
{
|
||||
static const opus_extension_data neg_size[] = {
|
||||
{2, 0, NULL, -4},
|
||||
};
|
||||
result = opus_packet_extensions_generate(packet, sizeof(packet), neg_size, 1, 1);
|
||||
expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
|
||||
}
|
||||
|
||||
/* negative size for extension IDs 32 through 127 */
|
||||
{
|
||||
static const opus_extension_data neg_size_33[] = {
|
||||
{33, 0, NULL, -4},
|
||||
};
|
||||
result = opus_packet_extensions_generate(packet, sizeof(packet), neg_size_33, 1, 1);
|
||||
expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
|
||||
}
|
||||
}
|
||||
|
||||
void test_extensions_parse_success(void)
|
||||
{
|
||||
static const opus_extension_data ext[] = {
|
||||
{2, 0, (const unsigned char *)"a", 1},
|
||||
{32, 10, (const unsigned char *)"DRED", 4},
|
||||
{33, 1, (const unsigned char *)"NOT DRED", 8},
|
||||
{3, 4, (const unsigned char *)NULL, 0}
|
||||
};
|
||||
opus_extension_data ext_out[10];
|
||||
int nb_ext;
|
||||
int len, result;
|
||||
unsigned char packet[32];
|
||||
|
||||
nb_ext = 10;
|
||||
len = opus_packet_extensions_generate(packet, 32, ext, 4, 1);
|
||||
expect_true(len == 32, "expected length 32");
|
||||
result = opus_packet_extensions_count(packet, len);
|
||||
expect_true(result == 4, "expected opus_packet_extensions_count 4");
|
||||
result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
|
||||
expect_true(nb_ext == 4, "expected 4 extensions");
|
||||
|
||||
expect_true(ext_out[0].id == 2, "expected id 2");
|
||||
expect_true(ext_out[0].frame == 0, "expected frame 0");
|
||||
expect_true(ext_out[0].len == 1, "expected len 1");
|
||||
expect_true(0 == memcmp(ext_out[0].data, ext[0].data, 1), "expected data");
|
||||
|
||||
expect_true(ext_out[1].id == 33, "expected id 33");
|
||||
expect_true(ext_out[1].frame == 1, "expected frame 1");
|
||||
expect_true(ext_out[1].len == 8, "expected len 8");
|
||||
expect_true(0 == memcmp(ext_out[1].data, ext[2].data, 8), "expected data");
|
||||
|
||||
expect_true(ext_out[2].id == 3, "expected id 3");
|
||||
expect_true(ext_out[2].frame == 4, "expected frame 4");
|
||||
expect_true(ext_out[2].len == 0, "expected len 0");
|
||||
|
||||
expect_true(ext_out[3].id == 32, "expected id 32");
|
||||
expect_true(ext_out[3].frame == 10, "expected frame 10");
|
||||
expect_true(ext_out[3].len == 4, "expected len 4");
|
||||
expect_true(0 == memcmp(ext_out[3].data, ext[1].data, 4), "expected data");
|
||||
}
|
||||
|
||||
void test_extensions_parse_zero(void)
|
||||
{
|
||||
static const opus_extension_data ext[] = {
|
||||
{32, 1, (const unsigned char *)"DRED", 4},
|
||||
};
|
||||
int nb_ext;
|
||||
int len, result;
|
||||
unsigned char packet[32];
|
||||
|
||||
len = opus_packet_extensions_generate(packet, 32, ext, 1, 1);
|
||||
expect_true(len == 32, "expected length 32");
|
||||
|
||||
nb_ext = 0;
|
||||
result = opus_packet_extensions_parse(packet, len, NULL, &nb_ext);
|
||||
expect_true(result == OPUS_BUFFER_TOO_SMALL, "expected OPUS_BUFFER_TOO_SMALL");
|
||||
}
|
||||
|
||||
void test_extensions_parse_fail(void)
|
||||
{
|
||||
static const opus_extension_data ext[] = {
|
||||
{2, 0, (const unsigned char *)"a", 1},
|
||||
{33, 1, (const unsigned char *)"NOT DRED", 8},
|
||||
{3, 4, (const unsigned char *)NULL, 0},
|
||||
{32, 10, (const unsigned char *)"DRED", 4}
|
||||
};
|
||||
opus_extension_data ext_out[10];
|
||||
int nb_ext;
|
||||
int len, result;
|
||||
unsigned char packet[32];
|
||||
|
||||
/* create invalid length */
|
||||
len = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
|
||||
packet[4] = 255;
|
||||
nb_ext = 10;
|
||||
result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
|
||||
expect_true(result == OPUS_INVALID_PACKET, "expected OPUS_INVALID_PACKET");
|
||||
result = opus_packet_extensions_count(packet, len);
|
||||
expect_true(result == OPUS_INVALID_PACKET, "expected OPUS_INVALID_PACKET");
|
||||
|
||||
/* create invalid frame increment */
|
||||
nb_ext = 10;
|
||||
len = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
|
||||
packet[14] = 255;
|
||||
result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
|
||||
expect_true(result == OPUS_INVALID_PACKET, "expected OPUS_INVALID_PACKET");
|
||||
/* note, opus_packet_extensions_count does not read the invalid frame increment
|
||||
and tells us that we have 4 extensions */
|
||||
result = opus_packet_extensions_count(packet, len);
|
||||
expect_true(result == 4, "expected opus_packet_extensions_count to return 4");
|
||||
|
||||
/* not enough space */
|
||||
nb_ext = 1;
|
||||
len = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
|
||||
result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
|
||||
expect_true(result == OPUS_BUFFER_TOO_SMALL, "expected OPUS_BUFFER_TOO_SMALL");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_extensions_generate_success();
|
||||
test_extensions_generate_zero();
|
||||
test_extensions_generate_no_padding();
|
||||
test_extensions_generate_fail();
|
||||
test_extensions_parse_success();
|
||||
test_extensions_parse_zero();
|
||||
test_extensions_parse_fail();
|
||||
fprintf(stderr,"Tests completed successfully.\n");
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue