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:
commit
0c35e4385d
1
Makefile
1
Makefile
@ -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 = @
|
||||
|
@ -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
32
test/c_interface_test.c
Normal 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
116
test/cpp_interface_test.cpp
Normal 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;
|
||||
}
|
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user