Merge pull request #281 from jwwang/add_gtests

1. support .c in makefile generator. 2. add test to check C interfaces.
This commit is contained in:
Ethan Hugg 2014-02-12 07:47:16 -08:00
commit 0c35e4385d
5 changed files with 183 additions and 3 deletions

View File

@ -64,6 +64,7 @@ ASMFLAGS += $(ASMFLAGS_PLATFORM) -DNO_DYNAMIC_VP
#### No user-serviceable parts below this line
ifneq ($(V),Yes)
QUIET_CXX = @printf "CXX\t$@\n";
QUIET_CC = @printf "CC\t$@\n";
QUIET_ASM = @printf "ASM\t$@\n";
QUIET_AR = @printf "AR\t$@\n";
QUIET = @

View File

@ -30,6 +30,14 @@ def write_cpp_rule_pattern(f):
f.write('\t$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(' + PREFIX + '_CFLAGS) $(' + PREFIX + '_INCLUDES) -c $(CXX_O) $<\n')
f.write("\n")
def write_c_rule_pattern(f):
src = "$(%s_SRCDIR)/%%.c"%(PREFIX)
dst = "$(%s_SRCDIR)/%%.o"%(PREFIX)
f.write("%s: %s\n"%(dst, src))
f.write('\t$(QUIET_CC)$(CC) $(CFLAGS) $(INCLUDES) $(' + PREFIX + '_CFLAGS) $(' + PREFIX + '_INCLUDES) -c $(CXX_O) $<\n')
f.write("\n")
def write_asm_rule_pattern(f):
src = "$(%s_SRCDIR)/%%.asm"%(PREFIX)
dst = "$(%s_SRCDIR)/%%.o"%(PREFIX)
@ -42,6 +50,7 @@ def write_asm_rule_pattern(f):
def find_sources():
cpp_files = []
asm_files = []
c_files = []
print EXCLUDE
for dir in os.walk("."):
for file in dir[2]:
@ -50,7 +59,9 @@ def find_sources():
cpp_files.append(os.path.join(dir[0].strip('./'), file))
if os.path.splitext(file)[1] == '.asm':
asm_files.append(os.path.join(dir[0].strip('./'), file))
return [cpp_files, asm_files]
if os.path.splitext(file)[1] == '.c':
c_files.append(os.path.join(dir[0].strip('./'), file))
return [cpp_files, asm_files, c_files]
args = parser.parse_args()
@ -80,7 +91,7 @@ try:
except:
sys.exit(1)
(cpp, asm) = find_sources()
(cpp, asm, cfiles) = find_sources()
@ -91,7 +102,14 @@ f.write("%s_CPP_SRCS=\\\n"%(PREFIX))
for c in cpp:
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, c))
f.write("\n")
f.write("%s_OBJS += $(%s_CPP_SRCS:%s=.o)\n"%(PREFIX, PREFIX, CPP_SUFFIX))
f.write("%s_OBJS += $(%s_CPP_SRCS:%s=.o)\n\n"%(PREFIX, PREFIX, CPP_SUFFIX))
if len(cfiles) > 0:
f.write("%s_C_SRCS=\\\n"%(PREFIX))
for cfile in cfiles:
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, cfile))
f.write("\n")
f.write("%s_OBJS += $(%s_C_SRCS:.c=.o)\n\n"%(PREFIX, PREFIX))
if len(asm) > 0:
f.write("ifeq ($(USE_ASM), Yes)\n")
@ -106,6 +124,9 @@ f.write("OBJS += $(%s_OBJS)\n"%PREFIX)
write_cpp_rule_pattern(f)
if len(cfiles) > 0:
write_c_rule_pattern(f)
if len(asm) > 0:
write_asm_rule_pattern(f)

32
test/c_interface_test.c Normal file
View File

@ -0,0 +1,32 @@
#include "codec_api.h"
// Cast to this function type to ignore other parameters.
typedef int (*Func)(void*);
#define CALL(p, m) (((Func)((*p)->m))(p))
// Check if the function return an expected number.
#define CHECK(n, p, m) check(n, CALL(p, m), #m)
typedef void(*CheckFunc)(int, int, const char*);
void CheckEncoderInterface(ISVCEncoder* p, CheckFunc check) {
CHECK(1, p, Initialize);
CHECK(2, p, Initialize2);
CHECK(3, p, Uninitialize);
CHECK(4, p, EncodeFrame);
CHECK(5, p, EncodeFrame2);
CHECK(6, p, EncodeParameterSets);
CHECK(7, p, PauseFrame);
CHECK(8, p, ForceIntraFrame);
CHECK(9, p, SetOption);
CHECK(10, p, GetOption);
}
void CheckDecoderInterface(ISVCDecoder* p, CheckFunc check) {
CHECK(1, p, Initialize);
CHECK(2, p, Uninitialize);
CHECK(3, p, DecodeFrame);
CHECK(4, p, DecodeFrame2);
CHECK(5, p, DecodeFrameEx);
CHECK(6, p, SetOption);
CHECK(7, p, GetOption);
}

116
test/cpp_interface_test.cpp Normal file
View File

@ -0,0 +1,116 @@
#include <gtest/gtest.h>
#include "codec_api.h"
static void CheckFunctionOrder(int expect, int actual, const char* name) {
EXPECT_EQ(expect, actual) << "Wrong function order: " << name;
}
typedef void(*CheckFunc)(int, int, const char*);
extern "C" void CheckEncoderInterface(ISVCEncoder* p, CheckFunc);
extern "C" void CheckDecoderInterface(ISVCDecoder* p, CheckFunc);
// Store the 'this' pointer to verify 'this' is received as expected from C code.
static void* gThis;
/**
* Return a unique number for each virtual function so that we are able to
* check if the order of functions in the virtual table is as expected.
*/
struct SVCEncoderImpl : public ISVCEncoder {
virtual ~SVCEncoderImpl() {}
virtual int EXTAPI Initialize(SVCEncodingParam* pParam,
const INIT_TYPE kiInitType) {
EXPECT_TRUE(gThis == this);
return 1;
}
virtual int EXTAPI Initialize2(void* pParam, const INIT_TYPE kiInitType) {
EXPECT_TRUE(gThis == this);
return 2;
}
virtual int EXTAPI Uninitialize() {
EXPECT_TRUE(gThis == this);
return 3;
}
virtual int EXTAPI EncodeFrame(const unsigned char* kpSrc,
SFrameBSInfo* pBsInfo) {
EXPECT_TRUE(gThis == this);
return 4;
}
virtual int EXTAPI EncodeFrame2(const SSourcePicture** kppSrcPicList,
int nSrcPicNum, SFrameBSInfo* pBsInfo) {
EXPECT_TRUE(gThis == this);
return 5;
}
virtual int EXTAPI EncodeParameterSets(SFrameBSInfo* pBsInfo) {
EXPECT_TRUE(gThis == this);
return 6;
}
virtual int EXTAPI PauseFrame(const unsigned char* kpSrc,
SFrameBSInfo* pBsInfo) {
EXPECT_TRUE(gThis == this);
return 7;
}
virtual int EXTAPI ForceIntraFrame(bool bIDR) {
EXPECT_TRUE(gThis == this);
return 8;
}
virtual int EXTAPI SetOption(ENCODER_OPTION eOptionId, void* pOption) {
EXPECT_TRUE(gThis == this);
return 9;
}
virtual int EXTAPI GetOption(ENCODER_OPTION eOptionId, void* pOption) {
EXPECT_TRUE(gThis == this);
return 10;
}
};
struct SVCDecoderImpl : public ISVCDecoder {
virtual ~SVCDecoderImpl() {}
virtual long EXTAPI Initialize(void* pParam, const INIT_TYPE iInitType) {
EXPECT_TRUE(gThis == this);
return 1;
}
virtual long EXTAPI Uninitialize() {
EXPECT_TRUE(gThis == this);
return 2;
}
virtual DECODING_STATE EXTAPI DecodeFrame(const unsigned char* pSrc,
const int iSrcLen, unsigned char** ppDst, int* pStride,
int& iWidth, int& iHeight) {
EXPECT_TRUE(gThis == this);
return static_cast<DECODING_STATE>(3);
}
virtual DECODING_STATE EXTAPI DecodeFrame2(const unsigned char* pSrc,
const int iSrcLen, void** ppDst, SBufferInfo* pDstInfo) {
EXPECT_TRUE(gThis == this);
return static_cast<DECODING_STATE>(4);
}
virtual DECODING_STATE EXTAPI DecodeFrameEx(const unsigned char* pSrc,
const int iSrcLen, unsigned char* pDst, int iDstStride,
int& iDstLen, int& iWidth, int& iHeight, int& iColorFormat) {
EXPECT_TRUE(gThis == this);
return static_cast<DECODING_STATE>(5);
}
virtual long EXTAPI SetOption (DECODER_OPTION eOptionId, void* pOption) {
EXPECT_TRUE(gThis == this);
return 6;
}
virtual long EXTAPI GetOption (DECODER_OPTION eOptionId, void* pOption) {
EXPECT_TRUE(gThis == this);
return 7;
}
};
TEST(ISVCEncoderTest, CheckFunctionOrder) {
SVCEncoderImpl* p = new SVCEncoderImpl;
gThis = p;
CheckEncoderInterface(p, CheckFunctionOrder);
delete p;
}
TEST(ISVCDecoderTest, CheckFunctionOrder) {
SVCDecoderImpl* p = new SVCDecoderImpl;
gThis = p;
CheckDecoderInterface(p, CheckFunctionOrder);
delete p;
}

View File

@ -6,12 +6,22 @@ CODEC_UNITTEST_CPP_SRCS=\
$(CODEC_UNITTEST_SRCDIR)/decoder_test.cpp\
$(CODEC_UNITTEST_SRCDIR)/encoder_test.cpp\
$(CODEC_UNITTEST_SRCDIR)/simple_test.cpp\
$(CODEC_UNITTEST_SRCDIR)/./cpp_interface_test.cpp\
CODEC_UNITTEST_OBJS += $(CODEC_UNITTEST_CPP_SRCS:.cpp=.o)
CODEC_UNITTEST_C_SRCS=\
$(CODEC_UNITTEST_SRCDIR)/./c_interface_test.c\
CODEC_UNITTEST_OBJS += $(CODEC_UNITTEST_C_SRCS:.c=.o)
OBJS += $(CODEC_UNITTEST_OBJS)
$(CODEC_UNITTEST_SRCDIR)/%.o: $(CODEC_UNITTEST_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(CODEC_UNITTEST_CFLAGS) $(CODEC_UNITTEST_INCLUDES) -c $(CXX_O) $<
$(CODEC_UNITTEST_SRCDIR)/%.o: $(CODEC_UNITTEST_SRCDIR)/%.c
$(QUIET_CXX)$(CC) $(CFLAGS) $(INCLUDES) $(CODEC_UNITTEST_CFLAGS) $(CODEC_UNITTEST_INCLUDES) -c $(CXX_O) $<
codec_unittest$(EXEEXT): $(CODEC_UNITTEST_OBJS) $(LIBS) $(CODEC_UNITTEST_LIBS) $(CODEC_UNITTEST_DEPS)
$(QUIET_CXX)$(CXX) $(CXX_LINK_O) $(CODEC_UNITTEST_OBJS) $(CODEC_UNITTEST_LDFLAGS) $(CODEC_UNITTEST_LIBS) $(LDFLAGS) $(LIBS)