Compare commits
188 Commits
openh264v1
...
v1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
825ce5dcd9 | ||
|
|
6f9624790c | ||
|
|
ca0ed2a067 | ||
|
|
be97ccb45b | ||
|
|
6e56e80a8a | ||
|
|
4f7602e268 | ||
|
|
d6ff4304fa | ||
|
|
3cce92ea19 | ||
|
|
dcdcc7f3b8 | ||
|
|
273e1227a5 | ||
|
|
43c62d06eb | ||
|
|
5d6b20119a | ||
|
|
a594ddf3e7 | ||
|
|
0a3d4c4ebc | ||
|
|
57aae73d4c | ||
|
|
94a1d4426e | ||
|
|
23b5a61153 | ||
|
|
33e67427ab | ||
|
|
4e89e71e8f | ||
|
|
8d5863a170 | ||
|
|
97298de90a | ||
|
|
3c4279cdd8 | ||
|
|
452fb868c7 | ||
|
|
41720f8df5 | ||
|
|
769c38d4c4 | ||
|
|
195d13612c | ||
|
|
6c4f0d7d85 | ||
|
|
e415c3fe70 | ||
|
|
b17e9bb320 | ||
|
|
7720f2cc5d | ||
|
|
88b7a62f98 | ||
|
|
a765197b73 | ||
|
|
d720122a37 | ||
|
|
cbe7891300 | ||
|
|
5762cbb8fc | ||
|
|
1a78f69f2f | ||
|
|
d1a3bd3d33 | ||
|
|
89454f0cf9 | ||
|
|
9a0d56da97 | ||
|
|
d74c0f6ae6 | ||
|
|
9d182ee515 | ||
|
|
2479abf5c0 | ||
|
|
869c567f04 | ||
|
|
cdb7e5da61 | ||
|
|
46ee46c186 | ||
|
|
d9e0f2b023 | ||
|
|
39d725c113 | ||
|
|
cab92a3e36 | ||
|
|
ba535bda4d | ||
|
|
2ff61475d6 | ||
|
|
1e62aafcde | ||
|
|
4fc27714bd | ||
|
|
3ad4d9070e | ||
|
|
024ac63f15 | ||
|
|
614e898b67 | ||
|
|
3885bd8f0e | ||
|
|
b425450bc1 | ||
|
|
ad247a9a4a | ||
|
|
f9bab05b3a | ||
|
|
52419bd13e | ||
|
|
8c8cd50c96 | ||
|
|
68fed53687 | ||
|
|
b7c54242a9 | ||
|
|
04c2a7ac5c | ||
|
|
27a21edcc9 | ||
|
|
3593f2e3e7 | ||
|
|
007fb47004 | ||
|
|
0affe66f93 | ||
|
|
311272d341 | ||
|
|
efdefdba28 | ||
|
|
a3a0effc88 | ||
|
|
d875d923f8 | ||
|
|
6b1630cc90 | ||
|
|
3904c025cb | ||
|
|
72df20000b | ||
|
|
fd8d41dbb9 | ||
|
|
07fa3d1898 | ||
|
|
6673a5f71e | ||
|
|
e4b373a800 | ||
|
|
cf2cf9efd9 | ||
|
|
6ae38da3ab | ||
|
|
19c02bdfa8 | ||
|
|
bab0bf18f8 | ||
|
|
8945348c87 | ||
|
|
ed341048de | ||
|
|
73d27e9776 | ||
|
|
bef3d87f34 | ||
|
|
9f20c727d1 | ||
|
|
810d20a59d | ||
|
|
d0f9b218f4 | ||
|
|
ffebbdb9b2 | ||
|
|
4e57a46ca5 | ||
|
|
c618cb1eaf | ||
|
|
a3bdf4ffc9 | ||
|
|
147c9052b8 | ||
|
|
cfbf32b3fb | ||
|
|
f8d2ae42ef | ||
|
|
a59a989d9b | ||
|
|
06e56ecdd8 | ||
|
|
f6fb459a7f | ||
|
|
fd8db0451e | ||
|
|
ee2f87dbbc | ||
|
|
17df23c2eb | ||
|
|
480ff5acc2 | ||
|
|
66e38cc9ed | ||
|
|
c480ffdad5 | ||
|
|
84ca659f06 | ||
|
|
25cad576b3 | ||
|
|
f5b9d920ff | ||
|
|
64fa8a6b60 | ||
|
|
ac2de4cbab | ||
|
|
3ba0a9956a | ||
|
|
c4a446b43a | ||
|
|
880bf2d621 | ||
|
|
1d37250301 | ||
|
|
7e71714863 | ||
|
|
05684744c9 | ||
|
|
3ff145e839 | ||
|
|
25b723c413 | ||
|
|
ca96def4ff | ||
|
|
c213c6ba30 | ||
|
|
8538b22f23 | ||
|
|
399ca33284 | ||
|
|
4e54fd191b | ||
|
|
19dcff8616 | ||
|
|
68e92f9eb6 | ||
|
|
5c67f368c3 | ||
|
|
a6cc71208e | ||
|
|
58eba54e8c | ||
|
|
9d9c609aab | ||
|
|
958113073f | ||
|
|
37ae6505d4 | ||
|
|
c5091e73be | ||
|
|
8eafdfa598 | ||
|
|
e7cd53e81b | ||
|
|
f8d5f93b16 | ||
|
|
48f203929e | ||
|
|
b85a09163f | ||
|
|
49ce86c78a | ||
|
|
72862118f9 | ||
|
|
631ca210a8 | ||
|
|
b51ff51387 | ||
|
|
4001551027 | ||
|
|
458cc6b4fd | ||
|
|
522aa4457a | ||
|
|
311f7006fd | ||
|
|
9913b73cb1 | ||
|
|
9e7a19291c | ||
|
|
0fe477625c | ||
|
|
6b64efbf92 | ||
|
|
235f6e3474 | ||
|
|
77552551f7 | ||
|
|
679cc4ac6c | ||
|
|
c6a136c742 | ||
|
|
1a394d1432 | ||
|
|
bffbde9f45 | ||
|
|
84848bb7d3 | ||
|
|
bb43c1c9a9 | ||
|
|
f003fa1fe6 | ||
|
|
1df4cd43cc | ||
|
|
6f553c9742 | ||
|
|
79157ce632 | ||
|
|
a6df69c305 | ||
|
|
a1dbf6ab13 | ||
|
|
ef590de0dc | ||
|
|
684c42536d | ||
|
|
881667a533 | ||
|
|
4fc144b698 | ||
|
|
1b1ea2b9ef | ||
|
|
d63172db9b | ||
|
|
2f041c7a4b | ||
|
|
43dc6f01e1 | ||
|
|
61926f208c | ||
|
|
199d19a785 | ||
|
|
7c95ccc6a7 | ||
|
|
f2437f24b9 | ||
|
|
c287a9109f | ||
|
|
3735cfc1bd | ||
|
|
315d9315c4 | ||
|
|
7e8cde055f | ||
|
|
d98fd57252 | ||
|
|
4ece8efaed | ||
|
|
cef43e30fe | ||
|
|
15124b1258 | ||
|
|
b5a01efa96 | ||
|
|
aa7eb5fd09 | ||
|
|
849a730608 | ||
|
|
24bd0b74ae |
8
Makefile
8
Makefile
@@ -136,7 +136,7 @@ clean:
|
||||
ifeq (android,$(OS))
|
||||
clean: clean_Android
|
||||
endif
|
||||
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(LIBRARIES) $(BINARIES)
|
||||
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(OBJS:.$(OBJ)=.obj) $(LIBRARIES) $(BINARIES) *.lib *.a *.dylib *.dll *.so
|
||||
|
||||
gmp-bootstrap:
|
||||
if [ ! -d gmp-api ] ; then git clone https://github.com/mozilla/gmp-api gmp-api ; fi
|
||||
@@ -191,7 +191,7 @@ $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROC
|
||||
|
||||
$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
|
||||
$(QUIET)rm -f $@
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(LDFLAGS) $(CXX_LINK_O) $+ $(SHLDFLAGS)
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(SHLDFLAGS)
|
||||
|
||||
ifeq ($(HAVE_GMP_API),Yes)
|
||||
plugin: $(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX)
|
||||
@@ -204,7 +204,7 @@ endif
|
||||
|
||||
$(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX): $(MODULE_OBJS) $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
|
||||
$(QUIET)rm -f $@
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(LDFLAGS) $(CXX_LINK_O) $+ $(SHLDFLAGS) $(MODULE_LDFLAGS)
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(SHLDFLAGS) $(MODULE_LDFLAGS)
|
||||
|
||||
install-headers:
|
||||
mkdir -p $(PREFIX)/include/wels
|
||||
@@ -241,7 +241,7 @@ $(LIBPREFIX)ut.$(LIBSUFFIX): $(DECODER_UNITTEST_OBJS) $(ENCODER_UNITTEST_OBJS) $
|
||||
LIBRARIES +=$(LIBPREFIX)ut.$(SHAREDLIBSUFFIX)
|
||||
$(LIBPREFIX)ut.$(SHAREDLIBSUFFIX): $(DECODER_UNITTEST_OBJS) $(ENCODER_UNITTEST_OBJS) $(PROCESSING_UNITTEST_OBJS) $(API_TEST_OBJS) $(COMMON_UNITTEST_OBJS) $(CODEC_UNITTEST_DEPS)
|
||||
$(QUIET)rm -f $@
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(LDFLAGS) $(CXX_LINK_O) $+ $(CODEC_UNITTEST_LDFLAGS)
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(CODEC_UNITTEST_LDFLAGS)
|
||||
|
||||
binaries: codec_unittest$(EXEEXT)
|
||||
BINARIES += codec_unittest$(EXEEXT)
|
||||
|
||||
BIN
OpenH264_API_v1.2.0.docx
Normal file
BIN
OpenH264_API_v1.2.0.docx
Normal file
Binary file not shown.
34
RELEASES
34
RELEASES
@@ -1,19 +1,15 @@
|
||||
|
||||
Releases
|
||||
-----------
|
||||
v1.1.1
|
||||
- Modify some APIs
|
||||
- Add WelsGetDecoderCapability for SDP negotiation usage
|
||||
- Add RC_BUFFERBASED_MODE for screen content RC
|
||||
- Add SLTRConfig for SetOption in encoder
|
||||
- Add ENCODER_OPTION_COMPLEXITY/ECOMPLEXITY_MODE in TagEncParamExt
|
||||
- Remove uiFrameToBeCoded in TagEncParamExt
|
||||
- Remove iInputCsp in TagEncParamBase/TagEncParamExt
|
||||
- Modify iOutputColorFormat as eOutputColorFormat
|
||||
- Modify uiEcActiveFlag as eEcActiveIdc
|
||||
- Rename ENCOCER_LTR_MARKING_PERIOD to ENCODER_LTR_MARKING_PERIOD
|
||||
- Improve the encoding speed of screen content encoding including ARM and X86
|
||||
- fix some bugs
|
||||
v1.2.0
|
||||
------
|
||||
- Add and modify encoder APIs related to rate control and screen content encoding
|
||||
- Remove PauseFrame in encoder APIs
|
||||
- Improve rate control and compression ratio for screen content encoding
|
||||
- Improve error concealment algorithm
|
||||
- Improve validation of input parameters
|
||||
- Add ARM64 assembly
|
||||
- bug fixes
|
||||
|
||||
-----------
|
||||
v1.1.0
|
||||
@@ -30,11 +26,19 @@ Binaries
|
||||
These binary releases are distributed under this license:
|
||||
http://www.openh264.org/BINARY_LICENSE.txt
|
||||
|
||||
v1.2.0
|
||||
------
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-android19.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-linux32.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-linux64.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-osx32.dylib.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.2.0-osx64.dylib.bz2
|
||||
http://ciscobinary.openh264.org/openh264-1.2.0-win32msvc.dll.bz2
|
||||
http://ciscobinary.openh264.org/openh264-1.2.0-win64msvc.dll.bz2
|
||||
|
||||
v1.1.0
|
||||
------
|
||||
http://ciscobinary.openh264.org/libopenh264-1.1.0-android19.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.1.0-ios32.a.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.1.0-ios64.a.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.1.0-linux32.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.1.0-linux64.so.bz2
|
||||
http://ciscobinary.openh264.org/libopenh264-1.1.0-osx32.dylib.bz2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ifneq ($(filter %86 x86_64, $(ARCH)),)
|
||||
include $(SRC_PATH)build/platform-x86-common.mk
|
||||
include $(SRC_PATH)build/x86-common.mk
|
||||
endif
|
||||
ifneq ($(filter-out arm64, $(filter arm%, $(ARCH))),)
|
||||
ifeq ($(USE_ASM), Yes)
|
||||
@@ -5,6 +5,7 @@ GTEST_CPP_SRCS=\
|
||||
GTEST_OBJS += $(GTEST_CPP_SRCS:.cc=.$(OBJ))
|
||||
|
||||
OBJS += $(GTEST_OBJS)
|
||||
|
||||
$(GTEST_SRCDIR)/%.$(OBJ): $(GTEST_SRCDIR)/%.cc
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(GTEST_CFLAGS) $(GTEST_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -134,37 +134,42 @@ if len(cfiles) > 0:
|
||||
for cfile in cfiles:
|
||||
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, cfile))
|
||||
f.write("\n")
|
||||
f.write("%s_OBJS += $(%s_C_SRCS:.c=.$(OBJ))\n\n"%(PREFIX, PREFIX))
|
||||
f.write("%s_OBJS += $(%s_C_SRCS:.c=.$(OBJ))\n"%(PREFIX, PREFIX))
|
||||
|
||||
if len(asm) > 0:
|
||||
f.write("ifeq ($(ASM_ARCH), x86)\n")
|
||||
f.write("%s_ASM_SRCS=\\\n"%(PREFIX))
|
||||
for c in asm:
|
||||
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, c))
|
||||
f.write("\n")
|
||||
f.write("%s_OBJS += $(%s_ASM_SRCS:.asm=.$(OBJ))\n"%(PREFIX, PREFIX))
|
||||
f.write("endif\n\n")
|
||||
f.write("%s_OBJSASM += $(%s_ASM_SRCS:.asm=.$(OBJ))\n"%(PREFIX, PREFIX))
|
||||
f.write("ifeq ($(ASM_ARCH), x86)\n")
|
||||
f.write("%s_OBJS += $(%s_OBJSASM)\n"%(PREFIX,PREFIX))
|
||||
f.write("endif\n")
|
||||
f.write("OBJS += $(%s_OBJSASM)\n\n"%(PREFIX))
|
||||
|
||||
if len(armfiles) > 0:
|
||||
f.write("ifeq ($(ASM_ARCH), arm)\n")
|
||||
f.write("%s_ASM_ARM_SRCS=\\\n"%(PREFIX))
|
||||
for c in armfiles:
|
||||
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, c))
|
||||
f.write("\n")
|
||||
f.write("%s_OBJS += $(%s_ASM_ARM_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
|
||||
f.write("endif\n\n")
|
||||
f.write("%s_OBJSARM += $(%s_ASM_ARM_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
|
||||
f.write("ifeq ($(ASM_ARCH), arm)\n")
|
||||
f.write("%s_OBJS += $(%s_OBJSARM)\n"%(PREFIX,PREFIX))
|
||||
f.write("endif\n")
|
||||
f.write("OBJS += $(%s_OBJSARM)\n\n"%(PREFIX))
|
||||
|
||||
if len(arm64files) > 0:
|
||||
f.write("ifeq ($(ASM_ARCH), arm64)\n")
|
||||
f.write("%s_ASM_ARM64_SRCS=\\\n"%(PREFIX))
|
||||
for c in arm64files:
|
||||
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, c))
|
||||
f.write("\n")
|
||||
f.write("%s_OBJS += $(%s_ASM_ARM64_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
|
||||
f.write("endif\n\n")
|
||||
|
||||
f.write("OBJS += $(%s_OBJS)\n"%PREFIX)
|
||||
f.write("%s_OBJSARM64 += $(%s_ASM_ARM64_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
|
||||
f.write("ifeq ($(ASM_ARCH), arm64)\n")
|
||||
f.write("%s_OBJS += $(%s_OBJSARM64)\n"%(PREFIX,PREFIX))
|
||||
f.write("endif\n")
|
||||
f.write("OBJS += $(%s_OBJSARM64)\n\n"%(PREFIX))
|
||||
|
||||
f.write("OBJS += $(%s_OBJS)\n\n"%(PREFIX))
|
||||
write_cpp_rule_pattern(f)
|
||||
|
||||
if len(cfiles) > 0:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include $(SRC_PATH)build/platform-arch.mk
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
ifeq ($(ENABLE64BIT), Yes)
|
||||
ASMFLAGS += -f win64
|
||||
@@ -1,5 +1,5 @@
|
||||
ARCH = arm
|
||||
include $(SRC_PATH)build/platform-arch.mk
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIBSUFFIX = so
|
||||
NDKLEVEL = 12
|
||||
ifeq ($(ARCH), arm)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include $(SRC_PATH)build/platform-arch.mk
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIBSUFFIX = dylib
|
||||
SHARED = -dynamiclib
|
||||
CFLAGS += -Wall -fPIC -MMD -MP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include $(SRC_PATH)build/platform-arch.mk
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIBSUFFIX = so
|
||||
CFLAGS += -fPIC
|
||||
LDFLAGS += -lpthread
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include $(SRC_PATH)build/platform-arch.mk
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIBSUFFIX = so
|
||||
CFLAGS += -Wall -fno-strict-aliasing -fPIC -MMD -MP
|
||||
LDFLAGS += -lpthread
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include $(SRC_PATH)build/platform-x86-common.mk
|
||||
include $(SRC_PATH)build/x86-common.mk
|
||||
SHAREDLIBSUFFIX = dll
|
||||
CFLAGS += -MMD -MP
|
||||
LDFLAGS +=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ARCH = arm
|
||||
include $(SRC_PATH)build/platform-msvc-common.mk
|
||||
include $(SRC_PATH)build/msvc-common.mk
|
||||
CFLAGS_OPT += -MD
|
||||
CFLAGS_DEBUG += -MDd
|
||||
CFLAGS += -DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include $(SRC_PATH)build/platform-msvc-common.mk
|
||||
include $(SRC_PATH)build/msvc-common.mk
|
||||
LDFLAGS += user32.lib
|
||||
CFLAGS_OPT += -MT
|
||||
CFLAGS_DEBUG += -MTd -Gm
|
||||
|
||||
@@ -106,6 +106,14 @@ class ISVCDecoder {
|
||||
unsigned char** ppDst,
|
||||
SBufferInfo* pDstInfo) = 0;
|
||||
|
||||
/*
|
||||
* This function parse input bitstream only, and rewrite possible SVC syntax to AVC syntax
|
||||
* return: 0 - success; otherwise -failed;
|
||||
*/
|
||||
virtual DECODING_STATE EXTAPI DecodeParser (const unsigned char* pSrc,
|
||||
const int iSrcLen,
|
||||
SParserBsInfo* pDstInfo) = 0;
|
||||
|
||||
/*
|
||||
* this API does not work for now!! This is for future use to support non-I420 color format output.
|
||||
*/
|
||||
@@ -169,6 +177,10 @@ DECODING_STATE (*DecodeFrame2) (ISVCDecoder*, const unsigned char* pSrc,
|
||||
unsigned char** ppDst,
|
||||
SBufferInfo* pDstInfo);
|
||||
|
||||
DECODING_STATE (*DecodeParser) (ISVCDecoder*, const unsigned char* pSrc,
|
||||
const int iSrcLen,
|
||||
SParserBsInfo* pDstInfo);
|
||||
|
||||
DECODING_STATE (*DecodeFrameEx) (ISVCDecoder*, const unsigned char* pSrc,
|
||||
const int iSrcLen,
|
||||
unsigned char* pDst,
|
||||
|
||||
@@ -102,6 +102,12 @@ typedef enum {
|
||||
ENCODER_OPTION_TRACE_LEVEL,
|
||||
ENCODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
|
||||
ENCODER_OPTION_TRACE_CALLBACK_CONTEXT,
|
||||
|
||||
ENCODER_OPTION_GET_STATISTICS, //read only
|
||||
ENCODER_OPTION_STATISTICS_LOG_INTERVAL, // log interval in milliseconds
|
||||
|
||||
// advanced algorithmetic settings
|
||||
ENCODER_OPTION_IS_LOSSLESS_LINK
|
||||
} ENCODER_OPTION;
|
||||
|
||||
/* Option types introduced in decoder application */
|
||||
@@ -119,13 +125,15 @@ typedef enum {
|
||||
DECODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
|
||||
DECODER_OPTION_TRACE_CALLBACK_CONTEXT,
|
||||
|
||||
DECODER_OPTION_GET_STATISTICS
|
||||
|
||||
} DECODER_OPTION;
|
||||
|
||||
//enuerate the types of error concealment methods
|
||||
typedef enum {
|
||||
ERROR_CON_DISABLE = 0,
|
||||
ERROR_CON_FRAME_COPY,
|
||||
ERROR_CON_SLICE_COPY,
|
||||
ERROR_CON_SLICE_COPY
|
||||
} ERROR_CON_IDC;
|
||||
|
||||
typedef enum { //feedback that whether or not have VCL NAL in current AU
|
||||
@@ -145,14 +153,14 @@ typedef enum {
|
||||
SPATIAL_LAYER_1 = 1,
|
||||
SPATIAL_LAYER_2 = 2,
|
||||
SPATIAL_LAYER_3 = 3,
|
||||
SPATIAL_LAYER_ALL = 4,
|
||||
SPATIAL_LAYER_ALL = 4
|
||||
} LAYER_NUM;
|
||||
|
||||
//enumerate the type of video bitstream which is provided to decoder
|
||||
typedef enum {
|
||||
VIDEO_BITSTREAM_AVC = 0,
|
||||
VIDEO_BITSTREAM_SVC = 1,
|
||||
VIDEO_BITSTREAM_DEFAULT = VIDEO_BITSTREAM_SVC,
|
||||
VIDEO_BITSTREAM_DEFAULT = VIDEO_BITSTREAM_SVC
|
||||
} VIDEO_BITSTREAM_TYPE;
|
||||
|
||||
typedef enum {
|
||||
@@ -161,7 +169,7 @@ typedef enum {
|
||||
IDR_RECOVERY_REQUEST = 2,
|
||||
NO_LTR_MARKING_FEEDBACK = 3,
|
||||
LTR_MARKING_SUCCESS = 4,
|
||||
LTR_MARKING_FAILED = 5,
|
||||
LTR_MARKING_FAILED = 5
|
||||
} KEY_FRAME_REQUEST_TYPE;
|
||||
|
||||
typedef struct {
|
||||
@@ -179,7 +187,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
bool bEnableLongTermReference; // 1: on, 0: off
|
||||
int iLTRRefNum;
|
||||
int iLTRRefNum; //TODO: not supported to set it arbitrary yet
|
||||
} SLTRConfig;
|
||||
typedef struct {
|
||||
unsigned int
|
||||
@@ -201,9 +209,8 @@ typedef enum {
|
||||
typedef enum {
|
||||
RC_QUALITY_MODE = 0, //Quality mode
|
||||
RC_BITRATE_MODE = 1, //Bitrate mode
|
||||
RC_LOW_BW_MODE = 2, //bitrate limited mode
|
||||
RC_BUFFERBASED_MODE = 3,//no bitrate control,only using buffer status,adjust the video quality
|
||||
RC_OFF_MODE = -1, // rate control off mode
|
||||
RC_BUFFERBASED_MODE = 2,//no bitrate control,only using buffer status,adjust the video quality
|
||||
RC_OFF_MODE = -1 // rate control off mode
|
||||
} RC_MODES;
|
||||
|
||||
typedef enum {
|
||||
@@ -218,7 +225,7 @@ typedef enum {
|
||||
PRO_CAVLC444 = 244,
|
||||
|
||||
PRO_SCALABLE_BASELINE = 83,
|
||||
PRO_SCALABLE_HIGH = 86,
|
||||
PRO_SCALABLE_HIGH = 86
|
||||
} EProfileIdc;
|
||||
|
||||
typedef enum {
|
||||
@@ -275,13 +282,13 @@ typedef struct {
|
||||
|
||||
typedef enum {
|
||||
CAMERA_VIDEO_REAL_TIME, //camera video signal
|
||||
SCREEN_CONTENT_REAL_TIME,//screen content signal
|
||||
SCREEN_CONTENT_REAL_TIME //screen content signal
|
||||
} EUsageType;
|
||||
|
||||
typedef enum {
|
||||
LOW_COMPLEXITY, //the lowest compleixty,the fastest speed,
|
||||
MEDIUM_COMPLEXITY, //medium complexity, medium speed,medium quality
|
||||
HIGH_COMPLEXITY, //high complexity, lowest speed, high quality
|
||||
HIGH_COMPLEXITY //high complexity, lowest speed, high quality
|
||||
} ECOMPLEXITY_MODE;
|
||||
// TODO: Refine the parameters definition.
|
||||
// SVC Encoding Parameters
|
||||
@@ -330,7 +337,7 @@ typedef struct TagEncParamExt {
|
||||
|
||||
/*LTR settings*/
|
||||
bool bEnableLongTermReference; // 1: on, 0: off
|
||||
int iLTRRefNum;
|
||||
int iLTRRefNum; //TODO: not supported to set it arbitrary yet
|
||||
unsigned int iLtrMarkPeriod;
|
||||
|
||||
/* multi-thread settings*/
|
||||
@@ -347,6 +354,9 @@ typedef struct TagEncParamExt {
|
||||
bool bEnableAdaptiveQuant; // adaptive quantization control
|
||||
bool bEnableFrameCroppingFlag;// enable frame cropping flag: TRUE always in application
|
||||
bool bEnableSceneChangeDetect;
|
||||
|
||||
/*LTR advanced setting*/
|
||||
bool bIsLosslessLink;
|
||||
} SEncParamExt;
|
||||
|
||||
//Define a new struct to show the property of video bitstream.
|
||||
@@ -442,4 +452,46 @@ typedef struct TagDecoderCapability {
|
||||
bool bRedPicCap;
|
||||
} SDecoderCapability;
|
||||
|
||||
typedef struct TagParserBsInfo {
|
||||
int iNalNum; //total NAL number in current AU
|
||||
int iNalLenInByte [MAX_NAL_UNITS_IN_LAYER]; //each nal length
|
||||
unsigned char* pDstBuff; //outputted dst buffer for parsed bitstream
|
||||
int iSpsWidthInPixel; //required SPS width info
|
||||
int iSpsHeightInPixel; //required SPS height info
|
||||
} SParserBsInfo, PParserBsInfo;
|
||||
|
||||
typedef struct TagVideoEncoderStatistics {
|
||||
unsigned int uiWidth; // the width of encoded frame
|
||||
unsigned int uiHeight; // the height of encoded frame
|
||||
//following standard, will be 16x aligned, if there are multiple spatial, this is of the highest
|
||||
float fAverageFrameSpeedInMs; // Average_Encoding_Time
|
||||
|
||||
// rate control related
|
||||
float fAverageFrameRate; // the average frame rate in, calculate since encoding starts, supposed that the input timestamp is in unit of ms
|
||||
float fLatestFrameRate; // the frame rate in, in the last second, supposed that the input timestamp is in unit of ms (? useful for checking BR, but is it easy to calculate?
|
||||
unsigned int uiBitRate; // sendrate in Bits per second, calculated within the set time-window
|
||||
|
||||
unsigned int uiInputFrameCount; // number of frames
|
||||
unsigned int uiSkippedFrameCount; // number of frames
|
||||
|
||||
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
|
||||
unsigned int uiIDRReqNum; // number of IDR requests
|
||||
unsigned int uiIDRSentNum; // number of actual IDRs sent
|
||||
unsigned int uiLTRSentNum; // number of LTR sent/marked
|
||||
} SEncoderStatistics; // in building, coming soon
|
||||
|
||||
typedef struct TagVideoDecoderStatistics {
|
||||
unsigned int uiWidth; // the width of encode/decode frame
|
||||
unsigned int uiHeight; // the height of encode/decode frame
|
||||
float fAverageFrameSpeedInMs; // Average_Decoding_Time
|
||||
|
||||
unsigned int uiDecodedFrameCount; // number of frames
|
||||
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
|
||||
unsigned int
|
||||
uiAvgEcRatio; // when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
|
||||
unsigned int uiIDRReqNum; // number of actual IDR request
|
||||
unsigned int uiLTRReqNum; // number of actual LTR request
|
||||
unsigned int uiIDRRecvNum; // number of actual IDR received
|
||||
} SDecoderStatistics; // in building, coming soon
|
||||
|
||||
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef enum {
|
||||
videoFrameTypeI, /* I frame type */
|
||||
videoFrameTypeP, /* P frame type */
|
||||
videoFrameTypeSkip, /* Skip the frame based encoder kernel */
|
||||
videoFrameTypeIPMixed, /* Frame type introduced I and P slices are mixing */
|
||||
videoFrameTypeIPMixed /* Frame type introduced I and P slices are mixing */
|
||||
} EVideoFrameType;
|
||||
|
||||
typedef enum {
|
||||
@@ -72,7 +72,7 @@ typedef enum {
|
||||
cmUnkonwReason,
|
||||
cmMallocMemeError, /*Malloc a memory error*/
|
||||
cmInitExpected, /*Initial action is expected*/
|
||||
cmUnsupportedData,
|
||||
cmUnsupportedData
|
||||
} CM_RETURN;
|
||||
|
||||
/* nal unit type */
|
||||
@@ -93,7 +93,7 @@ enum ENalPriority {
|
||||
NAL_PRIORITY_DISPOSABLE = 0,
|
||||
NAL_PRIORITY_LOW = 1,
|
||||
NAL_PRIORITY_HIGH = 2,
|
||||
NAL_PRIORITY_HIGHEST = 3,
|
||||
NAL_PRIORITY_HIGHEST = 3
|
||||
};
|
||||
|
||||
#define IS_PARAMETER_SET_NAL(eNalRefIdc, eNalType) \
|
||||
@@ -116,7 +116,7 @@ enum {
|
||||
ET_IR_R3 = 0x10, // Intra Refresh in predifined 10% MB
|
||||
ET_FEC_HALF = 0x20, // Forward Error Correction in 50% redundency mode
|
||||
ET_FEC_FULL = 0x40, // Forward Error Correction in 100% redundency mode
|
||||
ET_RFS = 0x80, // Reference Frame Selection
|
||||
ET_RFS = 0x80 // Reference Frame Selection
|
||||
};
|
||||
|
||||
/* information of coded Slice(=NAL)(s) */
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
F5AC94FF193EB7D800F58154 /* deblocking_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */; };
|
||||
F5B8D82D190757290037849A /* mc_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5B8D82C190757290037849A /* mc_aarch64_neon.S */; };
|
||||
F5BB0BB8196BB5960072D50D /* copy_mb_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */; };
|
||||
F791965419D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F791965319D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S */; };
|
||||
F791965619D3B8A600F60C6B /* intra_pred_common_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F791965519D3B8A600F60C6B /* intra_pred_common_neon.S */; };
|
||||
F791965919D3BE2200F60C6B /* intra_pred_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F791965819D3BE2200F60C6B /* intra_pred_common.cpp */; };
|
||||
FAABAA1818E9354A00D4186F /* sad_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAABAA1718E9354A00D4186F /* sad_common.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -74,6 +77,10 @@
|
||||
F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = deblocking_aarch64_neon.S; path = arm64/deblocking_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
F5B8D82C190757290037849A /* mc_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = mc_aarch64_neon.S; path = arm64/mc_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = copy_mb_aarch64_neon.S; path = arm64/copy_mb_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
F791965319D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = intra_pred_common_aarch64_neon.S; path = arm64/intra_pred_common_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
F791965519D3B8A600F60C6B /* intra_pred_common_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_common_neon.S; sourceTree = "<group>"; };
|
||||
F791965719D3BA9300F60C6B /* intra_pred_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intra_pred_common.h; sourceTree = "<group>"; };
|
||||
F791965819D3BE2200F60C6B /* intra_pred_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intra_pred_common.cpp; sourceTree = "<group>"; };
|
||||
FAABAA1618E9353F00D4186F /* sad_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sad_common.h; sourceTree = "<group>"; };
|
||||
FAABAA1718E9354A00D4186F /* sad_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sad_common.cpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -93,6 +100,7 @@
|
||||
4C3406B118D96EA600DFA14A /* arm */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F791965519D3B8A600F60C6B /* intra_pred_common_neon.S */,
|
||||
4CC61F0818FF6B4B00E56EAB /* copy_mb_neon.S */,
|
||||
4C3406B218D96EA600DFA14A /* arm_arch_common_macro.S */,
|
||||
4C3406B318D96EA600DFA14A /* deblocking_neon.S */,
|
||||
@@ -105,6 +113,7 @@
|
||||
4C3406B618D96EA600DFA14A /* inc */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F791965719D3BA9300F60C6B /* intra_pred_common.h */,
|
||||
F0B204F718FD23B6005DA23F /* copy_mb.h */,
|
||||
FAABAA1618E9353F00D4186F /* sad_common.h */,
|
||||
4C3406B718D96EA600DFA14A /* cpu.h */,
|
||||
@@ -126,6 +135,7 @@
|
||||
4C3406C318D96EA600DFA14A /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F791965819D3BE2200F60C6B /* intra_pred_common.cpp */,
|
||||
5BA8F2BF19603F5F00011CE4 /* common_tables.cpp */,
|
||||
F0B204F818FD23BF005DA23F /* copy_mb.cpp */,
|
||||
FAABAA1718E9354A00D4186F /* sad_common.cpp */,
|
||||
@@ -179,6 +189,7 @@
|
||||
F556A81D1906669F00E156A8 /* arm64 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F791965319D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S */,
|
||||
F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */,
|
||||
F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */,
|
||||
F5B8D82C190757290037849A /* mc_aarch64_neon.S */,
|
||||
@@ -244,12 +255,15 @@
|
||||
F556A8241906673900E156A8 /* arm_arch64_common_macro.S in Sources */,
|
||||
F5AC94FF193EB7D800F58154 /* deblocking_aarch64_neon.S in Sources */,
|
||||
4C3406CE18D96EA600DFA14A /* crt_util_safe_x.cpp in Sources */,
|
||||
F791965919D3BE2200F60C6B /* intra_pred_common.cpp in Sources */,
|
||||
4C3406CF18D96EA600DFA14A /* deblocking_common.cpp in Sources */,
|
||||
5BA8F2C019603F5F00011CE4 /* common_tables.cpp in Sources */,
|
||||
F791965419D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S in Sources */,
|
||||
4C3406D118D96EA600DFA14A /* WelsThreadLib.cpp in Sources */,
|
||||
4C3406CC18D96EA600DFA14A /* mc_neon.S in Sources */,
|
||||
F5BB0BB8196BB5960072D50D /* copy_mb_aarch64_neon.S in Sources */,
|
||||
4C3406CB18D96EA600DFA14A /* expand_picture_neon.S in Sources */,
|
||||
F791965619D3B8A600F60C6B /* intra_pred_common_neon.S in Sources */,
|
||||
4CC61F0918FF6B4B00E56EAB /* copy_mb_neon.S in Sources */,
|
||||
53C1C9BC193F0FB000404D8F /* expand_pic.cpp in Sources */,
|
||||
4C3406CD18D96EA600DFA14A /* cpu.cpp in Sources */,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
549947E2196A3FB400BA3D87 /* pixel_sad_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 549947AE196A3FB400BA3D87 /* pixel_sad_neon.S */; };
|
||||
549947E3196A3FB400BA3D87 /* vaa_calc_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 549947AF196A3FB400BA3D87 /* vaa_calc_neon.S */; };
|
||||
549947E4196A3FB400BA3D87 /* BackgroundDetection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947B1196A3FB400BA3D87 /* BackgroundDetection.cpp */; };
|
||||
549947E5196A3FB400BA3D87 /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947B4196A3FB400BA3D87 /* common.cpp */; };
|
||||
549947E6196A3FB400BA3D87 /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947B6196A3FB400BA3D87 /* memory.cpp */; };
|
||||
549947E7196A3FB400BA3D87 /* WelsFrameWork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947BB196A3FB400BA3D87 /* WelsFrameWork.cpp */; };
|
||||
549947E8196A3FB400BA3D87 /* WelsFrameWorkEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947BD196A3FB400BA3D87 /* WelsFrameWorkEx.cpp */; };
|
||||
@@ -34,6 +33,7 @@
|
||||
549947F3196A3FB400BA3D87 /* vaacalcfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947D8196A3FB400BA3D87 /* vaacalcfuncs.cpp */; };
|
||||
549947F4196A3FB400BA3D87 /* vaacalculation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947D9196A3FB400BA3D87 /* vaacalculation.cpp */; };
|
||||
6C749B78197E2A2000A111F9 /* adaptive_quantization_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C749B77197E2A2000A111F9 /* adaptive_quantization_aarch64_neon.S */; };
|
||||
F791965B19D3BF6B00F60C6B /* intra_pred_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F791965A19D3BF6B00F60C6B /* intra_pred_common.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -64,7 +64,6 @@
|
||||
549947AF196A3FB400BA3D87 /* vaa_calc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = vaa_calc_neon.S; sourceTree = "<group>"; };
|
||||
549947B1196A3FB400BA3D87 /* BackgroundDetection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackgroundDetection.cpp; sourceTree = "<group>"; };
|
||||
549947B2196A3FB400BA3D87 /* BackgroundDetection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackgroundDetection.h; sourceTree = "<group>"; };
|
||||
549947B4196A3FB400BA3D87 /* common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = common.cpp; sourceTree = "<group>"; };
|
||||
549947B5196A3FB400BA3D87 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
|
||||
549947B6196A3FB400BA3D87 /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = "<group>"; };
|
||||
549947B7196A3FB400BA3D87 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
|
||||
@@ -97,6 +96,7 @@
|
||||
549947D9196A3FB400BA3D87 /* vaacalculation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vaacalculation.cpp; sourceTree = "<group>"; };
|
||||
549947DA196A3FB400BA3D87 /* vaacalculation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vaacalculation.h; sourceTree = "<group>"; };
|
||||
6C749B77197E2A2000A111F9 /* adaptive_quantization_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = adaptive_quantization_aarch64_neon.S; path = arm64/adaptive_quantization_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
F791965A19D3BF6B00F60C6B /* intra_pred_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = intra_pred_common.cpp; path = ../../../common/src/intra_pred_common.cpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -210,7 +210,7 @@
|
||||
549947B3196A3FB400BA3D87 /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
549947B4196A3FB400BA3D87 /* common.cpp */,
|
||||
F791965A19D3BF6B00F60C6B /* intra_pred_common.cpp */,
|
||||
549947B5196A3FB400BA3D87 /* common.h */,
|
||||
549947B6196A3FB400BA3D87 /* memory.cpp */,
|
||||
549947B7196A3FB400BA3D87 /* memory.h */,
|
||||
@@ -351,7 +351,6 @@
|
||||
549947E9196A3FB400BA3D87 /* ComplexityAnalysis.cpp in Sources */,
|
||||
549947E3196A3FB400BA3D87 /* vaa_calc_neon.S in Sources */,
|
||||
549947EE196A3FB400BA3D87 /* imagerotate.cpp in Sources */,
|
||||
549947E5196A3FB400BA3D87 /* common.cpp in Sources */,
|
||||
549947EA196A3FB400BA3D87 /* denoise.cpp in Sources */,
|
||||
549947E7196A3FB400BA3D87 /* WelsFrameWork.cpp in Sources */,
|
||||
549947F1196A3FB400BA3D87 /* ScrollDetection.cpp in Sources */,
|
||||
@@ -367,6 +366,7 @@
|
||||
4CC6094F197E009D00BE8B8B /* down_sample_aarch64_neon.S in Sources */,
|
||||
4CC6095A1980F34F00BE8B8B /* vaa_calc_aarch64_neon.S in Sources */,
|
||||
549947F2196A3FB400BA3D87 /* ScrollDetectionFuncs.cpp in Sources */,
|
||||
F791965B19D3BF6B00F60C6B /* intra_pred_common.cpp in Sources */,
|
||||
549947EF196A3FB400BA3D87 /* imagerotatefuncs.cpp in Sources */,
|
||||
549947DF196A3FB400BA3D87 /* AdaptiveQuantization.cpp in Sources */,
|
||||
549947EC196A3FB400BA3D87 /* downsample.cpp in Sources */,
|
||||
|
||||
@@ -381,6 +381,10 @@
|
||||
RelativePath="..\..\..\encoder\core\src\get_intra_predictor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\src\intra_pred_common.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\src\mc.cpp"
|
||||
>
|
||||
@@ -727,7 +731,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -745,7 +749,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -767,7 +771,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -959,6 +963,46 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\x86\intra_pred_com.asm"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\x86\matrix_transpose.asm"
|
||||
>
|
||||
@@ -1327,7 +1371,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -1345,7 +1389,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
||||
83
codec/common/arm/intra_pred_common_neon.S
Normal file
83
codec/common/arm/intra_pred_common_neon.S
Normal file
@@ -0,0 +1,83 @@
|
||||
/*!
|
||||
* \copy
|
||||
* Copyright (c) 2013, Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 HOLDER 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_NEON
|
||||
.text
|
||||
#include "arm_arch_common_macro.S"
|
||||
|
||||
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredV_neon
|
||||
//Get the top line data to 'q0'
|
||||
sub r3, r1, r2
|
||||
vldm r3, {d0, d1}
|
||||
|
||||
//mov r2, #16
|
||||
mov r3, #4
|
||||
//Set the top line to the each line of MB(16*16)
|
||||
loop_0_get_i16x16_luma_pred_v:
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
subs r3, #1
|
||||
bne loop_0_get_i16x16_luma_pred_v
|
||||
WELS_ASM_FUNC_END
|
||||
|
||||
|
||||
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredH_neon
|
||||
//stmdb sp!, {r4, lr}
|
||||
sub r1, r1, #1
|
||||
mov r3, #4
|
||||
loop_0_get_i16x16_luma_pred_h:
|
||||
//Get one byte data from left side
|
||||
vld1.8 {d0[],d1[]}, [r1], r2
|
||||
vld1.8 {d2[],d3[]}, [r1], r2
|
||||
vld1.8 {d4[],d5[]}, [r1], r2
|
||||
vld1.8 {d6[],d7[]}, [r1], r2
|
||||
|
||||
//Set the line of MB using the left side byte data
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
//add r0, #16
|
||||
vst1.8 {d2,d3}, [r0]!
|
||||
//add r0, #16
|
||||
vst1.8 {d4,d5}, [r0]!
|
||||
//add r0, #16
|
||||
vst1.8 {d6,d7}, [r0]!
|
||||
//add r0, #16
|
||||
|
||||
subs r3, #1
|
||||
bne loop_0_get_i16x16_luma_pred_h
|
||||
|
||||
WELS_ASM_FUNC_END
|
||||
|
||||
|
||||
#endif
|
||||
55
codec/common/arm64/intra_pred_common_aarch64_neon.S
Normal file
55
codec/common/arm64/intra_pred_common_aarch64_neon.S
Normal file
@@ -0,0 +1,55 @@
|
||||
/*!
|
||||
* \copy
|
||||
* Copyright (c) 2013, Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 HOLDER 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_NEON_AARCH64
|
||||
.text
|
||||
#include "arm_arch64_common_macro.S"
|
||||
|
||||
//for Luma 16x16
|
||||
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredV_AArch64_neon
|
||||
sub x3, x1, x2
|
||||
ld1 {v0.16b}, [x3]
|
||||
.rept 16
|
||||
st1 {v0.16b}, [x0], 16
|
||||
.endr
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
|
||||
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredH_AArch64_neon
|
||||
sub x3, x1, #1
|
||||
.rept 16
|
||||
ld1r {v0.16b}, [x3], x2
|
||||
st1 {v0.16b}, [x0], 16
|
||||
.endr
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
|
||||
#endif
|
||||
|
||||
@@ -117,6 +117,8 @@ WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WE
|
||||
WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
|
||||
void* arg, WELS_THREAD_ATTR attr);
|
||||
|
||||
WELS_THREAD_ERROR_CODE WelsThreadSetName (const char* thread_name);
|
||||
|
||||
WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread);
|
||||
|
||||
WELS_THREAD_HANDLE WelsThreadSelf();
|
||||
|
||||
76
codec/common/inc/intra_pred_common.h
Normal file
76
codec/common/inc/intra_pred_common.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*!
|
||||
* \copy
|
||||
* Copyright (c) 2009-2013, Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 HOLDER 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.
|
||||
*
|
||||
*
|
||||
* \file intra_pred_common.h
|
||||
*
|
||||
* \brief interfaces for intra predictor about 16x16.
|
||||
*
|
||||
* \date 4/2/2014 Created
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INTRA_PRED_COMMON_H
|
||||
#define INTRA_PRED_COMMON_H
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
|
||||
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif//__cplusplus
|
||||
|
||||
#if defined(X86_ASM)
|
||||
//for intra-prediction ASM functions
|
||||
void WelsI16x16LumaPredV_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
#endif//X86_ASM
|
||||
|
||||
#if defined(HAVE_NEON)
|
||||
void WelsI16x16LumaPredV_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
#endif//HAVE_NEON
|
||||
|
||||
#if defined(HAVE_NEON_AARCH64)
|
||||
void WelsI16x16LumaPredV_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
#endif//HAVE_NEON_AARCH64
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif//__cplusplus
|
||||
#endif//
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#define VERSION_NUMBER "openh264 default: 1.1"
|
||||
#define VERSION_NUMBER "openh264 default: 1.2"
|
||||
|
||||
#endif // VERSION_H
|
||||
|
||||
@@ -155,7 +155,7 @@ enum EWelsSliceType {
|
||||
UNKNOWN_SLICE = 5
|
||||
};
|
||||
|
||||
/* SSlice Types in scalable extension */ ;
|
||||
/* SSlice Types in scalable extension */
|
||||
enum ESliceTypeExt {
|
||||
EP_SLICE = 0, // EP_SLICE: 0, 5
|
||||
EB_SLICE = 1, // EB_SLICE: 1, 6
|
||||
|
||||
@@ -58,6 +58,9 @@
|
||||
#ifdef ANDROID_NDK
|
||||
#include <cpu-features.h>
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
#include <android/api-level.h>
|
||||
#endif
|
||||
|
||||
#include "WelsThreadLib.h"
|
||||
#include <stdio.h>
|
||||
@@ -195,6 +198,12 @@ WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_
|
||||
return WELS_THREAD_ERROR_OK;
|
||||
}
|
||||
|
||||
WELS_THREAD_ERROR_CODE WelsThreadSetName (const char* thread_name) {
|
||||
// do nothing
|
||||
return WELS_THREAD_ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
|
||||
WaitForSingleObject (thread, INFINITE);
|
||||
CloseHandle (thread);
|
||||
@@ -242,6 +251,17 @@ WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_
|
||||
return err;
|
||||
}
|
||||
|
||||
WELS_THREAD_ERROR_CODE WelsThreadSetName (const char* thread_name) {
|
||||
#ifdef APPLE_IOS
|
||||
pthread_setname_np(thread_name);
|
||||
#endif
|
||||
#if defined(__ANDROID__) && __ANDROID_API__ >= 9
|
||||
pthread_setname_np(pthread_self(), thread_name);
|
||||
#endif
|
||||
// do nothing
|
||||
return WELS_THREAD_ERROR_OK;
|
||||
}
|
||||
|
||||
WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
|
||||
return pthread_join (thread, NULL);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* \copy
|
||||
* Copyright (c) 2013, Cisco Systems
|
||||
* Copyright (c) 2009-2013, Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -28,12 +28,21 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* \file get_intra_predictor.c
|
||||
*
|
||||
* \brief implementation for get intra predictor about 16x16, 4x4, chroma.
|
||||
*
|
||||
* \date 4/2/2009 Created
|
||||
* 9/14/2009 C level based optimization with high performance gained.
|
||||
* [const, using ST32/ST64 to replace memset, memcpy and memmove etc.]
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "ls_defines.h"
|
||||
#include "cpu_core.h"
|
||||
#include "intra_pred_common.h"
|
||||
|
||||
WELSVP_NAMESPACE_BEGIN
|
||||
|
||||
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
|
||||
uint8_t i = 15;
|
||||
@@ -66,4 +75,3 @@ void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStrid
|
||||
} while (i-- > 0);
|
||||
}
|
||||
|
||||
WELSVP_NAMESPACE_END
|
||||
@@ -68,7 +68,7 @@ void WelsLog (SLogContext* logCtx, int32_t iLevel, const char* kpFmt, ...) {
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] Detail:");
|
||||
break;
|
||||
}
|
||||
WelsStrcat(pTraceTag,MAX_LOG_SIZE,kpFmt);
|
||||
WelsStrcat (pTraceTag, MAX_LOG_SIZE, kpFmt);
|
||||
va_start (vl, kpFmt);
|
||||
logCtx->pfLog (logCtx->pLogCtx, iLevel, pTraceTag, vl);
|
||||
va_end (vl);
|
||||
|
||||
@@ -78,8 +78,9 @@ void welsCodecTrace::CodecTrace (const int32_t iLevel, const char* Str_Format, v
|
||||
|
||||
char pBuf[MAX_LOG_SIZE] = {0};
|
||||
WelsVsnprintf (pBuf, MAX_LOG_SIZE, Str_Format, vl); // confirmed_safe_unsafe_usage
|
||||
|
||||
m_fpTrace (m_pTraceCtx, iLevel, pBuf);
|
||||
if (m_fpTrace) {
|
||||
m_fpTrace (m_pTraceCtx, iLevel, pBuf);
|
||||
}
|
||||
}
|
||||
|
||||
void welsCodecTrace::SetTraceLevel (const int32_t iLevel) {
|
||||
|
||||
@@ -6,6 +6,7 @@ COMMON_CPP_SRCS=\
|
||||
$(COMMON_SRCDIR)/src/crt_util_safe_x.cpp\
|
||||
$(COMMON_SRCDIR)/src/deblocking_common.cpp\
|
||||
$(COMMON_SRCDIR)/src/expand_pic.cpp\
|
||||
$(COMMON_SRCDIR)/src/intra_pred_common.cpp\
|
||||
$(COMMON_SRCDIR)/src/sad_common.cpp\
|
||||
$(COMMON_SRCDIR)/src/utils.cpp\
|
||||
$(COMMON_SRCDIR)/src/welsCodecTrace.cpp\
|
||||
@@ -13,41 +14,51 @@ COMMON_CPP_SRCS=\
|
||||
|
||||
COMMON_OBJS += $(COMMON_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
COMMON_ASM_SRCS=\
|
||||
$(COMMON_SRCDIR)/x86/cpuid.asm\
|
||||
$(COMMON_SRCDIR)/x86/deblock.asm\
|
||||
$(COMMON_SRCDIR)/x86/expand_picture.asm\
|
||||
$(COMMON_SRCDIR)/x86/intra_pred_com.asm\
|
||||
$(COMMON_SRCDIR)/x86/mb_copy.asm\
|
||||
$(COMMON_SRCDIR)/x86/mc_chroma.asm\
|
||||
$(COMMON_SRCDIR)/x86/mc_luma.asm\
|
||||
$(COMMON_SRCDIR)/x86/satd_sad.asm\
|
||||
$(COMMON_SRCDIR)/x86/vaa.asm\
|
||||
|
||||
COMMON_OBJS += $(COMMON_ASM_SRCS:.asm=.$(OBJ))
|
||||
COMMON_OBJSASM += $(COMMON_ASM_SRCS:.asm=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
COMMON_OBJS += $(COMMON_OBJSASM)
|
||||
endif
|
||||
OBJS += $(COMMON_OBJSASM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
COMMON_ASM_ARM_SRCS=\
|
||||
$(COMMON_SRCDIR)/arm/copy_mb_neon.S\
|
||||
$(COMMON_SRCDIR)/arm/deblocking_neon.S\
|
||||
$(COMMON_SRCDIR)/arm/expand_picture_neon.S\
|
||||
$(COMMON_SRCDIR)/arm/intra_pred_common_neon.S\
|
||||
$(COMMON_SRCDIR)/arm/mc_neon.S\
|
||||
|
||||
COMMON_OBJS += $(COMMON_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
COMMON_OBJSARM += $(COMMON_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
COMMON_OBJS += $(COMMON_OBJSARM)
|
||||
endif
|
||||
OBJS += $(COMMON_OBJSARM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
COMMON_ASM_ARM64_SRCS=\
|
||||
$(COMMON_SRCDIR)/arm64/copy_mb_aarch64_neon.S\
|
||||
$(COMMON_SRCDIR)/arm64/deblocking_aarch64_neon.S\
|
||||
$(COMMON_SRCDIR)/arm64/expand_picture_aarch64_neon.S\
|
||||
$(COMMON_SRCDIR)/arm64/intra_pred_common_aarch64_neon.S\
|
||||
$(COMMON_SRCDIR)/arm64/mc_aarch64_neon.S\
|
||||
|
||||
COMMON_OBJS += $(COMMON_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
COMMON_OBJSARM64 += $(COMMON_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
COMMON_OBJS += $(COMMON_OBJSARM64)
|
||||
endif
|
||||
OBJS += $(COMMON_OBJSARM64)
|
||||
|
||||
OBJS += $(COMMON_OBJS)
|
||||
|
||||
$(COMMON_SRCDIR)/%.$(OBJ): $(COMMON_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(COMMON_CFLAGS) $(COMMON_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
117
codec/common/x86/intra_pred_com.asm
Normal file
117
codec/common/x86/intra_pred_com.asm
Normal file
@@ -0,0 +1,117 @@
|
||||
;*!
|
||||
;* \copy
|
||||
;* Copyright (c) 2009-2013, Cisco Systems
|
||||
;* All rights reserved.
|
||||
;*
|
||||
;* 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 HOLDER 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.
|
||||
;*
|
||||
;*
|
||||
;* intra_pred_common.asm
|
||||
;*
|
||||
;* Abstract
|
||||
;* sse2 function for intra predict operations
|
||||
;*
|
||||
;* History
|
||||
;* 18/09/2009 Created
|
||||
;*
|
||||
;*
|
||||
;*************************************************************************/
|
||||
%include "asm_inc.asm"
|
||||
|
||||
;***********************************************************************
|
||||
; Code
|
||||
;***********************************************************************
|
||||
|
||||
SECTION .text
|
||||
|
||||
;***********************************************************************
|
||||
; void WelsI16x16LumaPredH_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
|
||||
;***********************************************************************
|
||||
|
||||
%macro SSE2_PRED_H_16X16_ONE_LINE 0
|
||||
add r0, 16
|
||||
add r1, r2
|
||||
movzx r3, byte [r1]
|
||||
SSE2_Copy16Times xmm0, r3d
|
||||
movdqa [r0], xmm0
|
||||
%endmacro
|
||||
|
||||
WELS_EXTERN WelsI16x16LumaPredH_sse2
|
||||
push r3
|
||||
%assign push_num 1
|
||||
LOAD_3_PARA
|
||||
SIGN_EXTENSION r2, r2d
|
||||
dec r1
|
||||
movzx r3, byte [r1]
|
||||
SSE2_Copy16Times xmm0, r3d
|
||||
movdqa [r0], xmm0
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
pop r3
|
||||
ret
|
||||
|
||||
;***********************************************************************
|
||||
; void WelsI16x16LumaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
|
||||
;***********************************************************************
|
||||
WELS_EXTERN WelsI16x16LumaPredV_sse2
|
||||
%assign push_num 0
|
||||
LOAD_3_PARA
|
||||
SIGN_EXTENSION r2, r2d
|
||||
sub r1, r2
|
||||
movdqa xmm0, [r1]
|
||||
|
||||
movdqa [r0], xmm0
|
||||
movdqa [r0+10h], xmm0
|
||||
movdqa [r0+20h], xmm0
|
||||
movdqa [r0+30h], xmm0
|
||||
movdqa [r0+40h], xmm0
|
||||
movdqa [r0+50h], xmm0
|
||||
movdqa [r0+60h], xmm0
|
||||
movdqa [r0+70h], xmm0
|
||||
movdqa [r0+80h], xmm0
|
||||
movdqa [r0+90h], xmm0
|
||||
movdqa [r0+160], xmm0
|
||||
movdqa [r0+176], xmm0
|
||||
movdqa [r0+192], xmm0
|
||||
movdqa [r0+208], xmm0
|
||||
movdqa [r0+224], xmm0
|
||||
movdqa [r0+240], xmm0
|
||||
|
||||
ret
|
||||
|
||||
@@ -42,26 +42,25 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
|
||||
class CReadConfig {
|
||||
public:
|
||||
CReadConfig();
|
||||
CReadConfig (const char* pConfigFileName);
|
||||
CReadConfig (const string& pConfigFileName);
|
||||
CReadConfig (const std::string& pConfigFileName);
|
||||
virtual ~CReadConfig();
|
||||
|
||||
void Openf (const char* strFile);
|
||||
long ReadLine (string* strVal, const int iValSize = 4);
|
||||
long ReadLine (std::string* strVal, const int iValSize = 4);
|
||||
const bool EndOfFile();
|
||||
const int GetLines();
|
||||
const bool ExistFile();
|
||||
const string& GetFileName();
|
||||
const std::string& GetFileName();
|
||||
|
||||
private:
|
||||
FILE* m_pCfgFile;
|
||||
string m_strCfgFileName;
|
||||
std::string m_strCfgFileName;
|
||||
unsigned int m_iLines;
|
||||
};
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ CReadConfig::CReadConfig (const char* kpConfigFileName)
|
||||
}
|
||||
}
|
||||
|
||||
CReadConfig::CReadConfig (const string& kpConfigFileName)
|
||||
CReadConfig::CReadConfig (const std::string& kpConfigFileName)
|
||||
: m_pCfgFile (0)
|
||||
, m_strCfgFileName (kpConfigFileName)
|
||||
, m_iLines (0) {
|
||||
@@ -81,11 +81,11 @@ void CReadConfig::Openf (const char* kpStrFile) {
|
||||
}
|
||||
}
|
||||
|
||||
long CReadConfig::ReadLine (string* pVal, const int kiValSize/* = 4*/) {
|
||||
long CReadConfig::ReadLine (std::string* pVal, const int kiValSize/* = 4*/) {
|
||||
if (m_pCfgFile == NULL || pVal == NULL || kiValSize <= 1)
|
||||
return 0;
|
||||
|
||||
string* strTags = &pVal[0];
|
||||
std::string* strTags = &pVal[0];
|
||||
int nTagNum = 0, n = 0;
|
||||
bool bCommentFlag = false;
|
||||
|
||||
@@ -134,6 +134,6 @@ const bool CReadConfig::ExistFile() {
|
||||
return (m_pCfgFile != NULL);
|
||||
}
|
||||
|
||||
const string& CReadConfig::GetFileName() {
|
||||
const std::string& CReadConfig::GetFileName() {
|
||||
return m_strCfgFileName;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ CONSOLE_COMMON_CPP_SRCS=\
|
||||
CONSOLE_COMMON_OBJS += $(CONSOLE_COMMON_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
OBJS += $(CONSOLE_COMMON_OBJS)
|
||||
|
||||
$(CONSOLE_COMMON_SRCDIR)/%.$(OBJ): $(CONSOLE_COMMON_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(CONSOLE_COMMON_CFLAGS) $(CONSOLE_COMMON_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ H264DEC_CPP_SRCS=\
|
||||
H264DEC_OBJS += $(H264DEC_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
OBJS += $(H264DEC_OBJS)
|
||||
|
||||
$(H264DEC_SRCDIR)/%.$(OBJ): $(H264DEC_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(H264DEC_CFLAGS) $(H264DEC_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -294,6 +294,8 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
|
||||
pSvcParam.iLTRRefNum = atoi (strTag[1].c_str());
|
||||
} else if (strTag[0].compare ("LtrMarkPeriod") == 0) {
|
||||
pSvcParam.iLtrMarkPeriod = (uint32_t)atoi (strTag[1].c_str());
|
||||
} else if (strTag[0].compare ("LosslessLink") == 0) {
|
||||
pSvcParam.bIsLosslessLink = atoi (strTag[1].c_str()) ? true : false;
|
||||
} else if (strTag[0].compare ("NumLayers") == 0) {
|
||||
pSvcParam.iSpatialLayerNum = (int8_t)atoi (strTag[1].c_str());
|
||||
if (pSvcParam.iSpatialLayerNum > MAX_DEPENDENCY_LAYER || pSvcParam.iSpatialLayerNum <= 0) {
|
||||
@@ -382,7 +384,7 @@ void PrintHelp() {
|
||||
|
||||
int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamExt& pSvcParam, SFilesSet& sFileSet) {
|
||||
char* pCommand = NULL;
|
||||
SLayerPEncCtx sLayerCtx[3];
|
||||
SLayerPEncCtx sLayerCtx[MAX_SPATIAL_LAYER_NUM];
|
||||
int n = 0;
|
||||
string str_ ("SlicesAssign");
|
||||
|
||||
@@ -805,10 +807,10 @@ int ProcessEncoding (ISVCEncoder* pPtrEnc, int argc, char** argv, bool bConfigFi
|
||||
break;
|
||||
// To encoder this frame
|
||||
iStart = WelsTime();
|
||||
pSrcPic->uiTimeStamp = WELS_ROUND (iFrameIdx * (1000 / sSvcParam.fMaxFrameRate));
|
||||
int iEncFrames = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
|
||||
iTotal += WelsTime() - iStart;
|
||||
|
||||
// fixed issue in case dismatch source picture introduced by frame skipped, 1/12/2010
|
||||
++ iFrameIdx;
|
||||
if (videoFrameTypeSkip == sFbi.eFrameType) {
|
||||
continue;
|
||||
}
|
||||
@@ -859,7 +861,6 @@ int ProcessEncoding (ISVCEncoder* pPtrEnc, int argc, char** argv, bool bConfigFi
|
||||
fprintf (stderr, "EncodeFrame(), ret: %d, frame index: %d.\n", iEncFrames, iFrameIdx);
|
||||
}
|
||||
|
||||
++ iFrameIdx;
|
||||
}
|
||||
|
||||
if (iActualFrameEncodedCount > 0) {
|
||||
@@ -891,7 +892,7 @@ INSIDE_MEM_FREE:
|
||||
pFileYUV = NULL;
|
||||
}
|
||||
if (pYUV) {
|
||||
delete pYUV;
|
||||
delete[] pYUV;
|
||||
pYUV = NULL;
|
||||
}
|
||||
if (pSrcPic) {
|
||||
|
||||
@@ -5,6 +5,7 @@ H264ENC_CPP_SRCS=\
|
||||
H264ENC_OBJS += $(H264ENC_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
OBJS += $(H264ENC_OBJS)
|
||||
|
||||
$(H264ENC_SRCDIR)/%.$(OBJ): $(H264ENC_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(H264ENC_CFLAGS) $(H264ENC_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -316,7 +316,6 @@ int32_t iFeedbackVclNalInAu;
|
||||
int32_t iFeedbackTidInAu;
|
||||
|
||||
bool bAuReadyFlag; // true: one au is ready for decoding; false: default value
|
||||
bool bDecErrorConedFlag; //true: current decoder is error coned
|
||||
|
||||
bool bPrintFrameErrorTraceFlag; //true: can print info for upper layer
|
||||
int32_t iIgnoredErrorInfoPacketCount; //store the packet number with error decoding info
|
||||
|
||||
@@ -144,8 +144,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
/*
|
||||
* Check if frame is completed and EC is required
|
||||
*/
|
||||
bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** pDst, SBufferInfo* pDstInfo);
|
||||
|
||||
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** pDst, SBufferInfo* pDstInfo);
|
||||
/*
|
||||
* Prepare current dq layer context initialization.
|
||||
*/
|
||||
@@ -158,6 +157,7 @@ void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
|
||||
void ForceResetCurrentAccessUnit (PAccessUnit pAu);
|
||||
void ForceClearCurrentNal (PAccessUnit pAu);
|
||||
|
||||
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx); // Check whether all ref pictures are complete
|
||||
} // namespace WelsDec
|
||||
|
||||
#endif//WELS_DECODER_CORE_H__
|
||||
|
||||
@@ -48,7 +48,7 @@ ERR_INVALID_PARAMETERS = 1,
|
||||
ERR_MALLOC_FAILED = 2,
|
||||
ERR_API_FAILED = 3,
|
||||
|
||||
ERR_BOUND = 31,
|
||||
ERR_BOUND = 31
|
||||
} EWelsErr;
|
||||
|
||||
/*
|
||||
@@ -68,7 +68,7 @@ ERR_LEVEL_PREFIX_NAL,
|
||||
ERR_LEVEL_PARAM_SETS,
|
||||
ERR_LEVEL_SLICE_HEADER,
|
||||
ERR_LEVEL_SLICE_DATA,
|
||||
ERR_LEVEL_MB_DATA,
|
||||
ERR_LEVEL_MB_DATA
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
@@ -180,7 +180,7 @@ EER_INFO_INVALID_MMCO_LONG2UNUSED,
|
||||
ERR_INFO_INVALID_MMCO_SHOART2LONG,
|
||||
ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW,
|
||||
ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH,
|
||||
ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX,
|
||||
ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX
|
||||
};
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ bool bIsLongRef; // long term reference frame flag //for ref pic management
|
||||
uint8_t uiRefCount;
|
||||
bool bAvailableFlag; // indicate whether it is available in this picture memory block.
|
||||
|
||||
bool bIsComplete; // indicate whether current picture is complete, not from EC
|
||||
/*******************************for future use****************************/
|
||||
uint8_t uiTemporalId;
|
||||
uint8_t uiSpatialId;
|
||||
|
||||
@@ -60,7 +60,7 @@ PRO_HIGH444 = 144,
|
||||
PRO_CAVLC444 = 244,
|
||||
|
||||
PRO_SCALABLE_BASELINE = 83,
|
||||
PRO_SCALABLE_HIGH = 86,
|
||||
PRO_SCALABLE_HIGH = 86
|
||||
};
|
||||
|
||||
/* Picture Size */
|
||||
@@ -83,7 +83,7 @@ MB_LEFT = 0x01, // A
|
||||
MB_TOP = 0x02, // B
|
||||
MB_TOPRIGHT = 0x04, // C
|
||||
MB_TOPLEFT = 0x08, // D,
|
||||
MB_PRIVATE = 0x10,
|
||||
MB_PRIVATE = 0x10
|
||||
};
|
||||
/* MB Type & Sub-MB Type */
|
||||
typedef int32_t MbType;
|
||||
|
||||
@@ -419,7 +419,7 @@ int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNal
|
||||
}
|
||||
if (iUsedBits > pBs->iBits) { //When BS incomplete, as long as find it, SHOULD stop decoding to avoid mosaic or crash.
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
|
||||
"WelsDecodeSlice()::::pBs incomplete, iUsedBits:%"PRId64" > pBs->iBits:%d, MUST stop decoding.",
|
||||
"WelsDecodeSlice()::::pBs incomplete, iUsedBits:%" PRId64" > pBs->iBits:%d, MUST stop decoding.",
|
||||
(int64_t) iUsedBits, pBs->iBits);
|
||||
return -1;
|
||||
}
|
||||
@@ -1065,9 +1065,9 @@ void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NEON_AARCH64
|
||||
if (iCpu & WELS_CPU_NEON) {
|
||||
pFunc->pWelsSetNonZeroCountFunc = SetNonZeroCount_AArch64_neon;
|
||||
}
|
||||
if (iCpu & WELS_CPU_NEON) {
|
||||
pFunc->pWelsSetNonZeroCountFunc = SetNonZeroCount_AArch64_neon;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -273,10 +273,12 @@ void WelsFreeMem (PWelsDecoderContext pCtx) {
|
||||
/*!
|
||||
* \brief Open decoder
|
||||
*/
|
||||
void WelsOpenDecoder (PWelsDecoderContext pCtx) {
|
||||
int32_t WelsOpenDecoder (PWelsDecoderContext pCtx) {
|
||||
// function pointers
|
||||
//initial MC function pointer--
|
||||
int iRet = ERR_NONE;
|
||||
InitMcFunc (& (pCtx->sMcFunc), pCtx->uiCpuFlag);
|
||||
InitErrorCon (pCtx);
|
||||
|
||||
InitExpandPictureFunc (& (pCtx->sExpandPicFunc), pCtx->uiCpuFlag);
|
||||
AssignFuncPointerForRec (pCtx);
|
||||
@@ -285,8 +287,9 @@ void WelsOpenDecoder (PWelsDecoderContext pCtx) {
|
||||
InitVlcTable (&pCtx->sVlcTable);
|
||||
|
||||
// startup memory
|
||||
if (ERR_NONE != WelsInitMemory (pCtx))
|
||||
return;
|
||||
iRet = WelsInitMemory (pCtx);
|
||||
if (ERR_NONE != iRet)
|
||||
return iRet;
|
||||
|
||||
#ifdef LONG_TERM_REF
|
||||
pCtx->bParamSetsLostFlag = true;
|
||||
@@ -294,9 +297,9 @@ void WelsOpenDecoder (PWelsDecoderContext pCtx) {
|
||||
pCtx->bReferenceLostAtT0Flag = true; // should be true to waiting IDR at incoming AU bits following, 6/4/2010
|
||||
#endif //LONG_TERM_REF
|
||||
pCtx->bNewSeqBegin = true;
|
||||
pCtx->bDecErrorConedFlag = false; //default: decoder normal status
|
||||
pCtx->bPrintFrameErrorTraceFlag = true;
|
||||
pCtx->iIgnoredErrorInfoPacketCount = 0;
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -332,6 +335,9 @@ int32_t DecoderConfigParam (PWelsDecoderContext pCtx, const SDecodingParam* kpPa
|
||||
|
||||
memcpy (pCtx->pParam, kpParam, sizeof (SDecodingParam));
|
||||
pCtx->eOutputColorFormat = pCtx->pParam->eOutputColorFormat;
|
||||
int32_t iRet = DecoderSetCsp (pCtx, pCtx->pParam->eOutputColorFormat);
|
||||
if (iRet)
|
||||
return iRet;
|
||||
pCtx->eErrorConMethod = pCtx->pParam->eEcActiveIdc;
|
||||
|
||||
if (VIDEO_BITSTREAM_SVC == pCtx->pParam->sVideoProperty.eVideoBsType ||
|
||||
@@ -367,10 +373,7 @@ int32_t WelsInitDecoder (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
||||
WelsDecoderDefaults (pCtx, pLogCtx);
|
||||
|
||||
// open decoder
|
||||
WelsOpenDecoder (pCtx);
|
||||
|
||||
|
||||
return ERR_NONE;
|
||||
return WelsOpenDecoder (pCtx);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -462,8 +465,8 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
|
||||
iConsumedBytes = 0;
|
||||
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
||||
if ((pCtx->eErrorConMethod != ERROR_CON_DISABLE) && (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1))) {
|
||||
CheckAndDoEC (pCtx, ppDst, pDstBufInfo);
|
||||
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
|
||||
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
|
||||
}
|
||||
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
|
||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
|
||||
@@ -522,8 +525,8 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
|
||||
iConsumedBytes = 0;
|
||||
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
||||
if ((pCtx->eErrorConMethod != ERROR_CON_DISABLE) && (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1))) {
|
||||
CheckAndDoEC (pCtx, ppDst, pDstBufInfo);
|
||||
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
|
||||
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
|
||||
}
|
||||
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
|
||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
|
||||
@@ -595,9 +598,12 @@ int32_t DecoderSetCsp (PWelsDecoderContext pCtx, const int32_t kiColorFormat) {
|
||||
}
|
||||
|
||||
//For now, support only videoFormatI420!
|
||||
if (kiColorFormat != (int32_t) videoFormatI420) {
|
||||
if (kiColorFormat == (int32_t) videoFormatInternal) {
|
||||
pCtx->pParam->eOutputColorFormat = pCtx->eOutputColorFormat = videoFormatI420;
|
||||
} else if (kiColorFormat != (int32_t) videoFormatI420) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Support I420 output only for now! Change to I420...");
|
||||
pCtx->pParam->eOutputColorFormat = pCtx->eOutputColorFormat = videoFormatI420;
|
||||
return cmUnsupportedData;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -82,7 +82,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
return -1;
|
||||
} else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
|
||||
&& (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
|
||||
pCtx->bDecErrorConedFlag = false;
|
||||
pCtx->pDec->bIsComplete = true;
|
||||
}
|
||||
|
||||
pCtx->iTotalNumMbRec = 0;
|
||||
@@ -104,10 +104,12 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
pDstInfo->iBufferStatus = 1;
|
||||
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete
|
||||
pDstInfo->iBufferStatus = (int32_t) bFrameCompleteFlag;
|
||||
pDstInfo->iBufferStatus = (int32_t) (bFrameCompleteFlag
|
||||
&& pPic->bIsComplete); // When EC disable, ECed picture not output
|
||||
|
||||
if (!bFrameCompleteFlag) {
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
if (pDstInfo->iBufferStatus == 0) {
|
||||
if (!bFrameCompleteFlag)
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -541,7 +543,10 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);
|
||||
}
|
||||
|
||||
pPps = &pCtx->sPpsBuffer[iPpsId];
|
||||
if (pCtx->iOverwriteFlags & OVERWRITE_PPS)
|
||||
pPps = &pCtx->sPpsBuffer[MAX_PPS_COUNT];
|
||||
else
|
||||
pPps = &pCtx->sPpsBuffer[iPpsId];
|
||||
|
||||
if (pPps->uiNumSliceGroups == 0) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
|
||||
@@ -550,7 +555,10 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
}
|
||||
|
||||
if (kbExtensionFlag) {
|
||||
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
|
||||
if (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS)
|
||||
pSubsetSps = &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT];
|
||||
else
|
||||
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
|
||||
pSps = &pSubsetSps->sSps;
|
||||
if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id is invalid!");
|
||||
@@ -563,7 +571,10 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
pCtx->iErrorCode |= dsNoParamSets;
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
|
||||
}
|
||||
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
|
||||
if (pCtx->iOverwriteFlags & OVERWRITE_SPS)
|
||||
pSps = &pCtx->sSpsBuffer[MAX_SPS_COUNT];
|
||||
else
|
||||
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
|
||||
}
|
||||
pSliceHead->iPpsId = iPpsId;
|
||||
pSliceHead->iSpsId = pPps->iSpsId;
|
||||
@@ -1657,7 +1668,6 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr);
|
||||
return iErr;
|
||||
}
|
||||
InitErrorCon (pCtx); //Do EC initialization here, for sequence start
|
||||
}
|
||||
|
||||
|
||||
@@ -1781,6 +1791,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
int32_t iPpsId = 0;
|
||||
int32_t iRet = ERR_NONE;
|
||||
|
||||
bool bAllRefComplete = true; // Assume default all ref picutres are complete
|
||||
|
||||
const uint8_t kuiTargetLayerDqId = GetTargetDqId (pCtx->uiTargetDqId, pCtx->pParam);
|
||||
const uint8_t kuiDependencyIdMax = (kuiTargetLayerDqId & 0x7F) >> 4;
|
||||
int16_t iLastIdD = -1, iLastIdQ = -1;
|
||||
@@ -1890,6 +1902,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
"referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d", pCtx->iPrevFrameNum,
|
||||
pSh->iFrameNum);
|
||||
|
||||
bAllRefComplete = false;
|
||||
pCtx->iErrorCode |= dsRefLost;
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
#ifdef LONG_TERM_REF
|
||||
@@ -1906,6 +1919,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID) {
|
||||
iRet = InitRefPicList (pCtx, uiNalRefIdc, pSh->iPicOrderCntLsb);
|
||||
if (iRet) {
|
||||
bAllRefComplete = false; // RPLR error, set ref pictures complete flag false
|
||||
HandleReferenceLost (pCtx, pNalCur);
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
|
||||
"reference picture introduced by this frame is lost during transmission! uiTId: %d",
|
||||
@@ -1923,6 +1937,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
|
||||
"DecodeCurrentAccessUnit() failed (%d) in frame: %d uiDId: %d uiQId: %d",
|
||||
iRet, pSh->iFrameNum, iCurrIdD, iCurrIdQ);
|
||||
bAllRefComplete = false;
|
||||
HandleReferenceLostL0 (pCtx, pNalCur);
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
return iRet;
|
||||
@@ -1930,9 +1945,13 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
}
|
||||
if (bReconstructSlice) {
|
||||
if (WelsDecodeConstructSlice (pCtx, pNalCur)) {
|
||||
pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (bAllRefComplete && (pCtx->sRefPic.uiRefCount[LIST_0] > 0 || pCtx->eSliceType != I_SLICE)) {
|
||||
bAllRefComplete &= bCheckRefPicturesComplete (pCtx);
|
||||
}
|
||||
}
|
||||
#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
|
||||
fprintf (stderr, "cur_frame : %d iCurrIdD : %d\n ",
|
||||
@@ -1955,6 +1974,12 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the current dec picture complete flag. The flag will be reset when current picture need do ErrorCon.
|
||||
pCtx->pDec->bIsComplete = bAllRefComplete;
|
||||
if (!pCtx->pDec->bIsComplete) { // Ref pictures ECed, result in ECed
|
||||
pCtx->iErrorCode |= dsDataErrorConcealed;
|
||||
}
|
||||
|
||||
// A dq layer decoded here
|
||||
#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
|
||||
#undef fprintf
|
||||
@@ -1966,9 +1991,11 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
if (dq_cur->uiLayerDqId == kuiTargetLayerDqId) {
|
||||
if (!pCtx->bInstantDecFlag) {
|
||||
//Do error concealment here
|
||||
if (NeedErrorCon (pCtx)) {
|
||||
if ((NeedErrorCon (pCtx)) && (pCtx->eErrorConMethod != ERROR_CON_DISABLE)) {
|
||||
ImplementErrorCon (pCtx);
|
||||
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
||||
pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
|
||||
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2001,7 +2028,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
PAccessUnit pAu = pCtx->pAccessUnitList;
|
||||
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
|
||||
if ((pCtx->iTotalNumMbRec != 0)
|
||||
@@ -2009,12 +2036,20 @@ bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstI
|
||||
&pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader))) {
|
||||
//Do Error Concealment here
|
||||
if (NeedErrorCon (pCtx)) { //should always be true!
|
||||
ImplementErrorCon (pCtx);
|
||||
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
||||
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
|
||||
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
|
||||
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
|
||||
MarkECFrameAsRef (pCtx);
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
ImplementErrorCon (pCtx);
|
||||
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
||||
pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
|
||||
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
|
||||
|
||||
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
|
||||
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
|
||||
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
|
||||
MarkECFrameAsRef (pCtx);
|
||||
}
|
||||
} else {
|
||||
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo))
|
||||
return false;
|
||||
}
|
||||
pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
|
||||
if (pCtx->bLastHasMmco5)
|
||||
@@ -2024,4 +2059,41 @@ bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstI
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx) {
|
||||
// Multi Reference, RefIdx may differ
|
||||
bool bAllRefComplete = true;
|
||||
int32_t iRealMbIdx;
|
||||
for (int32_t iMbIdx = 0; bAllRefComplete
|
||||
&& iMbIdx < pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.iTotalMbInCurSlice; iMbIdx++) {
|
||||
iRealMbIdx = pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice + iMbIdx;
|
||||
switch (pCtx->pCurDqLayer->pMbType[iRealMbIdx]) {
|
||||
case MB_TYPE_SKIP:
|
||||
case MB_TYPE_16x16:
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
|
||||
break;
|
||||
|
||||
case MB_TYPE_16x8:
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
|
||||
break;
|
||||
|
||||
case MB_TYPE_8x16:
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
|
||||
break;
|
||||
|
||||
case MB_TYPE_8x8:
|
||||
case MB_TYPE_8x8_REF0:
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
|
||||
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][10] ]->bIsComplete;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bAllRefComplete;
|
||||
}
|
||||
} // namespace WelsDec
|
||||
|
||||
@@ -189,7 +189,7 @@ void ImplementErrorCon (PWelsDecoderContext pCtx) {
|
||||
DoErrorConSliceCopy (pCtx);
|
||||
} //TODO add other EC methods here in the future
|
||||
pCtx->iErrorCode |= dsDataErrorConcealed;
|
||||
pCtx->bDecErrorConedFlag = true;
|
||||
pCtx->pDec->bIsComplete = false; // Set complete flag to false after do EC.
|
||||
}
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
@@ -73,6 +73,7 @@ static void SetUnRef (PPicture pRef) {
|
||||
pRef->uiTemporalId = -1;
|
||||
pRef->uiSpatialId = -1;
|
||||
pRef->iSpsId = -1;
|
||||
pRef->bIsComplete = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +116,9 @@ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
|
||||
PPicture pRef = PrefetchPic (pCtx->pPicBuff[0]);
|
||||
if (pRef != NULL) {
|
||||
// IDR lost, set new
|
||||
pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
|
||||
pCtx->iErrorCode |= dsDataErrorConcealed;
|
||||
memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
|
||||
memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
|
||||
memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
|
||||
|
||||
@@ -85,6 +85,9 @@ virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* kpSrc,
|
||||
const int kiSrcLen,
|
||||
unsigned char** ppDst,
|
||||
SBufferInfo* pDstInfo);
|
||||
virtual DECODING_STATE EXTAPI DecodeParser (const unsigned char* kpSrc,
|
||||
const int kiSrcLen,
|
||||
SParserBsInfo* pDstInfo);
|
||||
virtual DECODING_STATE EXTAPI DecodeFrameEx (const unsigned char* kpSrc,
|
||||
const int kiSrcLen,
|
||||
unsigned char* pDst,
|
||||
@@ -101,7 +104,7 @@ virtual long EXTAPI GetOption (DECODER_OPTION eOptID, void* pOption);
|
||||
PWelsDecoderContext m_pDecContext;
|
||||
welsCodecTrace* m_pWelsTrace;
|
||||
|
||||
void InitDecoder (void);
|
||||
int32_t InitDecoder (void);
|
||||
void UninitDecoder (void);
|
||||
|
||||
#ifdef OUTPUT_BIT_STREAM
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
//#include "macros.h"
|
||||
#include "decoder.h"
|
||||
#include "decoder_core.h"
|
||||
#include "error_concealment.h"
|
||||
|
||||
extern "C" {
|
||||
#include "decoder_core.h"
|
||||
@@ -184,6 +185,7 @@ CWelsDecoder::~CWelsDecoder() {
|
||||
}
|
||||
|
||||
long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
|
||||
int iRet = ERR_NONE;
|
||||
if (m_pWelsTrace == NULL) {
|
||||
return cmMallocMemeError;
|
||||
}
|
||||
@@ -194,9 +196,13 @@ long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
|
||||
}
|
||||
|
||||
// H.264 decoder initialization,including memory allocation,then open it ready to decode
|
||||
InitDecoder();
|
||||
iRet = InitDecoder();
|
||||
if (iRet)
|
||||
return iRet;
|
||||
|
||||
DecoderConfigParam (m_pDecContext, pParam);
|
||||
iRet = DecoderConfigParam (m_pDecContext, pParam);
|
||||
if (iRet)
|
||||
return iRet;
|
||||
|
||||
return cmResultSuccess;
|
||||
}
|
||||
@@ -225,15 +231,16 @@ void CWelsDecoder::UninitDecoder (void) {
|
||||
}
|
||||
|
||||
// the return value of this function is not suitable, it need report failure info to upper layer.
|
||||
void CWelsDecoder::InitDecoder (void) {
|
||||
int32_t CWelsDecoder::InitDecoder (void) {
|
||||
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::init_decoder(), openh264 codec version = %s",
|
||||
VERSION_NUMBER);
|
||||
|
||||
m_pDecContext = (PWelsDecoderContext)WelsMalloc (sizeof (SWelsDecoderContext), "m_pDecContext");
|
||||
if (NULL == m_pDecContext)
|
||||
return cmMallocMemeError;
|
||||
|
||||
WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
|
||||
|
||||
return WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -263,11 +270,16 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
|
||||
|
||||
return cmResultSuccess;
|
||||
} else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
|
||||
if (pOption == NULL) //Default: SLICE_COPY, enable
|
||||
iVal = ERROR_CON_SLICE_COPY;
|
||||
else
|
||||
iVal = * ((int*)pOption); //EC method
|
||||
if (pOption == NULL)
|
||||
return cmInitParaError;
|
||||
|
||||
iVal = * ((int*)pOption); // int value for error concealment idc
|
||||
iVal = WELS_CLIP3 (iVal, (int32_t) ERROR_CON_DISABLE, (int32_t) ERROR_CON_SLICE_COPY);
|
||||
m_pDecContext->eErrorConMethod = (ERROR_CON_IDC) iVal;
|
||||
InitErrorCon (m_pDecContext);
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||
"CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
|
||||
|
||||
return cmResultSuccess;
|
||||
} else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
|
||||
if (m_pWelsTrace) {
|
||||
@@ -424,17 +436,24 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
m_pDecContext->iIgnoredErrorInfoPacketCount = 0;
|
||||
}
|
||||
}
|
||||
return (DECODING_STATE)m_pDecContext->iErrorCode;
|
||||
} else { //decoding correct, but may have ECed status
|
||||
if (m_pDecContext->bDecErrorConedFlag) {
|
||||
if ((m_pDecContext->eErrorConMethod != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
|
||||
//TODO after dec status updated
|
||||
m_pDecContext->iErrorCode |= dsDataErrorConcealed;
|
||||
return dsDataErrorConcealed;
|
||||
}
|
||||
return (DECODING_STATE) m_pDecContext->iErrorCode;
|
||||
}
|
||||
// else Error free, the current codec works well
|
||||
|
||||
return dsErrorFree;
|
||||
}
|
||||
|
||||
DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
|
||||
const int kiSrcLen,
|
||||
SParserBsInfo* pDstInfo) {
|
||||
//TODO, add function here
|
||||
return (DECODING_STATE) m_pDecContext->iErrorCode;
|
||||
}
|
||||
|
||||
DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
|
||||
const int kiSrcLen,
|
||||
unsigned char** ppDst,
|
||||
|
||||
@@ -23,31 +23,38 @@ DECODER_CPP_SRCS=\
|
||||
|
||||
DECODER_OBJS += $(DECODER_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
DECODER_ASM_SRCS=\
|
||||
$(DECODER_SRCDIR)/core/x86/dct.asm\
|
||||
$(DECODER_SRCDIR)/core/x86/intra_pred.asm\
|
||||
|
||||
DECODER_OBJS += $(DECODER_ASM_SRCS:.asm=.$(OBJ))
|
||||
DECODER_OBJSASM += $(DECODER_ASM_SRCS:.asm=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
DECODER_OBJS += $(DECODER_OBJSASM)
|
||||
endif
|
||||
OBJS += $(DECODER_OBJSASM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
DECODER_ASM_ARM_SRCS=\
|
||||
$(DECODER_SRCDIR)/core/arm/block_add_neon.S\
|
||||
$(DECODER_SRCDIR)/core/arm/intra_pred_neon.S\
|
||||
|
||||
DECODER_OBJS += $(DECODER_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
DECODER_OBJSARM += $(DECODER_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
DECODER_OBJS += $(DECODER_OBJSARM)
|
||||
endif
|
||||
OBJS += $(DECODER_OBJSARM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
DECODER_ASM_ARM64_SRCS=\
|
||||
$(DECODER_SRCDIR)/core/arm64/block_add_aarch64_neon.S\
|
||||
$(DECODER_SRCDIR)/core/arm64/intra_pred_aarch64_neon.S\
|
||||
|
||||
DECODER_OBJS += $(DECODER_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
DECODER_OBJSARM64 += $(DECODER_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
DECODER_OBJS += $(DECODER_OBJSARM64)
|
||||
endif
|
||||
OBJS += $(DECODER_OBJSARM64)
|
||||
|
||||
OBJS += $(DECODER_OBJS)
|
||||
|
||||
$(DECODER_SRCDIR)/%.$(OBJ): $(DECODER_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(DECODER_CFLAGS) $(DECODER_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -62,51 +62,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredV_neon
|
||||
//Get the top line data to 'q0'
|
||||
sub r3, r1, r2
|
||||
vldm r3, {d0, d1}
|
||||
|
||||
//mov r2, #16
|
||||
mov r3, #4
|
||||
//Set the top line to the each line of MB(16*16)
|
||||
loop_0_get_i16x16_luma_pred_v:
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
subs r3, #1
|
||||
bne loop_0_get_i16x16_luma_pred_v
|
||||
WELS_ASM_FUNC_END
|
||||
|
||||
|
||||
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredH_neon
|
||||
//stmdb sp!, {r4, lr}
|
||||
sub r1, r1, #1
|
||||
mov r3, #4
|
||||
loop_0_get_i16x16_luma_pred_h:
|
||||
//Get one byte data from left side
|
||||
vld1.8 {d0[],d1[]}, [r1], r2
|
||||
vld1.8 {d2[],d3[]}, [r1], r2
|
||||
vld1.8 {d4[],d5[]}, [r1], r2
|
||||
vld1.8 {d6[],d7[]}, [r1], r2
|
||||
|
||||
//Set the line of MB using the left side byte data
|
||||
vst1.8 {d0,d1}, [r0]!
|
||||
//add r0, #16
|
||||
vst1.8 {d2,d3}, [r0]!
|
||||
//add r0, #16
|
||||
vst1.8 {d4,d5}, [r0]!
|
||||
//add r0, #16
|
||||
vst1.8 {d6,d7}, [r0]!
|
||||
//add r0, #16
|
||||
|
||||
subs r3, #1
|
||||
bne loop_0_get_i16x16_luma_pred_h
|
||||
|
||||
WELS_ASM_FUNC_END
|
||||
|
||||
|
||||
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredDc_neon
|
||||
//stmdb sp!, { r2-r5, lr}
|
||||
//Get the left vertical line data
|
||||
|
||||
@@ -349,23 +349,6 @@ WELS_ASM_AARCH64_FUNC_BEGIN WelsIChromaPredPlane_AArch64_neon
|
||||
.endr
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
|
||||
//for Luma 16x16
|
||||
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredV_AArch64_neon
|
||||
sub x3, x1, x2
|
||||
ld1 {v0.16b}, [x3]
|
||||
.rept 16
|
||||
st1 {v0.16b}, [x0], 16
|
||||
.endr
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
|
||||
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredH_AArch64_neon
|
||||
sub x3, x1, #1
|
||||
.rept 16
|
||||
ld1r {v0.16b}, [x3], x2
|
||||
st1 {v0.16b}, [x0], 16
|
||||
.endr
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
|
||||
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredDc_AArch64_neon
|
||||
sub x3, x1, x2
|
||||
sub x4, x1, #1
|
||||
|
||||
@@ -216,6 +216,12 @@ typedef struct TagWelsEncCtx {
|
||||
SStatSliceInfo sPerInfo;
|
||||
#endif//STAT_OUTPUT
|
||||
|
||||
//related to Statistics
|
||||
int64_t uiStartTimestamp;
|
||||
SEncoderStatistics sEncoderStatistics;
|
||||
int32_t iStatisticsLogInterval;
|
||||
int64_t iLastStatisticsLogTs;
|
||||
|
||||
int32_t iEncoderError;
|
||||
WELS_MUTEX mutexEncoderError;
|
||||
bool bDeliveryFlag;
|
||||
|
||||
@@ -108,7 +108,7 @@ int32_t ForceCodingIDR (sWelsEncCtx* pCtx);
|
||||
int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNew);
|
||||
void WelsEncoderApplyFrameRate (SWelsSvcCodingParam* pParam);
|
||||
void WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iLayer);
|
||||
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue);
|
||||
int32_t WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue);
|
||||
int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRecoverRequest);
|
||||
|
||||
void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarkingFeedback);
|
||||
|
||||
@@ -74,8 +74,6 @@ void WelsIChromaPredDcNA_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStrid
|
||||
void WelsI16x16ChromaPredVer (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16ChromaPredHor (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
|
||||
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredPlane_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredDc_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredDcLeft_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
@@ -94,8 +92,6 @@ void WelsFillingPred8x2to16_sse2 (uint8_t* pPred, uint8_t* pValue);
|
||||
void WelsFillingPred1to16_sse2 (uint8_t* pPred, const uint8_t kuiValue);
|
||||
|
||||
//for intra-prediction ASM functions
|
||||
void WelsI16x16LumaPredV_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredDc_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredPlane_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
|
||||
@@ -116,8 +112,6 @@ void WelsI4x4LumaPredHU_mmx (uint8_t* pPred, uint8_t* pRef, const int32_t kiStri
|
||||
#endif//X86_ASM
|
||||
|
||||
#if defined(HAVE_NEON)
|
||||
void WelsI16x16LumaPredV_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredDc_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredPlane_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
|
||||
@@ -137,8 +131,6 @@ void WelsIChromaPredPlane_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiS
|
||||
#endif//HAVE_NEON
|
||||
|
||||
#if defined(HAVE_NEON_AARCH64)
|
||||
void WelsI16x16LumaPredV_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredH_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredDc_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredPlane_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
void WelsI16x16LumaPredDcTop_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
|
||||
@@ -64,32 +64,32 @@ extern const uint8_t g_kuiTemporalIdListTable[MAX_TEMPORAL_LEVEL][MAX_GOP_SIZE
|
||||
* \return 2 based scaling factor
|
||||
*/
|
||||
static inline uint32_t GetLogFactor (float base, float upper) {
|
||||
const double dLog2factor = log10 (1.0 * upper / base) / log10 (2.0);
|
||||
const double dEpsilon = 0.0001;
|
||||
const double dRound = floor (dLog2factor + 0.5);
|
||||
const double dLog2factor = log10 (1.0 * upper / base) / log10 (2.0);
|
||||
const double dEpsilon = 0.0001;
|
||||
const double dRound = floor (dLog2factor + 0.5);
|
||||
|
||||
if (dLog2factor < dRound + dEpsilon && dRound < dLog2factor + dEpsilon) {
|
||||
return (uint32_t) (dRound);
|
||||
}
|
||||
return UINT_MAX;
|
||||
if (dLog2factor < dRound + dEpsilon && dRound < dLog2factor + dEpsilon) {
|
||||
return (uint32_t) (dRound);
|
||||
}
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dependency Layer Parameter
|
||||
*/
|
||||
typedef struct TagDLayerParam {
|
||||
int32_t iActualWidth; // input source picture actual width
|
||||
int32_t iActualHeight; // input source picture actual height
|
||||
int32_t iTemporalResolution;
|
||||
int32_t iDecompositionStages;
|
||||
uint8_t uiCodingIdx2TemporalId[ (1 << MAX_TEMPORAL_LEVEL) + 1];
|
||||
int32_t iActualWidth; // input source picture actual width
|
||||
int32_t iActualHeight; // input source picture actual height
|
||||
int32_t iTemporalResolution;
|
||||
int32_t iDecompositionStages;
|
||||
uint8_t uiCodingIdx2TemporalId[ (1 << MAX_TEMPORAL_LEVEL) + 1];
|
||||
|
||||
int8_t iHighestTemporalId;
|
||||
float fInputFrameRate; // input frame rate
|
||||
float fOutputFrameRate; // output frame rate
|
||||
int8_t iHighestTemporalId;
|
||||
float fInputFrameRate; // input frame rate
|
||||
float fOutputFrameRate; // output frame rate
|
||||
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
|
||||
char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
|
||||
#endif//ENABLE_FRAME_DUMP
|
||||
} SSpatialLayerInternal;
|
||||
|
||||
@@ -97,419 +97,432 @@ char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
|
||||
* Cisco OpenH264 Encoder Parameter Configuration
|
||||
*/
|
||||
typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
SSpatialLayerInternal sDependencyLayers[MAX_DEPENDENCY_LAYER];
|
||||
SSpatialLayerInternal sDependencyLayers[MAX_DEPENDENCY_LAYER];
|
||||
|
||||
/* General */
|
||||
uint32_t uiGopSize; // GOP size (at maximal frame rate: 16)
|
||||
struct {
|
||||
int32_t iLeft;
|
||||
int32_t iTop;
|
||||
int32_t iWidth;
|
||||
int32_t iHeight;
|
||||
} SUsedPicRect; // the rect in input picture that encoder actually used
|
||||
/* General */
|
||||
uint32_t uiGopSize; // GOP size (at maximal frame rate: 16)
|
||||
struct {
|
||||
int32_t iLeft;
|
||||
int32_t iTop;
|
||||
int32_t iWidth;
|
||||
int32_t iHeight;
|
||||
} SUsedPicRect; // the rect in input picture that encoder actually used
|
||||
|
||||
char* pCurPath; // record current lib path such as:/pData/pData/com.wels.enc/lib/
|
||||
char* pCurPath; // record current lib path such as:/pData/pData/com.wels.enc/lib/
|
||||
|
||||
bool bDeblockingParallelFlag; // deblocking filter parallelization control flag
|
||||
bool bDeblockingParallelFlag; // deblocking filter parallelization control flag
|
||||
|
||||
short
|
||||
iCountThreadsNum; // # derived from disable_multiple_slice_idc (=0 or >1) means;
|
||||
short
|
||||
iCountThreadsNum; // # derived from disable_multiple_slice_idc (=0 or >1) means;
|
||||
|
||||
int8_t iDecompStages; // GOP size dependency
|
||||
int32_t iMaxNumRefFrame;
|
||||
int8_t iDecompStages; // GOP size dependency
|
||||
int32_t iMaxNumRefFrame;
|
||||
|
||||
//setting this according to link type in use MAY invoke some algorithms targeting higher coding efficiency
|
||||
bool bIsLosslessLink;
|
||||
|
||||
public:
|
||||
TagWelsSvcCodingParam() {
|
||||
FillDefault();
|
||||
}
|
||||
~TagWelsSvcCodingParam() {}
|
||||
TagWelsSvcCodingParam() {
|
||||
FillDefault();
|
||||
}
|
||||
~TagWelsSvcCodingParam() {}
|
||||
|
||||
static void FillDefault (SEncParamExt& param) {
|
||||
memset (¶m, 0, sizeof (param));
|
||||
param.uiIntraPeriod = 0; // intra period (multiple of GOP size as desired)
|
||||
param.iNumRefFrame = AUTO_REF_PIC_COUNT;// number of reference frame used
|
||||
static void FillDefault (SEncParamExt& param) {
|
||||
memset (¶m, 0, sizeof (param));
|
||||
param.uiIntraPeriod = 0; // intra period (multiple of GOP size as desired)
|
||||
param.iNumRefFrame = AUTO_REF_PIC_COUNT;// number of reference frame used
|
||||
|
||||
param.iPicWidth = 0; // actual input picture width
|
||||
param.iPicHeight = 0; // actual input picture height
|
||||
param.iPicWidth = 0; // actual input picture width
|
||||
param.iPicHeight = 0; // actual input picture height
|
||||
|
||||
param.fMaxFrameRate = MAX_FRAME_RATE; // maximal frame rate [Hz / fps]
|
||||
param.fMaxFrameRate = MAX_FRAME_RATE; // maximal frame rate [Hz / fps]
|
||||
|
||||
param.iComplexityMode = MEDIUM_COMPLEXITY;
|
||||
param.iTargetBitrate = 0; // overall target bitrate introduced in RC module
|
||||
param.iMaxBitrate = MAX_BIT_RATE;
|
||||
param.iMultipleThreadIdc = 1;
|
||||
param.iComplexityMode = MEDIUM_COMPLEXITY;
|
||||
param.iTargetBitrate = 0; // overall target bitrate introduced in RC module
|
||||
param.iMaxBitrate = MAX_BIT_RATE;
|
||||
param.iMultipleThreadIdc = 1;
|
||||
|
||||
param.iLTRRefNum = 0;
|
||||
param.iLtrMarkPeriod = 30; //the min distance of two int32_t references
|
||||
param.iLTRRefNum = 0;
|
||||
param.iLtrMarkPeriod = 30; //the min distance of two int32_t references
|
||||
|
||||
param.bEnableSSEI = true;
|
||||
param.bEnableFrameCroppingFlag = true; // enable frame cropping flag: true alwayse in application
|
||||
// false: Streaming Video Sharing; true: Video Conferencing Meeting;
|
||||
param.bEnableSSEI = true;
|
||||
param.bEnableFrameCroppingFlag = true; // enable frame cropping flag: true alwayse in application
|
||||
// false: Streaming Video Sharing; true: Video Conferencing Meeting;
|
||||
|
||||
/* Deblocking loop filter */
|
||||
param.iLoopFilterDisableIdc = 0; // 0: on, 1: off, 2: on except for slice boundaries
|
||||
param.iLoopFilterAlphaC0Offset = 0; // AlphaOffset: valid range [-6, 6], default 0
|
||||
param.iLoopFilterBetaOffset = 0; // BetaOffset: valid range [-6, 6], default 0
|
||||
/* Deblocking loop filter */
|
||||
param.iLoopFilterDisableIdc = 0; // 0: on, 1: off, 2: on except for slice boundaries
|
||||
param.iLoopFilterAlphaC0Offset = 0; // AlphaOffset: valid range [-6, 6], default 0
|
||||
param.iLoopFilterBetaOffset = 0; // BetaOffset: valid range [-6, 6], default 0
|
||||
|
||||
/* Rate Control */
|
||||
param.iRCMode = RC_QUALITY_MODE;
|
||||
param.iPaddingFlag = 0;
|
||||
/* Rate Control */
|
||||
param.iRCMode = RC_QUALITY_MODE;
|
||||
param.iPaddingFlag = 0;
|
||||
|
||||
param.bEnableDenoise = false; // denoise control
|
||||
param.bEnableSceneChangeDetect = true; // scene change detection control
|
||||
param.bEnableBackgroundDetection = true; // background detection control
|
||||
param.bEnableAdaptiveQuant = true; // adaptive quantization control
|
||||
param.bEnableFrameSkip = true; // frame skipping
|
||||
param.bEnableLongTermReference = false; // long term reference control
|
||||
param.bEnableSpsPpsIdAddition = true; // pSps pPps id addition control
|
||||
param.bPrefixNalAddingCtrl = false; // prefix NAL adding control
|
||||
param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded
|
||||
param.iTemporalLayerNum = 1; // number of temporal layer specified
|
||||
param.bEnableDenoise = false; // denoise control
|
||||
param.bEnableSceneChangeDetect = true; // scene change detection control
|
||||
param.bEnableBackgroundDetection = true; // background detection control
|
||||
param.bEnableAdaptiveQuant = true; // adaptive quantization control
|
||||
param.bEnableFrameSkip = true; // frame skipping
|
||||
param.bEnableLongTermReference = false; // long term reference control
|
||||
param.bEnableSpsPpsIdAddition = true; // pSps pPps id addition control
|
||||
param.bPrefixNalAddingCtrl = false; // prefix NAL adding control
|
||||
param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded
|
||||
param.iTemporalLayerNum = 1; // number of temporal layer specified
|
||||
|
||||
param.iMaxQp = 51;
|
||||
param.iMinQp = 0;
|
||||
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||
param.uiMaxNalSize = 0;
|
||||
param.iMaxQp = 51;
|
||||
param.iMinQp = 0;
|
||||
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||
param.uiMaxNalSize = 0;
|
||||
|
||||
for (int32_t iLayer = 0; iLayer < MAX_SPATIAL_LAYER_NUM; iLayer++) {
|
||||
param.sSpatialLayers[iLayer].uiProfileIdc = PRO_BASELINE;
|
||||
param.sSpatialLayers[iLayer].uiLevelIdc = LEVEL_5_0;
|
||||
param.sSpatialLayers[iLayer].iDLayerQp = SVC_QUALITY_BASE_QP;
|
||||
param.sSpatialLayers[iLayer].fFrameRate = param.fMaxFrameRate;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
|
||||
for (int32_t iLayer = 0; iLayer < MAX_SPATIAL_LAYER_NUM; iLayer++) {
|
||||
param.sSpatialLayers[iLayer].uiProfileIdc = PRO_BASELINE;
|
||||
param.sSpatialLayers[iLayer].uiLevelIdc = LEVEL_5_0;
|
||||
param.sSpatialLayers[iLayer].iDLayerQp = SVC_QUALITY_BASE_QP;
|
||||
param.sSpatialLayers[iLayer].fFrameRate = param.fMaxFrameRate;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
|
||||
|
||||
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
|
||||
for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
|
||||
}
|
||||
}
|
||||
|
||||
void FillDefault() {
|
||||
FillDefault (*this);
|
||||
uiGopSize = 1; // GOP size (at maximal frame rate: 16)
|
||||
iMaxNumRefFrame = 1;
|
||||
SUsedPicRect.iLeft =
|
||||
SUsedPicRect.iTop =
|
||||
SUsedPicRect.iWidth =
|
||||
SUsedPicRect.iHeight = 0; // the rect in input picture that encoder actually used
|
||||
|
||||
pCurPath = NULL; // record current lib path such as:/pData/pData/com.wels.enc/lib/
|
||||
|
||||
bDeblockingParallelFlag = false; // deblocking filter parallelization control flag
|
||||
|
||||
iCountThreadsNum = 1; // # derived from disable_multiple_slice_idc (=0 or >1) means;
|
||||
|
||||
iDecompStages = 0; // GOP size dependency, unknown here and be revised later
|
||||
iComplexityMode = MEDIUM_COMPLEXITY;
|
||||
memset (sDependencyLayers, 0, sizeof (SSpatialLayerInternal)*MAX_DEPENDENCY_LAYER);
|
||||
memset (sSpatialLayers, 0 , sizeof (SSpatialLayerConfig)*MAX_SPATIAL_LAYER_NUM);
|
||||
|
||||
|
||||
//init multi-slice
|
||||
sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
|
||||
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = 1;
|
||||
|
||||
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
|
||||
for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
|
||||
}
|
||||
}
|
||||
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
|
||||
sSpatialLayers[0].iDLayerQp = SVC_QUALITY_BASE_QP;
|
||||
|
||||
void FillDefault() {
|
||||
FillDefault (*this);
|
||||
uiGopSize = 1; // GOP size (at maximal frame rate: 16)
|
||||
iMaxNumRefFrame = 1;
|
||||
SUsedPicRect.iLeft =
|
||||
SUsedPicRect.iTop =
|
||||
SUsedPicRect.iWidth =
|
||||
SUsedPicRect.iHeight = 0; // the rect in input picture that encoder actually used
|
||||
|
||||
pCurPath = NULL; // record current lib path such as:/pData/pData/com.wels.enc/lib/
|
||||
|
||||
bDeblockingParallelFlag = false; // deblocking filter parallelization control flag
|
||||
|
||||
iCountThreadsNum = 1; // # derived from disable_multiple_slice_idc (=0 or >1) means;
|
||||
|
||||
iDecompStages = 0; // GOP size dependency, unknown here and be revised later
|
||||
iComplexityMode = MEDIUM_COMPLEXITY;
|
||||
memset (sDependencyLayers, 0, sizeof (SSpatialLayerInternal)*MAX_DEPENDENCY_LAYER);
|
||||
memset (sSpatialLayers, 0 , sizeof (SSpatialLayerConfig)*MAX_SPATIAL_LAYER_NUM);
|
||||
|
||||
|
||||
//init multi-slice
|
||||
sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
|
||||
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = 1;
|
||||
|
||||
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
|
||||
for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
|
||||
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
|
||||
sSpatialLayers[0].iDLayerQp = SVC_QUALITY_BASE_QP;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam) {
|
||||
|
||||
fMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
iTargetBitrate = pCodingParam.iTargetBitrate;
|
||||
iUsageType = pCodingParam.iUsageType;
|
||||
iPicWidth = pCodingParam.iPicWidth;
|
||||
iPicHeight = pCodingParam.iPicHeight;
|
||||
|
||||
SUsedPicRect.iLeft = 0;
|
||||
SUsedPicRect.iTop = 0;
|
||||
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
|
||||
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
|
||||
|
||||
iRCMode = pCodingParam.iRCMode; // rc mode
|
||||
|
||||
int8_t iIdxSpatial = 0;
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
|
||||
while (iIdxSpatial < iSpatialLayerNum) {
|
||||
|
||||
sSpatialLayers->uiProfileIdc = uiProfileIdc;
|
||||
sSpatialLayers[iIdxSpatial].fFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate,
|
||||
MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
pDlp->fInputFrameRate =
|
||||
pDlp->fOutputFrameRate = WELS_CLIP3 (sSpatialLayers[iIdxSpatial].fFrameRate, MIN_FRAME_RATE,
|
||||
MAX_FRAME_RATE);
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||
#endif//ENABLE_FRAME_DUMP
|
||||
pDlp->iActualWidth = sSpatialLayers[iIdxSpatial].iVideoWidth = iPicWidth;
|
||||
pDlp->iActualHeight = sSpatialLayers[iIdxSpatial].iVideoHeight = iPicHeight;
|
||||
|
||||
sSpatialLayers->iSpatialBitrate =
|
||||
sSpatialLayers[iIdxSpatial].iSpatialBitrate = pCodingParam.iTargetBitrate; // target bitrate for current spatial layer
|
||||
|
||||
sSpatialLayers->iDLayerQp = SVC_QUALITY_BASE_QP;
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
++ iIdxSpatial;
|
||||
}
|
||||
SetActualPicResolution();
|
||||
|
||||
return 0;
|
||||
}
|
||||
void GetBaseParams (SEncParamBase* pCodingParam) {
|
||||
pCodingParam->iUsageType = iUsageType;
|
||||
pCodingParam->iPicWidth = iPicWidth;
|
||||
pCodingParam->iPicHeight = iPicHeight;
|
||||
pCodingParam->iTargetBitrate = iTargetBitrate;
|
||||
pCodingParam->iRCMode = iRCMode;
|
||||
pCodingParam->fMaxFrameRate = fMaxFrameRate;
|
||||
}
|
||||
int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
|
||||
float fParamMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
|
||||
iUsageType = pCodingParam.iUsageType;
|
||||
iPicWidth = pCodingParam.iPicWidth;
|
||||
iPicHeight = pCodingParam.iPicHeight;
|
||||
iComplexityMode = pCodingParam.iComplexityMode;
|
||||
|
||||
SUsedPicRect.iLeft = 0;
|
||||
SUsedPicRect.iTop = 0;
|
||||
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
|
||||
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
|
||||
|
||||
iMultipleThreadIdc = pCodingParam.iMultipleThreadIdc;
|
||||
|
||||
/* Deblocking loop filter */
|
||||
iLoopFilterDisableIdc = pCodingParam.iLoopFilterDisableIdc; // 0: on, 1: off, 2: on except for slice boundaries,
|
||||
iLoopFilterAlphaC0Offset = pCodingParam.iLoopFilterAlphaC0Offset; // AlphaOffset: valid range [-6, 6], default 0
|
||||
iLoopFilterBetaOffset = pCodingParam.iLoopFilterBetaOffset; // BetaOffset: valid range [-6, 6], default 0
|
||||
|
||||
bEnableFrameCroppingFlag = pCodingParam.bEnableFrameCroppingFlag;
|
||||
|
||||
/* Rate Control */
|
||||
iRCMode = pCodingParam.iRCMode; // rc mode
|
||||
iPaddingFlag = pCodingParam.iPaddingFlag;
|
||||
|
||||
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
|
||||
iMaxBitrate = pCodingParam.iMaxBitrate;
|
||||
if (iMaxBitrate < iTargetBitrate) {
|
||||
iMaxBitrate = iTargetBitrate;
|
||||
bIsLosslessLink = false;
|
||||
}
|
||||
|
||||
uiMaxNalSize = pCodingParam.uiMaxNalSize;
|
||||
/* Denoise Control */
|
||||
bEnableDenoise = pCodingParam.bEnableDenoise ? true : false; // Denoise Control // only support 0 or 1 now
|
||||
int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam) {
|
||||
|
||||
/* Scene change detection control */
|
||||
bEnableSceneChangeDetect = pCodingParam.bEnableSceneChangeDetect;
|
||||
fMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
iTargetBitrate = pCodingParam.iTargetBitrate;
|
||||
iUsageType = pCodingParam.iUsageType;
|
||||
iPicWidth = pCodingParam.iPicWidth;
|
||||
iPicHeight = pCodingParam.iPicHeight;
|
||||
|
||||
/* Background detection Control */
|
||||
bEnableBackgroundDetection = pCodingParam.bEnableBackgroundDetection ? true : false;
|
||||
SUsedPicRect.iLeft = 0;
|
||||
SUsedPicRect.iTop = 0;
|
||||
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
|
||||
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
|
||||
|
||||
/* Adaptive quantization control */
|
||||
bEnableAdaptiveQuant = pCodingParam.bEnableAdaptiveQuant ? true : false;
|
||||
iRCMode = pCodingParam.iRCMode; // rc mode
|
||||
|
||||
/* Frame skipping */
|
||||
bEnableFrameSkip = pCodingParam.bEnableFrameSkip ? true : false;
|
||||
int8_t iIdxSpatial = 0;
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
|
||||
/* Enable int32_t term reference */
|
||||
bEnableLongTermReference = pCodingParam.bEnableLongTermReference ? true : false;
|
||||
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
|
||||
/* For ssei information */
|
||||
bEnableSSEI = pCodingParam.bEnableSSEI;
|
||||
while (iIdxSpatial < iSpatialLayerNum) {
|
||||
|
||||
/* Layer definition */
|
||||
iSpatialLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iSpatialLayerNum, 1,
|
||||
MAX_DEPENDENCY_LAYER); // number of dependency(Spatial/CGS) layers used to be encoded
|
||||
iTemporalLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iTemporalLayerNum, 1,
|
||||
MAX_TEMPORAL_LEVEL); // number of temporal layer specified
|
||||
|
||||
uiGopSize = 1 << (iTemporalLayerNum - 1); // Override GOP size based temporal layer
|
||||
iDecompStages = iTemporalLayerNum - 1; // WELS_LOG2( uiGopSize );// GOP size dependency
|
||||
uiIntraPeriod = pCodingParam.uiIntraPeriod;// intra period (multiple of GOP size as desired)
|
||||
if (uiIntraPeriod == (uint32_t) (-1))
|
||||
uiIntraPeriod = 0;
|
||||
else if (uiIntraPeriod & (uiGopSize - 1)) // none multiple of GOP size
|
||||
uiIntraPeriod = ((uiIntraPeriod + uiGopSize - 1) / uiGopSize) * uiGopSize;
|
||||
|
||||
if (iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
if (bEnableLongTermReference) {
|
||||
iLTRRefNum = LONG_TERM_REF_NUM_SCREEN;
|
||||
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
|
||||
iNumRefFrame = WELS_MAX (1, WELS_LOG2 (uiGopSize)) + iLTRRefNum;
|
||||
} else {
|
||||
iLTRRefNum = 0;
|
||||
|
||||
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
|
||||
iNumRefFrame = WELS_MAX (1, uiGopSize >> 1);
|
||||
}
|
||||
} else {
|
||||
iLTRRefNum = bEnableLongTermReference ? LONG_TERM_REF_NUM : 0;
|
||||
if (iNumRefFrame == AUTO_REF_PIC_COUNT) {
|
||||
iNumRefFrame = ((uiGopSize >> 1) > 1) ? ((uiGopSize >> 1) + iLTRRefNum) : (MIN_REF_PIC_COUNT + iLTRRefNum);
|
||||
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
|
||||
}
|
||||
}
|
||||
if (iNumRefFrame > iMaxNumRefFrame)
|
||||
iMaxNumRefFrame = iNumRefFrame;
|
||||
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
|
||||
|
||||
bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
|
||||
|
||||
bEnableSpsPpsIdAddition =
|
||||
pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
|
||||
//SHOULD enable this feature.
|
||||
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
||||
float fMaxFr = .0f;
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
int8_t iIdxSpatial = 0;
|
||||
while (iIdxSpatial < iSpatialLayerNum) {
|
||||
pSpatialLayer->uiProfileIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc == PRO_UNKNOWN) ? uiProfileIdc :
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc;
|
||||
pSpatialLayer->uiLevelIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc == LEVEL_UNKNOWN) ? LEVEL_5_0 :
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc;
|
||||
|
||||
float fLayerFrameRate = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
|
||||
MIN_FRAME_RATE, fParamMaxFrameRate);
|
||||
pSpatialLayer->fFrameRate =
|
||||
sSpatialLayers->uiProfileIdc = uiProfileIdc;
|
||||
sSpatialLayers[iIdxSpatial].fFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate,
|
||||
MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
pDlp->fInputFrameRate =
|
||||
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
if (pDlp->fInputFrameRate > fMaxFr + EPSN)
|
||||
fMaxFr = pDlp->fInputFrameRate;
|
||||
pDlp->fOutputFrameRate = WELS_CLIP3 (sSpatialLayers[iIdxSpatial].fFrameRate, MIN_FRAME_RATE,
|
||||
MAX_FRAME_RATE);
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||
#endif//ENABLE_FRAME_DUMP
|
||||
pDlp->iActualWidth = sSpatialLayers[iIdxSpatial].iVideoWidth = iPicWidth;
|
||||
pDlp->iActualHeight = sSpatialLayers[iIdxSpatial].iVideoHeight = iPicHeight;
|
||||
|
||||
sSpatialLayers->iSpatialBitrate =
|
||||
sSpatialLayers[iIdxSpatial].iSpatialBitrate = pCodingParam.iTargetBitrate; // target bitrate for current spatial layer
|
||||
|
||||
sSpatialLayers->iDLayerQp = SVC_QUALITY_BASE_QP;
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
++ iIdxSpatial;
|
||||
}
|
||||
SetActualPicResolution();
|
||||
|
||||
return 0;
|
||||
}
|
||||
void GetBaseParams (SEncParamBase* pCodingParam) {
|
||||
pCodingParam->iUsageType = iUsageType;
|
||||
pCodingParam->iPicWidth = iPicWidth;
|
||||
pCodingParam->iPicHeight = iPicHeight;
|
||||
pCodingParam->iTargetBitrate = iTargetBitrate;
|
||||
pCodingParam->iRCMode = iRCMode;
|
||||
pCodingParam->fMaxFrameRate = fMaxFrameRate;
|
||||
}
|
||||
int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
|
||||
float fParamMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
|
||||
iUsageType = pCodingParam.iUsageType;
|
||||
iPicWidth = pCodingParam.iPicWidth;
|
||||
iPicHeight = pCodingParam.iPicHeight;
|
||||
fMaxFrameRate = fParamMaxFrameRate;
|
||||
iComplexityMode = pCodingParam.iComplexityMode;
|
||||
|
||||
SUsedPicRect.iLeft = 0;
|
||||
SUsedPicRect.iTop = 0;
|
||||
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
|
||||
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
|
||||
|
||||
iMultipleThreadIdc = pCodingParam.iMultipleThreadIdc;
|
||||
|
||||
/* Deblocking loop filter */
|
||||
iLoopFilterDisableIdc = pCodingParam.iLoopFilterDisableIdc; // 0: on, 1: off, 2: on except for slice boundaries,
|
||||
iLoopFilterAlphaC0Offset = pCodingParam.iLoopFilterAlphaC0Offset; // AlphaOffset: valid range [-6, 6], default 0
|
||||
iLoopFilterBetaOffset = pCodingParam.iLoopFilterBetaOffset; // BetaOffset: valid range [-6, 6], default 0
|
||||
|
||||
bEnableFrameCroppingFlag = pCodingParam.bEnableFrameCroppingFlag;
|
||||
|
||||
/* Rate Control */
|
||||
iRCMode = pCodingParam.iRCMode; // rc mode
|
||||
iPaddingFlag = pCodingParam.iPaddingFlag;
|
||||
|
||||
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
|
||||
iMaxBitrate = pCodingParam.iMaxBitrate;
|
||||
if (iMaxBitrate < iTargetBitrate) {
|
||||
iMaxBitrate = iTargetBitrate;
|
||||
}
|
||||
|
||||
uiMaxNalSize = pCodingParam.uiMaxNalSize;
|
||||
/* Denoise Control */
|
||||
bEnableDenoise = pCodingParam.bEnableDenoise ? true : false; // Denoise Control // only support 0 or 1 now
|
||||
|
||||
/* Scene change detection control */
|
||||
bEnableSceneChangeDetect = pCodingParam.bEnableSceneChangeDetect;
|
||||
|
||||
/* Background detection Control */
|
||||
bEnableBackgroundDetection = pCodingParam.bEnableBackgroundDetection ? true : false;
|
||||
|
||||
/* Adaptive quantization control */
|
||||
bEnableAdaptiveQuant = pCodingParam.bEnableAdaptiveQuant ? true : false;
|
||||
|
||||
/* Frame skipping */
|
||||
bEnableFrameSkip = pCodingParam.bEnableFrameSkip ? true : false;
|
||||
|
||||
/* Enable int32_t term reference */
|
||||
bEnableLongTermReference = pCodingParam.bEnableLongTermReference ? true : false;
|
||||
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
|
||||
bIsLosslessLink = pCodingParam.bIsLosslessLink;
|
||||
if (iUsageType == SCREEN_CONTENT_REAL_TIME && !bIsLosslessLink && bEnableLongTermReference) {
|
||||
bEnableLongTermReference = false;
|
||||
}
|
||||
|
||||
/* For ssei information */
|
||||
bEnableSSEI = pCodingParam.bEnableSSEI;
|
||||
|
||||
/* Layer definition */
|
||||
iSpatialLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iSpatialLayerNum, 1,
|
||||
MAX_DEPENDENCY_LAYER); // number of dependency(Spatial/CGS) layers used to be encoded
|
||||
iTemporalLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iTemporalLayerNum, 1,
|
||||
MAX_TEMPORAL_LEVEL); // number of temporal layer specified
|
||||
|
||||
uiGopSize = 1 << (iTemporalLayerNum - 1); // Override GOP size based temporal layer
|
||||
iDecompStages = iTemporalLayerNum - 1; // WELS_LOG2( uiGopSize );// GOP size dependency
|
||||
uiIntraPeriod = pCodingParam.uiIntraPeriod;// intra period (multiple of GOP size as desired)
|
||||
if (uiIntraPeriod == (uint32_t) (-1))
|
||||
uiIntraPeriod = 0;
|
||||
else if (uiIntraPeriod & (uiGopSize - 1)) // none multiple of GOP size
|
||||
uiIntraPeriod = ((uiIntraPeriod + uiGopSize - 1) / uiGopSize) * uiGopSize;
|
||||
|
||||
if (iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
if (bEnableLongTermReference) {
|
||||
iLTRRefNum = LONG_TERM_REF_NUM_SCREEN;
|
||||
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
|
||||
iNumRefFrame = WELS_MAX (1, WELS_LOG2 (uiGopSize)) + iLTRRefNum;
|
||||
} else {
|
||||
iLTRRefNum = 0;
|
||||
|
||||
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
|
||||
iNumRefFrame = WELS_MAX (1, uiGopSize >> 1);
|
||||
}
|
||||
} else {
|
||||
iLTRRefNum = bEnableLongTermReference ? LONG_TERM_REF_NUM : 0;
|
||||
if (iNumRefFrame == AUTO_REF_PIC_COUNT) {
|
||||
iNumRefFrame = ((uiGopSize >> 1) > 1) ? ((uiGopSize >> 1) + iLTRRefNum) : (MIN_REF_PIC_COUNT + iLTRRefNum);
|
||||
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA);
|
||||
}
|
||||
}
|
||||
if (iNumRefFrame > iMaxNumRefFrame)
|
||||
iMaxNumRefFrame = iNumRefFrame;
|
||||
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
|
||||
|
||||
bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
|
||||
|
||||
bEnableSpsPpsIdAddition =
|
||||
pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
|
||||
//SHOULD enable this feature.
|
||||
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
int8_t iIdxSpatial = 0;
|
||||
while (iIdxSpatial < iSpatialLayerNum) {
|
||||
pSpatialLayer->uiProfileIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc == PRO_UNKNOWN) ? uiProfileIdc :
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc;
|
||||
pSpatialLayer->uiLevelIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc == LEVEL_UNKNOWN) ? LEVEL_5_0 :
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc;
|
||||
|
||||
float fLayerFrameRate = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
|
||||
MIN_FRAME_RATE, fParamMaxFrameRate);
|
||||
pDlp->fInputFrameRate = fParamMaxFrameRate;
|
||||
pSpatialLayer->fFrameRate =
|
||||
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, fParamMaxFrameRate);
|
||||
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||
#endif//ENABLE_FRAME_DUMP
|
||||
pSpatialLayer->iVideoWidth = pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth; // frame width
|
||||
pSpatialLayer->iVideoHeight = pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight;// frame height
|
||||
pSpatialLayer->iSpatialBitrate =
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].iSpatialBitrate; // target bitrate for current spatial layer
|
||||
pSpatialLayer->iMaxSpatialBitrate =
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].iMaxSpatialBitrate;
|
||||
pSpatialLayer->iVideoWidth = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth, 0,
|
||||
iPicWidth); // frame width
|
||||
pSpatialLayer->iVideoHeight = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight, 0,
|
||||
iPicHeight);// frame height
|
||||
|
||||
//multi slice
|
||||
pSpatialLayer->sSliceCfg.uiSliceMode = pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.uiSliceMode;
|
||||
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
|
||||
= (uint32_t) (pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceSizeConstraint);
|
||||
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum
|
||||
= pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceNum;
|
||||
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
|
||||
memcpy (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum,
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceMbNum, // confirmed_safe_unsafe_usage
|
||||
kiLesserSliceNum * sizeof (uint32_t)) ;
|
||||
pSpatialLayer->iSpatialBitrate =
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].iSpatialBitrate; // target bitrate for current spatial layer
|
||||
pSpatialLayer->iMaxSpatialBitrate =
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].iMaxSpatialBitrate;
|
||||
|
||||
pSpatialLayer->iDLayerQp = pCodingParam.sSpatialLayers[iIdxSpatial].iDLayerQp;
|
||||
//multi slice
|
||||
pSpatialLayer->sSliceCfg.uiSliceMode = pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.uiSliceMode;
|
||||
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
|
||||
= (uint32_t) (pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceSizeConstraint);
|
||||
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum
|
||||
= pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceNum;
|
||||
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
|
||||
memcpy (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum,
|
||||
pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceMbNum, // confirmed_safe_unsafe_usage
|
||||
kiLesserSliceNum * sizeof (uint32_t)) ;
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
++ pSpatialLayer;
|
||||
++ iIdxSpatial;
|
||||
pSpatialLayer->iDLayerQp = pCodingParam.sSpatialLayers[iIdxSpatial].iDLayerQp;
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
++ pSpatialLayer;
|
||||
++ iIdxSpatial;
|
||||
}
|
||||
|
||||
SetActualPicResolution();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fMaxFrameRate = fMaxFr;
|
||||
|
||||
SetActualPicResolution();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// assuming that the width/height ratio of all spatial layers are the same
|
||||
|
||||
void SetActualPicResolution() {
|
||||
int32_t iSpatialIdx = iSpatialLayerNum - 1;
|
||||
for (; iSpatialIdx >= 0; iSpatialIdx --) {
|
||||
SSpatialLayerInternal* pDlayerInternal = &sDependencyLayers[iSpatialIdx];
|
||||
SSpatialLayerConfig* pDlayer = &sSpatialLayers[iSpatialIdx];
|
||||
void SetActualPicResolution() {
|
||||
int32_t iSpatialIdx = iSpatialLayerNum - 1;
|
||||
for (; iSpatialIdx >= 0; iSpatialIdx --) {
|
||||
SSpatialLayerInternal* pDlayerInternal = &sDependencyLayers[iSpatialIdx];
|
||||
SSpatialLayerConfig* pDlayer = &sSpatialLayers[iSpatialIdx];
|
||||
|
||||
pDlayerInternal->iActualWidth = pDlayer->iVideoWidth;
|
||||
pDlayerInternal->iActualHeight = pDlayer->iVideoHeight;
|
||||
pDlayer->iVideoWidth = WELS_ALIGN (pDlayerInternal->iActualWidth, MB_WIDTH_LUMA);
|
||||
pDlayer->iVideoHeight = WELS_ALIGN (pDlayerInternal->iActualHeight, MB_HEIGHT_LUMA);
|
||||
pDlayerInternal->iActualWidth = pDlayer->iVideoWidth;
|
||||
pDlayerInternal->iActualHeight = pDlayer->iVideoHeight;
|
||||
pDlayer->iVideoWidth = WELS_ALIGN (pDlayerInternal->iActualWidth, MB_WIDTH_LUMA);
|
||||
pDlayer->iVideoHeight = WELS_ALIGN (pDlayerInternal->iActualHeight, MB_HEIGHT_LUMA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief determined key coding tables for temporal scalability, uiProfileIdc etc for each spatial layer settings
|
||||
* \param SWelsSvcCodingParam, and carried with known GOP size, max, input and output frame rate of each spatial
|
||||
* \return NONE (should ensure valid parameter before this procedure)
|
||||
*/
|
||||
void DetermineTemporalSettings() {
|
||||
const int32_t iDecStages = WELS_LOG2 (
|
||||
uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize); //log2(uiGopSize)
|
||||
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
int8_t i = 0;
|
||||
/*!
|
||||
* \brief determined key coding tables for temporal scalability, uiProfileIdc etc for each spatial layer settings
|
||||
* \param SWelsSvcCodingParam, and carried with known GOP size, max, input and output frame rate of each spatial
|
||||
* \return NONE (should ensure valid parameter before this procedure)
|
||||
*/
|
||||
int32_t DetermineTemporalSettings() {
|
||||
const int32_t iDecStages = WELS_LOG2 (
|
||||
uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize); //log2(uiGopSize)
|
||||
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
int8_t i = 0;
|
||||
|
||||
while (i < iSpatialLayerNum) {
|
||||
const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
|
||||
const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
|
||||
int32_t iNotCodedMask = 0;
|
||||
int8_t iMaxTemporalId = 0;
|
||||
while (i < iSpatialLayerNum) {
|
||||
const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
|
||||
const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
|
||||
if (UINT_MAX == kuiLogFactorInOutRate || UINT_MAX == kuiLogFactorMaxInRate) {
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
int32_t iNotCodedMask = 0;
|
||||
int8_t iMaxTemporalId = 0;
|
||||
|
||||
memset (pDlp->uiCodingIdx2TemporalId, INVALID_TEMPORAL_ID, sizeof (pDlp->uiCodingIdx2TemporalId));
|
||||
pSpatialLayer->uiProfileIdc = uiProfileIdc; // PRO_BASELINE, PRO_SCALABLE_BASELINE;
|
||||
memset (pDlp->uiCodingIdx2TemporalId, INVALID_TEMPORAL_ID, sizeof (pDlp->uiCodingIdx2TemporalId));
|
||||
pSpatialLayer->uiProfileIdc = uiProfileIdc; // PRO_BASELINE, PRO_SCALABLE_BASELINE;
|
||||
|
||||
iNotCodedMask = (1 << (kuiLogFactorInOutRate + kuiLogFactorMaxInRate)) - 1;
|
||||
for (uint32_t uiFrameIdx = 0; uiFrameIdx <= uiGopSize; ++ uiFrameIdx) {
|
||||
if (0 == (uiFrameIdx & iNotCodedMask)) {
|
||||
const int8_t kiTemporalId = pTemporalIdList[uiFrameIdx];
|
||||
pDlp->uiCodingIdx2TemporalId[uiFrameIdx] = kiTemporalId;
|
||||
if (kiTemporalId > iMaxTemporalId) {
|
||||
iMaxTemporalId = kiTemporalId;
|
||||
iNotCodedMask = (1 << (kuiLogFactorInOutRate + kuiLogFactorMaxInRate)) - 1;
|
||||
for (uint32_t uiFrameIdx = 0; uiFrameIdx <= uiGopSize; ++ uiFrameIdx) {
|
||||
if (0 == (uiFrameIdx & iNotCodedMask)) {
|
||||
const int8_t kiTemporalId = pTemporalIdList[uiFrameIdx];
|
||||
pDlp->uiCodingIdx2TemporalId[uiFrameIdx] = kiTemporalId;
|
||||
if (kiTemporalId > iMaxTemporalId) {
|
||||
iMaxTemporalId = kiTemporalId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pDlp->iHighestTemporalId = iMaxTemporalId;
|
||||
pDlp->iTemporalResolution = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
|
||||
pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
|
||||
if (pDlp->iDecompositionStages < 0) {
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
++ pSpatialLayer;
|
||||
++ i;
|
||||
}
|
||||
|
||||
pDlp->iHighestTemporalId = iMaxTemporalId;
|
||||
pDlp->iTemporalResolution = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
|
||||
pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
++ pSpatialLayer;
|
||||
++ i;
|
||||
iDecompStages = (int8_t)iDecStages;
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
iDecompStages = (int8_t)iDecStages;
|
||||
}
|
||||
|
||||
} SWelsSvcCodingParam;
|
||||
|
||||
static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
|
||||
if (pParam == NULL || *pParam == NULL || pMa == NULL)
|
||||
return 1;
|
||||
pMa->WelsFree (*pParam, "SWelsSvcCodingParam");
|
||||
*pParam = NULL;
|
||||
return 0;
|
||||
if (pParam == NULL || *pParam == NULL || pMa == NULL)
|
||||
return 1;
|
||||
pMa->WelsFree (*pParam, "SWelsSvcCodingParam");
|
||||
*pParam = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int32_t AllocCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
|
||||
if (pParam == NULL || pMa == NULL)
|
||||
return 1;
|
||||
if (*pParam != NULL) {
|
||||
FreeCodingParam (pParam, pMa);
|
||||
}
|
||||
SWelsSvcCodingParam* pCodingParam = (SWelsSvcCodingParam*)pMa->WelsMalloc (sizeof (SWelsSvcCodingParam),
|
||||
"SWelsSvcCodingParam");
|
||||
if (NULL == pCodingParam)
|
||||
return 1;
|
||||
*pParam = pCodingParam;
|
||||
return 0;
|
||||
if (pParam == NULL || pMa == NULL)
|
||||
return 1;
|
||||
if (*pParam != NULL) {
|
||||
FreeCodingParam (pParam, pMa);
|
||||
}
|
||||
SWelsSvcCodingParam* pCodingParam = (SWelsSvcCodingParam*)pMa->WelsMalloc (sizeof (SWelsSvcCodingParam),
|
||||
"SWelsSvcCodingParam");
|
||||
if (NULL == pCodingParam)
|
||||
return 1;
|
||||
*pParam = pCodingParam;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}//end of namespace WelsEnc
|
||||
|
||||
@@ -99,6 +99,25 @@ int32_t iFrameAverageQp;
|
||||
|
||||
/*******************************for screen reference frames****************************/
|
||||
SScreenBlockFeatureStorage* pScreenBlockFeatureStorage;
|
||||
|
||||
/*
|
||||
* set picture as unreferenced
|
||||
*/
|
||||
void SetUnref () {
|
||||
iFramePoc = -1;
|
||||
iFrameNum = -1;
|
||||
uiTemporalId =
|
||||
uiSpatialId =
|
||||
iLongTermPicNum = -1;
|
||||
bIsLongRef = false;
|
||||
uiRecieveConfirmed = RECIEVE_FAILED;
|
||||
iMarkFrameNum = -1;
|
||||
bUsedAsRef = false;
|
||||
|
||||
if (NULL != pScreenBlockFeatureStorage)
|
||||
pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = false;
|
||||
}
|
||||
|
||||
} SPicture;
|
||||
|
||||
/*
|
||||
|
||||
@@ -62,12 +62,5 @@ SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth, const int32_t
|
||||
*/
|
||||
void FreePicture (CMemoryAlign* pMa, SPicture** ppPic);
|
||||
|
||||
/*!
|
||||
* \brief exchange two picture pData planes
|
||||
* \param ppPic1 picture pointer to picture 1
|
||||
* \param ppPic2 picture pointer to picture 2
|
||||
* \return none
|
||||
*/
|
||||
void WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2);
|
||||
}
|
||||
#endif//WELS_ENCODER_PICTURE_HANDLE_H__
|
||||
|
||||
@@ -54,55 +54,55 @@ namespace WelsEnc {
|
||||
#define GOM_H_SCC 8
|
||||
|
||||
enum {
|
||||
BITS_NORMAL,
|
||||
BITS_LIMITED,
|
||||
BITS_EXCEEDED,
|
||||
BITS_NORMAL,
|
||||
BITS_LIMITED,
|
||||
BITS_EXCEEDED
|
||||
};
|
||||
|
||||
enum {
|
||||
//virtual gop size
|
||||
VGOP_SIZE = 8,
|
||||
VGOP_SIZE = 8,
|
||||
|
||||
//qp information
|
||||
GOM_MIN_QP_MODE = 12,
|
||||
GOM_MAX_QP_MODE = 36,
|
||||
MAX_LOW_BR_QP = 42,
|
||||
MIN_IDR_QP = 26,
|
||||
MAX_IDR_QP = 32,
|
||||
MIN_SCREEN_QP = 26,
|
||||
MAX_SCREEN_QP = 32,
|
||||
DELTA_QP = 2,
|
||||
DELTA_QP_BGD_THD = 3,
|
||||
GOM_MIN_QP_MODE = 12,
|
||||
GOM_MAX_QP_MODE = 36,
|
||||
MAX_LOW_BR_QP = 42,
|
||||
MIN_IDR_QP = 26,
|
||||
MAX_IDR_QP = 32,
|
||||
MIN_SCREEN_QP = 26,
|
||||
MAX_SCREEN_QP = 35,
|
||||
DELTA_QP = 2,
|
||||
DELTA_QP_BGD_THD = 3,
|
||||
|
||||
//frame skip constants
|
||||
SKIP_QP_90P = 24,
|
||||
SKIP_QP_180P = 24,
|
||||
SKIP_QP_360P = 31,
|
||||
SKIP_QP_720P = 31,
|
||||
LAST_FRAME_QP_RANGE_UPPER_MODE0 = 3,
|
||||
LAST_FRAME_QP_RANGE_LOWER_MODE0 = 2,
|
||||
LAST_FRAME_QP_RANGE_UPPER_MODE1 = 5,
|
||||
LAST_FRAME_QP_RANGE_LOWER_MODE1 = 3,
|
||||
SKIP_QP_90P = 24,
|
||||
SKIP_QP_180P = 24,
|
||||
SKIP_QP_360P = 31,
|
||||
SKIP_QP_720P = 31,
|
||||
LAST_FRAME_QP_RANGE_UPPER_MODE0 = 3,
|
||||
LAST_FRAME_QP_RANGE_LOWER_MODE0 = 2,
|
||||
LAST_FRAME_QP_RANGE_UPPER_MODE1 = 5,
|
||||
LAST_FRAME_QP_RANGE_LOWER_MODE1 = 3,
|
||||
|
||||
MB_WIDTH_THRESHOLD_90P = 15,
|
||||
MB_WIDTH_THRESHOLD_180P = 30,
|
||||
MB_WIDTH_THRESHOLD_360P = 60,
|
||||
MB_WIDTH_THRESHOLD_90P = 15,
|
||||
MB_WIDTH_THRESHOLD_180P = 30,
|
||||
MB_WIDTH_THRESHOLD_360P = 60,
|
||||
|
||||
//Mode 0 parameter
|
||||
GOM_ROW_MODE0_90P = 2,
|
||||
GOM_ROW_MODE0_180P = 2,
|
||||
GOM_ROW_MODE0_360P = 4,
|
||||
GOM_ROW_MODE0_720P = 4,
|
||||
QP_RANGE_MODE0 = 3,
|
||||
GOM_ROW_MODE0_90P = 2,
|
||||
GOM_ROW_MODE0_180P = 2,
|
||||
GOM_ROW_MODE0_360P = 4,
|
||||
GOM_ROW_MODE0_720P = 4,
|
||||
QP_RANGE_MODE0 = 3,
|
||||
|
||||
//Mode 1 parameter
|
||||
GOM_ROW_MODE1_90P = 1,
|
||||
GOM_ROW_MODE1_180P = 1,
|
||||
GOM_ROW_MODE1_360P = 2,
|
||||
GOM_ROW_MODE1_720P = 2,
|
||||
QP_RANGE_UPPER_MODE1 = 9,
|
||||
QP_RANGE_LOWER_MODE1 = 4,
|
||||
QP_RANGE_INTRA_MODE1 = 3,
|
||||
GOM_ROW_MODE1_90P = 1,
|
||||
GOM_ROW_MODE1_180P = 1,
|
||||
GOM_ROW_MODE1_360P = 2,
|
||||
GOM_ROW_MODE1_720P = 2,
|
||||
QP_RANGE_UPPER_MODE1 = 9,
|
||||
QP_RANGE_LOWER_MODE1 = 4,
|
||||
QP_RANGE_INTRA_MODE1 = 3
|
||||
};
|
||||
|
||||
//bits allocation
|
||||
@@ -181,6 +181,8 @@ int32_t* pCurrentFrameGomSad;
|
||||
int32_t* pGomCost;
|
||||
|
||||
int32_t iAverageFrameQp;
|
||||
int32_t iMinFrameQp;
|
||||
int32_t iMaxFrameQp;
|
||||
int32_t iNumberMbFrame;
|
||||
int32_t iNumberMbGom;
|
||||
int32_t iSliceNum;
|
||||
@@ -216,10 +218,20 @@ bool bSkipFlag;
|
||||
|
||||
SRCSlicing* pSlicingOverRc;
|
||||
SRCTemporal* pTemporalOverRc;
|
||||
|
||||
//for scc
|
||||
int64_t iAvgCost2Bits;
|
||||
int64_t iCost2BitsIntra;
|
||||
int32_t iBaseQp;
|
||||
long long uiLastTimeStamp;
|
||||
|
||||
//for statistics and online adjustments
|
||||
int32_t iActualBitRate; // TODO: to complete later
|
||||
float fLatestFrameRate; // TODO: to complete later
|
||||
} SWelsSvcRc;
|
||||
|
||||
typedef void (*PWelsRCPictureInitFunc) (void* pCtx);
|
||||
typedef void (*PWelsRCPictureDelayJudgeFunc) (void* pCtx);
|
||||
typedef void (*PWelsRCPictureDelayJudgeFunc) (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp);
|
||||
typedef void (*PWelsRCPictureInfoUpdateFunc) (void* pCtx, int32_t iLayerSize);
|
||||
typedef void (*PWelsRCMBInfoUpdateFunc) (void* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice* pSlice);
|
||||
typedef void (*PWelsRCMBInitFunc) (void* pCtx, SMB* pCurMb, SSlice* pSlice);
|
||||
@@ -232,9 +244,9 @@ PWelsRCMBInitFunc pfWelsRcMbInit;
|
||||
PWelsRCMBInfoUpdateFunc pfWelsRcMbInfoUpdate;
|
||||
} SWelsRcFunc;
|
||||
|
||||
void WelsRcInitModule (void* pCtx,RC_MODES iRcMode);
|
||||
void RcTraceFrameBits (void* pEncCtx, long long uiTimeStamp);
|
||||
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode);
|
||||
void WelsRcFreeMemory (void* pCtx);
|
||||
|
||||
}
|
||||
#endif //RC_H
|
||||
|
||||
@@ -47,22 +47,17 @@
|
||||
#include "codec_app_def.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
typedef enum {
|
||||
RECIEVE_UNKOWN = 0,
|
||||
RECIEVE_SUCCESS = 1,
|
||||
RECIEVE_FAILED = 2,
|
||||
} LTR_MARKING_RECEIVE_STATE;
|
||||
|
||||
typedef enum {
|
||||
LTR_DIRECT_MARK = 0,
|
||||
LTR_DELAY_MARK = 1,
|
||||
LTR_DELAY_MARK = 1
|
||||
} LTR_MARKING_PROCESS_MODE;
|
||||
|
||||
typedef enum {
|
||||
FRAME_NUM_EQUAL = 0x01,
|
||||
FRAME_NUM_BIGGER = 0x02,
|
||||
FRAME_NUM_SMALLER = 0x04,
|
||||
FRAME_NUM_OVER_MAX = 0x08,
|
||||
FRAME_NUM_OVER_MAX = 0x08
|
||||
} COMPARE_FRAME_NUM;
|
||||
|
||||
/*
|
||||
@@ -98,7 +93,7 @@ bool CheckCurMarkFrameNumUsed (sWelsEncCtx* pCtx);
|
||||
*/
|
||||
void WelsMarkPic (void* pCtx);
|
||||
|
||||
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, EUsageType eUsageType);
|
||||
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bEnableLongTermReference, const bool bScreenContent);
|
||||
|
||||
#ifdef LONG_TERM_REF_DUMP
|
||||
void DumpRef (sWelsEncCtx* ctx);
|
||||
|
||||
@@ -168,7 +168,7 @@ SMVUnitXY sMvc[5];
|
||||
uint8_t uiMvcNum;
|
||||
uint8_t sScaleShift;
|
||||
|
||||
uint8_t uiSliceIdx;
|
||||
uint32_t uiSliceIdx;
|
||||
bool bSliceHeaderExtFlag; // Indicate which slice header is used, avc or ext?
|
||||
uint8_t uiLastMbQp; // stored qp for last mb coded, maybe more efficient for mb skip detection etc.
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace WelsEnc {
|
||||
|
||||
typedef enum {
|
||||
STATIC,
|
||||
SCROLLED,
|
||||
SCROLLED
|
||||
} ESkipModes;
|
||||
|
||||
// NOILP ILFMD ENTRANCE
|
||||
|
||||
@@ -62,7 +62,7 @@ ME_FULL = 0x10, // FULL
|
||||
|
||||
// derived ME methods combination
|
||||
ME_DIA_CROSS = (ME_DIA | ME_CROSS), // DIA+CROSS
|
||||
ME_DIA_CROSS_FME = (ME_DIA_CROSS | ME_FME), // DIA+CROSS+FME
|
||||
ME_DIA_CROSS_FME = (ME_DIA_CROSS | ME_FME) // DIA+CROSS+FME
|
||||
};
|
||||
|
||||
union SadPredISatdUnit {
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
#define MAX_TRACE_LOG_SIZE (50 * (1<<20)) // max trace log size: 50 MB, overwrite occur if log file size exceeds this size
|
||||
#endif//MAX_TRACE_LOG_SIZE
|
||||
|
||||
#define STATISTICS_LOG_INTERVAL_MS (5000) // output statistics log every 5s
|
||||
|
||||
/* MB width in pixels for specified colorspace I420 usually used in codec */
|
||||
#define MB_WIDTH_LUMA 16
|
||||
#define MB_WIDTH_CHROMA (MB_WIDTH_LUMA>>1)
|
||||
@@ -149,7 +151,6 @@
|
||||
#define MAX_SHORT_REF_COUNT (MAX_GOP_SIZE>>1) // 16 in standard, maximal count number of short reference pictures
|
||||
#define LONG_TERM_REF_NUM 2
|
||||
#define LONG_TERM_REF_NUM_SCREEN 4
|
||||
#define MAX_LONG_REF_COUNT 2 // 16 in standard, maximal count number of long reference pictures
|
||||
#define MAX_REF_PIC_COUNT 16 // 32 in standard, maximal Short + Long reference pictures
|
||||
#define MIN_REF_PIC_COUNT 1 // minimal count number of reference pictures, 1 short + 2 key reference based?
|
||||
#define MAX_MULTI_REF_PIC_COUNT 1 //maximum multi-reference number
|
||||
@@ -159,7 +160,8 @@
|
||||
// adjusted numbers reference picture functionality related definition
|
||||
#define MAX_REFERENCE_MMCO_COUNT_NUM 4 // adjusted MAX_MMCO_COUNT(66 in standard) definition per encoder design
|
||||
#define MAX_REFERENCE_REORDER_COUNT_NUM 2 // adjusted MAX_REF_PIC_COUNT(32 in standard) for reference reordering definition per encoder design
|
||||
#define MAX_REFERENCE_PICTURE_COUNT_NUM (MAX_SHORT_REF_COUNT+MAX_LONG_REF_COUNT) // <= MAX_REF_PIC_COUNT, memory saved if <
|
||||
#define MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA (MAX_SHORT_REF_COUNT+LONG_TERM_REF_NUM) // <= MAX_REF_PIC_COUNT, memory saved if <
|
||||
#define MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN (MAX_SHORT_REF_COUNT+LONG_TERM_REF_NUM_SCREEN) // <= MAX_REF_PIC_COUNT, memory saved if <
|
||||
|
||||
#define BASE_QUALITY_ID 0
|
||||
#define BASE_DEPENDENCY_ID 0
|
||||
@@ -189,6 +191,12 @@ BLOCK_4x4 = 4,
|
||||
BLOCK_SIZE_ALL = 5
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
RECIEVE_UNKOWN = 0,
|
||||
RECIEVE_SUCCESS = 1,
|
||||
RECIEVE_FAILED = 2
|
||||
} LTR_MARKING_RECEIVE_STATE;
|
||||
|
||||
enum {
|
||||
CUR_AU_IDX = 0, // index symbol for current access unit
|
||||
SUC_AU_IDX = 1 // index symbol for successive access unit
|
||||
|
||||
@@ -195,6 +195,8 @@ typedef void (*PUpdateMbMvFunc) (SMVUnitXY* pMvUnit, const SMVUnitXY ksMv);
|
||||
typedef bool (*PBuildRefListFunc) (void* pCtx, const int32_t iPOC, int32_t iBestLtrRefIdx);
|
||||
typedef void (*PMarkPicFunc) (void* pCtx);
|
||||
typedef bool (*PUpdateRefListFunc) (void* pCtx);
|
||||
typedef void (*PEndofUpdateRefListFunc) (void* pCtx);
|
||||
typedef void (*PAfterBuildRefListFunc) (void* pCtx);
|
||||
|
||||
typedef int32_t (*PCavlcParamCalFunc) (int16_t* pCoff, uint8_t* pRun, int16_t* pLevel, int32_t* pTotalCoeffs,
|
||||
int32_t iEndIdx);
|
||||
@@ -291,6 +293,8 @@ struct TagWelsFuncPointerList {
|
||||
PBuildRefListFunc pBuildRefList;
|
||||
PMarkPicFunc pMarkPic;
|
||||
PUpdateRefListFunc pUpdateRefList;
|
||||
PEndofUpdateRefListFunc pEndofUpdateRefList;
|
||||
PAfterBuildRefListFunc pAfterBuildRefList;
|
||||
|
||||
PCavlcParamCalFunc pfCavlcParamCal;
|
||||
};
|
||||
|
||||
@@ -109,6 +109,7 @@ typedef struct SVAAFrameInfoExt_t: public SVAAFrameInfo {
|
||||
SRefInfoParam sVaaStrBestRefCandidate[MAX_REF_PIC_COUNT]; //TOP3_BEST_REF_NO_TID
|
||||
int32_t iNumOfAvailableRef;
|
||||
|
||||
int32_t iVaaBestRefFrameNum;
|
||||
uint8_t* pVaaBestBlockStaticIdc;//pointer
|
||||
uint8_t* pVaaBlockStaticIdc[16];//real memory,
|
||||
} SVAAFrameInfoExt;
|
||||
@@ -129,6 +130,15 @@ class CWelsPreProcess {
|
||||
int32_t GetRefFrameInfo (int32_t iRefIdx, SPicture*& pRefOri);
|
||||
void AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture,
|
||||
const int32_t kiDependencyId, const bool kbCalculateBGD);
|
||||
int32_t UpdateBlockIdcForScreen (uint8_t* pCurBlockStaticPointer, const SPicture* kpRefPic, const SPicture* kpSrcPic);
|
||||
|
||||
SPicture* GetCurrentFrameFromOrigList (int32_t iDIdx) {
|
||||
return m_pSpatialPic[iDIdx][0];
|
||||
}
|
||||
void UpdateSrcList (SPicture* pCurPicture, const int32_t kiCurDid, SPicture** pShortRefList,
|
||||
const uint32_t kuiShortRefCount);
|
||||
void UpdateSrcListLosslessScreenRefSelectionWithLtr (SPicture* pCurPicture, const int32_t kiCurDid,
|
||||
const int32_t kuiMarkLongTermPicIdx, SPicture** pLongRefList);
|
||||
|
||||
private:
|
||||
int32_t WelsPreprocessCreate();
|
||||
@@ -158,6 +168,9 @@ class CWelsPreProcess {
|
||||
|
||||
ESceneChangeIdc DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPicture* pCurPicture);
|
||||
void InitPixMap (const SPicture* pPicture, SPixMap* pPixMap);
|
||||
void GetAvailableRefListLosslessScreenRefSelection (SPicture** pSrcPicList, uint8_t iCurTid,
|
||||
const int32_t iClosestLtrFrameNum,
|
||||
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum);
|
||||
void GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurTid, const int32_t iClosestLtrFrameNum,
|
||||
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum);
|
||||
void InitRefJudgement (SRefJudgement* pRefJudgement);
|
||||
@@ -168,6 +181,14 @@ class CWelsPreProcess {
|
||||
SRefInfoParam* pRefSaved);
|
||||
void SaveBestRefToVaa (SRefInfoParam& sRefSaved, SRefInfoParam* pVaaBestRef);
|
||||
|
||||
/*!
|
||||
* \brief exchange two picture pData planes
|
||||
* \param ppPic1 picture pointer to picture 1
|
||||
* \param ppPic2 picture pointer to picture 2
|
||||
* \return none
|
||||
*/
|
||||
void WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2);
|
||||
|
||||
private:
|
||||
Scaled_Picture m_sScaledPicture;
|
||||
SPicture* m_pLastSpatialPicture[MAX_DEPENDENCY_LAYER][2];
|
||||
@@ -178,8 +199,9 @@ class CWelsPreProcess {
|
||||
uint8_t m_uiSpatialPicNum[MAX_DEPENDENCY_LAYER];
|
||||
public:
|
||||
/* For Downsampling & VAA I420 based source pictures */
|
||||
SPicture* m_pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1 +
|
||||
LONG_TERM_REF_NUM]; // need memory requirement with total number of (log2(uiGopSize)+1+1+long_term_ref_num)
|
||||
SPicture* m_pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_REF_PIC_COUNT + 1];
|
||||
// need memory requirement with total number of num_of_ref + 1, "+1" is for current frame
|
||||
int32_t m_iAvaliableRefInSpatialPicList;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -218,7 +218,9 @@ int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam*
|
||||
WelsBlockFuncInit (&pFuncList->pfSetNZCZero, uiCpuFlag);
|
||||
|
||||
InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection);
|
||||
InitRefListMgrFunc (pFuncList, pParam->iUsageType);
|
||||
|
||||
InitRefListMgrFunc (pFuncList, pParam->bEnableLongTermReference, bScreenContent);
|
||||
|
||||
return iReturn;
|
||||
}
|
||||
|
||||
@@ -363,11 +365,13 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
|
||||
* \brief Dump reconstruction for dependency layer
|
||||
*/
|
||||
|
||||
extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend, SDqLayer* pDqLayer) {
|
||||
extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend,
|
||||
SDqLayer* pDqLayer) {
|
||||
WelsFileHandle* pDumpRecFile = NULL;
|
||||
int32_t iWrittenSize = 0;
|
||||
const char* openMode = bAppend ? "ab" : "wb";
|
||||
SWelsSPS* pSpsTmp = (kiDid> BASE_DEPENDENCY_ID)? &(pDqLayer->sLayerInfo.pSubsetSpsP->pSps) : pDqLayer->sLayerInfo.pSpsP;
|
||||
SWelsSPS* pSpsTmp = (kiDid > BASE_DEPENDENCY_ID) ? & (pDqLayer->sLayerInfo.pSubsetSpsP->pSps) :
|
||||
pDqLayer->sLayerInfo.pSpsP;
|
||||
bool bFrameCroppingFlag = pSpsTmp->bFrameCroppingFlag;
|
||||
SCropOffset* pFrameCrop = &pSpsTmp->sFrameCrop;
|
||||
|
||||
@@ -388,12 +392,15 @@ extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName
|
||||
int32_t i = 0;
|
||||
int32_t j = 0;
|
||||
const int32_t kiStrideY = pCurPicture->iLineSize[0];
|
||||
const int32_t kiLumaWidth = bFrameCroppingFlag?(pCurPicture->iWidthInPixel-(( pFrameCrop->iCropLeft + pFrameCrop->iCropRight ) << 1 )) : pCurPicture->iWidthInPixel;
|
||||
const int32_t kiLumaHeight = bFrameCroppingFlag?(pCurPicture->iHeightInPixel-(( pFrameCrop->iCropTop + pFrameCrop->iCropBottom ) << 1 )) : pCurPicture->iHeightInPixel;
|
||||
const int32_t kiLumaWidth = bFrameCroppingFlag ? (pCurPicture->iWidthInPixel - ((pFrameCrop->iCropLeft +
|
||||
pFrameCrop->iCropRight) << 1)) : pCurPicture->iWidthInPixel;
|
||||
const int32_t kiLumaHeight = bFrameCroppingFlag ? (pCurPicture->iHeightInPixel - ((pFrameCrop->iCropTop +
|
||||
pFrameCrop->iCropBottom) << 1)) : pCurPicture->iHeightInPixel;
|
||||
const int32_t kiChromaWidth = kiLumaWidth >> 1;
|
||||
const int32_t kiChromaHeight = kiLumaHeight >> 1;
|
||||
uint8_t* pSrc = NULL;
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * ( pFrameCrop->iCropTop << 1 ) + ( pFrameCrop->iCropLeft << 1 )) : pCurPicture->pData[0];
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * (pFrameCrop->iCropTop << 1) +
|
||||
(pFrameCrop->iCropLeft << 1)) : pCurPicture->pData[0];
|
||||
for (j = 0; j < kiLumaHeight; ++ j) {
|
||||
iWrittenSize = WelsFwrite (pSrc + j * kiStrideY, 1, kiLumaWidth, pDumpRecFile);
|
||||
assert (iWrittenSize == kiLumaWidth);
|
||||
@@ -405,7 +412,8 @@ extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName
|
||||
}
|
||||
for (i = 1; i < I420_PLANES; ++ i) {
|
||||
const int32_t kiStrideUV = pCurPicture->iLineSize[i];
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) : pCurPicture->pData[i];
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) :
|
||||
pCurPicture->pData[i];
|
||||
for (j = 0; j < kiChromaHeight; ++ j) {
|
||||
iWrittenSize = WelsFwrite (pSrc + j * kiStrideUV, 1, kiChromaWidth, pDumpRecFile);
|
||||
assert (iWrittenSize == kiChromaWidth);
|
||||
@@ -425,9 +433,11 @@ extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName
|
||||
* \brief Dump the reconstruction pictures
|
||||
*/
|
||||
|
||||
void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend, SDqLayer* pDqLayer) {
|
||||
void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend,
|
||||
SDqLayer* pDqLayer) {
|
||||
WelsFileHandle* pDumpRecFile = NULL;
|
||||
SWelsSPS* pSpsTmp = (kiDid> BASE_DEPENDENCY_ID)? &(pDqLayer->sLayerInfo.pSubsetSpsP->pSps) : pDqLayer->sLayerInfo.pSpsP;
|
||||
SWelsSPS* pSpsTmp = (kiDid > BASE_DEPENDENCY_ID) ? & (pDqLayer->sLayerInfo.pSubsetSpsP->pSps) :
|
||||
pDqLayer->sLayerInfo.pSpsP;
|
||||
bool bFrameCroppingFlag = pSpsTmp->bFrameCroppingFlag;
|
||||
SCropOffset* pFrameCrop = &pSpsTmp->sFrameCrop;
|
||||
|
||||
@@ -449,12 +459,15 @@ void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t k
|
||||
int32_t i = 0;
|
||||
int32_t j = 0;
|
||||
const int32_t kiStrideY = pCurPicture->iLineSize[0];
|
||||
const int32_t kiLumaWidth = bFrameCroppingFlag ? (pCurPicture->iWidthInPixel-(( pFrameCrop->iCropLeft + pFrameCrop->iCropRight ) << 1 )) : pCurPicture->iWidthInPixel;
|
||||
const int32_t kiLumaHeight = bFrameCroppingFlag ? (pCurPicture->iHeightInPixel-(( pFrameCrop->iCropTop + pFrameCrop->iCropBottom ) << 1 )) : pCurPicture->iHeightInPixel;
|
||||
const int32_t kiLumaWidth = bFrameCroppingFlag ? (pCurPicture->iWidthInPixel - ((pFrameCrop->iCropLeft +
|
||||
pFrameCrop->iCropRight) << 1)) : pCurPicture->iWidthInPixel;
|
||||
const int32_t kiLumaHeight = bFrameCroppingFlag ? (pCurPicture->iHeightInPixel - ((pFrameCrop->iCropTop +
|
||||
pFrameCrop->iCropBottom) << 1)) : pCurPicture->iHeightInPixel;
|
||||
const int32_t kiChromaWidth = kiLumaWidth >> 1;
|
||||
const int32_t kiChromaHeight = kiLumaHeight >> 1;
|
||||
uint8_t* pSrc = NULL;
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * ( pFrameCrop->iCropTop << 1 ) + ( pFrameCrop->iCropLeft << 1 )) : pCurPicture->pData[0];
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * (pFrameCrop->iCropTop << 1) +
|
||||
(pFrameCrop->iCropLeft << 1)) : pCurPicture->pData[0];
|
||||
for (j = 0; j < kiLumaHeight; ++ j) {
|
||||
iWrittenSize = WelsFwrite (pSrc + j * kiStrideY, 1, kiLumaWidth, pDumpRecFile);
|
||||
assert (iWrittenSize == kiLumaWidth);
|
||||
@@ -466,7 +479,8 @@ void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t k
|
||||
}
|
||||
for (i = 1; i < I420_PLANES; ++ i) {
|
||||
const int32_t kiStrideUV = pCurPicture->iLineSize[i];
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) : pCurPicture->pData[i];
|
||||
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) :
|
||||
pCurPicture->pData[i];
|
||||
for (j = 0; j < kiChromaHeight; ++ j) {
|
||||
iWrittenSize = WelsFwrite (pSrc + j * kiStrideUV, 1, kiChromaWidth, pDumpRecFile);
|
||||
assert (iWrittenSize == kiChromaWidth);
|
||||
|
||||
@@ -75,7 +75,6 @@ int32_t WelsCodeOnePicPartition (sWelsEncCtx* pCtx,
|
||||
* \return successful - 0; otherwise none 0 for failed
|
||||
*/
|
||||
int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||
float fMaxFrameRate = 0.0f;
|
||||
const float fEpsn = 0.000001f;
|
||||
int32_t i = 0;
|
||||
|
||||
@@ -128,28 +127,15 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
if (UINT_MAX == GetLogFactor (fDlp->fOutputFrameRate, fDlp->fInputFrameRate)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
"Invalid settings in input frame rate(%.6f) and output frame rate(%.6f) of layer #%d config file: iResult of output frame rate divided by input frame rate should be power of 2(i.e,in/pOut=2^n)..",
|
||||
fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i);
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"AUTO CORRECT: Invalid settings in input frame rate(%.6f) and output frame rate(%.6f) of layer #%d config file: iResult of output frame rate divided by input frame rate should be power of 2(i.e,in/pOut=2^n). \n Auto correcting Output Framerate to Input Framerate %f!\n",
|
||||
fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i, fDlp->fInputFrameRate);
|
||||
fDlp->fOutputFrameRate = fDlp->fInputFrameRate;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {
|
||||
SSpatialLayerInternal* fDlp = &pCfg->sDependencyLayers[i];
|
||||
if (fDlp->fInputFrameRate > fMaxFrameRate)
|
||||
fMaxFrameRate = fDlp->fInputFrameRate;
|
||||
}
|
||||
|
||||
if (fMaxFrameRate > fEpsn && (fMaxFrameRate - pCfg->fMaxFrameRate > fEpsn
|
||||
|| fMaxFrameRate - pCfg->fMaxFrameRate < -fEpsn)) {
|
||||
pCfg->fMaxFrameRate = fMaxFrameRate;
|
||||
}
|
||||
|
||||
|
||||
if ((pCfg->iRCMode != RC_OFF_MODE) && (pCfg->iRCMode != RC_QUALITY_MODE) && (pCfg->iRCMode != RC_BUFFERBASED_MODE)
|
||||
&& (pCfg->iRCMode != RC_BITRATE_MODE)
|
||||
&& (pCfg->iRCMode != RC_LOW_BW_MODE)) {
|
||||
&& (pCfg->iRCMode != RC_BITRATE_MODE)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidation(),Invalid iRCMode = %d", pCfg->iRCMode);
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
@@ -168,6 +154,12 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||
pSpatialLayer->iSpatialBitrate);
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
if (pSpatialLayer->iMaxSpatialBitrate < pSpatialLayer->iSpatialBitrate * 1.1f) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"MaxSpatialBitrate (%d) should set be larger than 1.1 times of SpatialBitrate (%d)",
|
||||
pSpatialLayer->iMaxSpatialBitrate, pSpatialLayer->iSpatialBitrate);
|
||||
// pSpatialLayer->iSpatialBitrate = (int32_t) (pSpatialLayer->iMaxSpatialBitrate/1.1f);
|
||||
}
|
||||
}
|
||||
if (iTotalBitrate > pCfg->iTargetBitrate) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
@@ -197,6 +189,12 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(),Invalid usage type = %d", pCodingParam->iUsageType);
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
if ((pCodingParam->iUsageType == SCREEN_CONTENT_REAL_TIME) && (!pCodingParam->bIsLosslessLink
|
||||
&& pCodingParam->bEnableLongTermReference)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"ParamValidationExt(), setting lossy link for LTR under screen, which is not supported yet! Auto disabled LTR!");
|
||||
pCodingParam->bEnableLongTermReference = false;
|
||||
}
|
||||
if (pCodingParam->iSpatialLayerNum < 1 || pCodingParam->iSpatialLayerNum > MAX_DEPENDENCY_LAYER) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->iSpatialLayerNum: %d!",
|
||||
pCodingParam->iSpatialLayerNum);
|
||||
@@ -358,7 +356,7 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum == 1) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"ParamValidationExt(), pSlice setting for SM_RASTER_SLICE now turn to SM_SINGLE_SLICE!");
|
||||
pSpatialLayer->sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
break;
|
||||
@@ -1255,7 +1253,7 @@ int32_t RequestMemoryVaaScreen (SVAAFrameInfo* pVaa, CMemoryAlign* pMa, const
|
||||
void ReleaseMemoryVaaScreen (SVAAFrameInfo* pVaa, CMemoryAlign* pMa, const int32_t iNumRef) {
|
||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pVaa);
|
||||
if (pVaaExt && pMa && pVaaExt->pVaaBlockStaticIdc[0]) {
|
||||
pMa->WelsFree (pVaaExt->pVaaBlockStaticIdc[0], "pVaa->pVaaBlockStaticIdc");
|
||||
pMa->WelsFree (pVaaExt->pVaaBlockStaticIdc[0], "pVaa->pVaaBlockStaticIdc[0]");
|
||||
|
||||
for (int32_t idx = 0; idx < iNumRef; idx++) {
|
||||
pVaaExt->pVaaBlockStaticIdc[idx] = NULL;
|
||||
@@ -1359,7 +1357,9 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
||||
iTargetSpatialBsSize = iLayerBsSize;
|
||||
iCountBsLen = iNonVclLayersBsSizeCount + iVclLayersBsSizeCount;
|
||||
|
||||
pParam->iNumRefFrame = WELS_CLIP3 (pParam->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
|
||||
pParam->iNumRefFrame = WELS_CLIP3 (pParam->iNumRefFrame, MIN_REF_PIC_COUNT,
|
||||
(pParam->iUsageType == CAMERA_VIDEO_REAL_TIME ? MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA :
|
||||
MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN));
|
||||
|
||||
// Output
|
||||
(*ppCtx)->pOut = (SWelsEncoderOutput*)pMa->WelsMalloc (sizeof (SWelsEncoderOutput), "SWelsEncoderOutput");
|
||||
@@ -1471,7 +1471,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
||||
}
|
||||
|
||||
(*ppCtx)->pVaa->pVaaBackgroundMbFlag = (int8_t*)pMa->WelsMallocz (iCountMaxMbNum * sizeof (int8_t),
|
||||
"pVaa->vaa_skip_mb_flag");
|
||||
"pVaa->pVaaBackgroundMbFlag");
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pVaa->pVaaBackgroundMbFlag), FreeMemorySvc (ppCtx))
|
||||
|
||||
(*ppCtx)->pVaa->sVaaCalcInfo.pSad8x8 = static_cast<int32_t (*)[4]>
|
||||
@@ -1489,10 +1489,10 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
||||
|
||||
if ((*ppCtx)->pSvcParam->bEnableBackgroundDetection) { //BGD control
|
||||
(*ppCtx)->pVaa->sVaaCalcInfo.pSumOfDiff8x8 = static_cast<int32_t (*)[4]>
|
||||
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (int32_t), "pVaa->sVaaCalcInfo.sd_16x16"));
|
||||
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (int32_t), "pVaa->sVaaCalcInfo.pSumOfDiff8x8"));
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pVaa->sVaaCalcInfo.pSumOfDiff8x8), FreeMemorySvc (ppCtx))
|
||||
(*ppCtx)->pVaa->sVaaCalcInfo.pMad8x8 = static_cast<uint8_t (*)[4]>
|
||||
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (uint8_t), "pVaa->sVaaCalcInfo.mad_16x16"));
|
||||
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (uint8_t), "pVaa->sVaaCalcInfo.pMad8x8"));
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pVaa->sVaaCalcInfo.pMad8x8), FreeMemorySvc (ppCtx))
|
||||
}
|
||||
|
||||
@@ -2015,6 +2015,13 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), ParamValidationExt failed return %d.", iRet);
|
||||
return iRet;
|
||||
}
|
||||
iRet = pCodingParam->DetermineTemporalSettings();
|
||||
if (iRet != ENC_RETURN_SUCCESS) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
"WelsInitEncoderExt(), DetermineTemporalSettings failed return %d (check in/out frame rate and temporal layer setting!)",
|
||||
iRet);
|
||||
return iRet;
|
||||
}
|
||||
iRet = GetMultipleThreadIdc (pLogCtx, pCodingParam, iSliceNum, iCacheLineSize, uiCpuFeatureFlags);
|
||||
if (iRet != 0) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), GetMultipleThreadIdc failed return %d.", iRet);
|
||||
@@ -2034,7 +2041,6 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
||||
pCtx->pMemAlign = new CMemoryAlign (iCacheLineSize);
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pCtx->pMemAlign), FreeMemorySvc (&pCtx))
|
||||
|
||||
pCodingParam->DetermineTemporalSettings();
|
||||
iRet = AllocCodingParam (&pCtx->pSvcParam, pCtx->pMemAlign);
|
||||
if (iRet != 0) {
|
||||
FreeMemorySvc (&pCtx);
|
||||
@@ -2083,6 +2089,8 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
||||
);
|
||||
#endif//MEMORY_MONITOR
|
||||
|
||||
pCtx->iStatisticsLogInterval = STATISTICS_LOG_INTERVAL_MS;
|
||||
|
||||
*ppCtx = pCtx;
|
||||
|
||||
WelsLog (pLogCtx, WELS_LOG_DEBUG, "WelsInitEncoderExt(), pCtx= 0x%p.", (void*)pCtx);
|
||||
@@ -2594,7 +2602,8 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
||||
pFeatureSearchPreparation->pRefBlockFeature = pScreenBlockFeatureStorage;
|
||||
if (pFeatureSearchPreparation->bFMESwitchFlag
|
||||
&& !pScreenBlockFeatureStorage->bRefBlockFeatureCalculated) {
|
||||
PerformFMEPreprocess (pFuncList, pCurLayer->pRefOri[0], pFeatureSearchPreparation->pFeatureOfBlock,
|
||||
SPicture* pRef = (pCtx->pSvcParam->bEnableLongTermReference ? pCurLayer->pRefOri[0] : pCurLayer->pRefPic);
|
||||
PerformFMEPreprocess (pFuncList, pRef, pFeatureSearchPreparation->pFeatureOfBlock,
|
||||
pScreenBlockFeatureStorage);
|
||||
}
|
||||
|
||||
@@ -2694,7 +2703,6 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
|
||||
if (uiNextIdInBs >= kuiMaxIdInBs) {
|
||||
uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT
|
||||
}
|
||||
|
||||
// update next_id
|
||||
sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs;
|
||||
}
|
||||
@@ -2952,18 +2960,18 @@ int32_t GetSubSequenceId (sWelsEncCtx* pCtx, EVideoFrameType eFrameType) {
|
||||
}
|
||||
|
||||
//loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
|
||||
bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pCtx, int32_t iSpatialNum) {
|
||||
bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
|
||||
const uint32_t uiTimeStamp) {
|
||||
SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
|
||||
bool bSkipMustFlag = false;
|
||||
if (pCtx->pSvcParam->bEnableFrameSkip) {
|
||||
if ((RC_QUALITY_MODE == pCtx->pSvcParam->iRCMode) || (RC_BITRATE_MODE == pCtx->pSvcParam->iRCMode)
|
||||
|| (RC_LOW_BW_MODE == pCtx->pSvcParam->iRCMode)) {
|
||||
if ((RC_QUALITY_MODE == pCtx->pSvcParam->iRCMode) || (RC_BITRATE_MODE == pCtx->pSvcParam->iRCMode)) {
|
||||
for (int32_t i = 0; i < iSpatialNum; i++) {
|
||||
if (0 == pCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
|
||||
break;
|
||||
}
|
||||
pCtx->uiDependencyId = (uint8_t) (pSpatialIndexMap + i)->iDid;
|
||||
pCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pCtx);
|
||||
pCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pCtx, eFrameType, uiTimeStamp);
|
||||
if (true == pCtx->pWelsSvcRc[pCtx->uiDependencyId].bSkipFlag) {
|
||||
bSkipMustFlag = true;
|
||||
break;
|
||||
@@ -3027,18 +3035,24 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
if (iSpatialNum < 1) { // skip due to temporal layer settings (different frame rate)
|
||||
++ pCtx->iCodingIndex;
|
||||
pFbi->eFrameType = videoFrameTypeSkip;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %8" PRId64", skip one frame",
|
||||
(int64_t)pSrcPic->uiTimeStamp);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
eFrameType = DecideFrameType (pCtx, iSpatialNum);
|
||||
if (eFrameType == videoFrameTypeSkip) {
|
||||
pFbi->eFrameType = eFrameType;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %8" PRId64", skip one frame",
|
||||
(int64_t)pSrcPic->uiTimeStamp);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
//loop each layer to check if have skip frame when RC and frame skip enable
|
||||
if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum)) {
|
||||
if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType, (uint32_t)pSrcPic->uiTimeStamp)) {
|
||||
pFbi->eFrameType = videoFrameTypeSkip;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %8" PRId64", skip one frame",
|
||||
(int64_t)pSrcPic->uiTimeStamp);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3166,6 +3180,9 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pCtx->iEncoderError = ENC_RETURN_CORRECTED;
|
||||
return ENC_RETURN_CORRECTED;
|
||||
}
|
||||
if (pCtx->eSliceType != I_SLICE) {
|
||||
pCtx->pFuncList->pAfterBuildRefList (pCtx);
|
||||
}
|
||||
#ifdef LONG_TERM_REF_DUMP
|
||||
DumpRef (pCtx);
|
||||
#endif
|
||||
@@ -3419,6 +3436,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
}
|
||||
|
||||
pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
|
||||
RcTraceFrameBits (pCtx, pSrcPic->uiTimeStamp);
|
||||
pCtx->pDecPic->iFrameAverageQp = pCtx->pWelsSvcRc->iAverageFrameQp;
|
||||
|
||||
//update scc related
|
||||
@@ -3438,7 +3456,14 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
}
|
||||
|
||||
iFrameSize += iLayerSize;
|
||||
|
||||
//check MinCr
|
||||
{
|
||||
int32_t iImageSize = (pParam->iVideoWidth * pParam->iVideoHeight * 3) >> 1;
|
||||
int32_t iMinCr = g_ksLevelLimits[pParam->uiLevelIdc - 1].uiMinCR;
|
||||
if (iFrameSize > (iImageSize / iMinCr))
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"WelsEncoderEncodeExt()MinCr Checking,codec bitstream size is larger than Level limitation");
|
||||
}
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
if (iCurDid + 1 < pSvcParam->iSpatialLayerNum) {
|
||||
DumpDependencyRec (fsnr, &pSvcParam->sDependencyLayers[iCurDid].sRecFileName[0], iCurDid,
|
||||
@@ -3720,6 +3745,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
uiTmpIdrPicId = (*ppCtx)->sPSOVector.uiIdrPicId;
|
||||
|
||||
SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;
|
||||
|
||||
WelsUninitEncoderExt (ppCtx);
|
||||
|
||||
/* Update new parameters */
|
||||
@@ -3730,14 +3757,18 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
|
||||
//if WelsInitEncoderExt succeed
|
||||
|
||||
//load back the needed structure
|
||||
//for FLEXIBLE_PARASET_ID
|
||||
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
(*ppCtx)->sPSOVector.uiIdrPicId = uiTmpIdrPicId;
|
||||
//for sEncoderStatistics
|
||||
(*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;
|
||||
} else {
|
||||
/* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
|
||||
pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,
|
||||
MAX_REFERENCE_PICTURE_COUNT_NUM);
|
||||
(pNewParam->iUsageType == CAMERA_VIDEO_REAL_TIME ? MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA :
|
||||
MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN));
|
||||
pNewParam->iLoopFilterDisableIdc = WELS_CLIP3 (pNewParam->iLoopFilterDisableIdc, 0, 6);
|
||||
pNewParam->iLoopFilterAlphaC0Offset = WELS_CLIP3 (pNewParam->iLoopFilterAlphaC0Offset, -6, 6);
|
||||
pNewParam->iLoopFilterBetaOffset = WELS_CLIP3 (pNewParam->iLoopFilterBetaOffset, -6, 6);
|
||||
@@ -3819,16 +3850,17 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue) {
|
||||
int32_t WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue) {
|
||||
SWelsSvcCodingParam sConfig;
|
||||
int32_t iNumRefFrame = 1;
|
||||
int32_t iRet = 0;
|
||||
memcpy (&sConfig, (*ppCtx)->pSvcParam, sizeof (SWelsSvcCodingParam));
|
||||
sConfig.bEnableLongTermReference = pLTRValue->bEnableLongTermReference;
|
||||
sConfig.iLTRRefNum = pLTRValue->iLTRRefNum;
|
||||
int32_t uiGopSize = 1 << (sConfig.iTemporalLayerNum - 1);
|
||||
if (sConfig.iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
if (sConfig.bEnableLongTermReference) {
|
||||
sConfig.iLTRRefNum = WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM_SCREEN);
|
||||
sConfig.iLTRRefNum = LONG_TERM_REF_NUM_SCREEN;//WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM_SCREEN);
|
||||
iNumRefFrame = WELS_MAX (1, WELS_LOG2 (uiGopSize)) + sConfig.iLTRRefNum;
|
||||
} else {
|
||||
sConfig.iLTRRefNum = 0;
|
||||
@@ -3836,13 +3868,13 @@ void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig*
|
||||
}
|
||||
} else {
|
||||
if (sConfig.bEnableLongTermReference) {
|
||||
sConfig.iLTRRefNum = WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM);
|
||||
sConfig.iLTRRefNum = LONG_TERM_REF_NUM;//WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM);
|
||||
} else {
|
||||
sConfig.iLTRRefNum = 0;
|
||||
}
|
||||
iNumRefFrame = ((uiGopSize >> 1) > 1) ? ((uiGopSize >> 1) + sConfig.iLTRRefNum) : (MIN_REF_PIC_COUNT +
|
||||
sConfig.iLTRRefNum);
|
||||
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
|
||||
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA);
|
||||
|
||||
}
|
||||
if (sConfig.iNumRefFrame < iNumRefFrame)
|
||||
@@ -3852,7 +3884,8 @@ void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig*
|
||||
|
||||
WelsLog (pLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable LTR = %d,ltrnum = %d",
|
||||
sConfig.bEnableLongTermReference, sConfig.iLTRRefNum);
|
||||
WelsEncoderParamAdjust (ppCtx, &sConfig);
|
||||
iRet = WelsEncoderParamAdjust (ppCtx, &sConfig);
|
||||
return iRet;
|
||||
}
|
||||
int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
|
||||
SFrameBSInfo* pFrameBsInfo,
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
*/
|
||||
#include "ls_defines.h"
|
||||
#include "cpu_core.h"
|
||||
#include "intra_pred_common.h"
|
||||
#include "get_intra_predictor.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
@@ -538,37 +539,6 @@ void WelsIChromaPredDcNA_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStrid
|
||||
}
|
||||
|
||||
|
||||
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
|
||||
uint8_t i = 15;
|
||||
const int8_t* kpSrc = (int8_t*)&pRef[-kiStride];
|
||||
const uint64_t kuiT1 = LD64 (kpSrc);
|
||||
const uint64_t kuiT2 = LD64 (kpSrc + 8);
|
||||
uint8_t* pDst = pPred;
|
||||
|
||||
do {
|
||||
ST64 (pDst , kuiT1);
|
||||
ST64 (pDst + 8, kuiT2);
|
||||
pDst += 16;
|
||||
} while (i-- > 0);
|
||||
}
|
||||
|
||||
void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
|
||||
int32_t iStridex15 = (kiStride << 4) - kiStride;
|
||||
int32_t iPredStride = 16;
|
||||
int32_t iPredStridex15 = 240; //(iPredStride<<4)-iPredStride;
|
||||
uint8_t i = 15;
|
||||
|
||||
do {
|
||||
const uint8_t kuiSrc8 = pRef[iStridex15 - 1];
|
||||
const uint64_t kuiV64 = (uint64_t) (0x0101010101010101ULL * kuiSrc8);
|
||||
ST64 (&pPred[iPredStridex15], kuiV64);
|
||||
ST64 (&pPred[iPredStridex15 + 8], kuiV64);
|
||||
|
||||
iStridex15 -= kiStride;
|
||||
iPredStridex15 -= iPredStride;
|
||||
} while (i-- > 0);
|
||||
}
|
||||
|
||||
void WelsI16x16LumaPredPlane_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
|
||||
int32_t iLTshift = 0, iTopshift = 0, iLeftshift = 0, iTopSum = 0, iLeftSum = 0;
|
||||
int32_t i, j;
|
||||
|
||||
@@ -98,7 +98,7 @@ SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth , const int32_t
|
||||
pPic->uiRefMbType = (uint32_t*)pMa->WelsMallocz (kuiCountMbNum * sizeof (uint32_t), "pPic->uiRefMbType");
|
||||
WELS_VERIFY_RETURN_PROC_IF (NULL, NULL == pPic->uiRefMbType, FreePicture (pMa, &pPic));
|
||||
|
||||
pPic->pRefMbQp = (uint8_t*)pMa->WelsMallocz (kuiCountMbNum * sizeof (uint8_t), "pPic->bgd_mb_qp");
|
||||
pPic->pRefMbQp = (uint8_t*)pMa->WelsMallocz (kuiCountMbNum * sizeof (uint8_t), "pPic->pRefMbQp");
|
||||
WELS_VERIFY_RETURN_PROC_IF (NULL, NULL == pPic->pRefMbQp, FreePicture (pMa, &pPic));
|
||||
|
||||
pPic->sMvList = static_cast<SMVUnitXY*> (pMa->WelsMallocz (kuiCountMbNum * sizeof (SMVUnitXY),
|
||||
@@ -152,11 +152,11 @@ void FreePicture (CMemoryAlign* pMa, SPicture** ppPic) {
|
||||
pPic->iMarkFrameNum = -1;
|
||||
|
||||
if (pPic->uiRefMbType) {
|
||||
pMa->WelsFree (pPic->uiRefMbType, "pPic->bgd_mb_type");
|
||||
pMa->WelsFree (pPic->uiRefMbType, "pPic->uiRefMbType");
|
||||
pPic->uiRefMbType = NULL;
|
||||
}
|
||||
if (pPic->pRefMbQp) {
|
||||
pMa->WelsFree (pPic->pRefMbQp, "pPic->bgd_mb_qp");
|
||||
pMa->WelsFree (pPic->pRefMbQp, "pPic->pRefMbQp");
|
||||
pPic->pRefMbQp = NULL;
|
||||
}
|
||||
|
||||
@@ -179,20 +179,6 @@ void FreePicture (CMemoryAlign* pMa, SPicture** ppPic) {
|
||||
*ppPic = NULL;
|
||||
}
|
||||
}
|
||||
/*!
|
||||
* \brief exchange two picture pData planes
|
||||
* \param ppPic1 picture pointer to picture 1
|
||||
* \param ppPic2 picture pointer to picture 2
|
||||
* \return none
|
||||
*/
|
||||
void WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2) {
|
||||
SPicture* tmp = *ppPic1;
|
||||
|
||||
assert (*ppPic1 != *ppPic2);
|
||||
|
||||
*ppPic1 = *ppPic2;
|
||||
*ppPic2 = tmp;
|
||||
}
|
||||
|
||||
} // namespace WelsEnc
|
||||
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
|
||||
#define VIRTUAL_BUFFER_LOW_TH 120 //*INT_MULTIPLY
|
||||
#define VIRTUAL_BUFFER_HIGH_TH 180 //*INT_MULTIPLY
|
||||
|
||||
//#define _TEST_TEMP_RC_
|
||||
#ifdef _TEST_TEMP_RC_
|
||||
//#define _NOT_USE_AQ_FOR_TEST_
|
||||
@@ -70,7 +74,7 @@ void RcInitLayerMemory (SWelsSvcRc* pWelsSvcRc, CMemoryAlign* pMA, const int32_t
|
||||
const int32_t kiGomSizeD = kiGomSize * sizeof (double);
|
||||
const int32_t kiGomSizeI = kiGomSize * sizeof (int32_t);
|
||||
const int32_t kiLayerRcSize = kiGomSizeD + (kiGomSizeI * 3) + sizeof (SRCTemporal) * kiMaxTl;
|
||||
uint8_t* pBaseMem = (uint8_t*)pMA->WelsMalloc (kiLayerRcSize, "rc_layer_memory");
|
||||
uint8_t* pBaseMem = (uint8_t*)pMA->WelsMalloc (kiLayerRcSize, "pWelsSvcRc->pTemporalOverRc");
|
||||
|
||||
if (NULL == pBaseMem)
|
||||
return;
|
||||
@@ -94,7 +98,7 @@ void RcFreeLayerMemory (SWelsSvcRc* pWelsSvcRc, CMemoryAlign* pMA) {
|
||||
pWelsSvcRc->pSlicingOverRc = NULL;
|
||||
}
|
||||
if (pWelsSvcRc != NULL && pWelsSvcRc->pTemporalOverRc != NULL) {
|
||||
pMA->WelsFree (pWelsSvcRc->pTemporalOverRc, "rc_layer_memory");
|
||||
pMA->WelsFree (pWelsSvcRc->pTemporalOverRc, "pWelsSvcRc->pTemporalOverRc");
|
||||
pWelsSvcRc->pTemporalOverRc = NULL;
|
||||
pWelsSvcRc->pGomComplexity = NULL;
|
||||
pWelsSvcRc->pGomForegroundBlockNum = NULL;
|
||||
@@ -512,7 +516,7 @@ void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {
|
||||
iLumaQp = WELS_DIV_ROUND (iLumaQp * INT_MULTIPLY - pEncCtx->pVaa->sAdaptiveQuantParam.iAverMotionTextureIndexToDeltaQp,
|
||||
INT_MULTIPLY);
|
||||
|
||||
if (pEncCtx->pSvcParam->iRCMode != RC_LOW_BW_MODE)
|
||||
if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false)))
|
||||
iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
|
||||
|
||||
}
|
||||
@@ -554,10 +558,9 @@ void RcDecideTargetBits (sWelsEncCtx* pEncCtx) {
|
||||
pWelsSvcRc->iRemainingWeights);
|
||||
else //this case should be not hit. needs to more test case to verify this
|
||||
pWelsSvcRc->iTargetBits = pWelsSvcRc->iRemainingBits;
|
||||
if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) {
|
||||
if ((pWelsSvcRc->iTargetBits <= 0) && ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE)
|
||||
&& (pEncCtx->pSvcParam->bEnableFrameSkip == false))) {
|
||||
pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED;
|
||||
} else if ((pWelsSvcRc->iTargetBits <= pTOverRc->iMinBitsTl) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) {
|
||||
pWelsSvcRc->iCurrentBitsLevel = BITS_LIMITED;
|
||||
}
|
||||
pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl);
|
||||
}
|
||||
@@ -572,6 +575,8 @@ void RcInitGomParameters (sWelsEncCtx* pEncCtx) {
|
||||
const int32_t kiGlobalQp = pEncCtx->iGlobalQp;
|
||||
|
||||
pWelsSvcRc->iAverageFrameQp = 0;
|
||||
pWelsSvcRc->iMinFrameQp = 51;;
|
||||
pWelsSvcRc->iMaxFrameQp = 0;
|
||||
for (int32_t i = 0; i < kiSliceNum; ++i) {
|
||||
pSOverRc->iComplexityIndexSlice = 0;
|
||||
pSOverRc->iCalculatedQpSlice = kiGlobalQp;
|
||||
@@ -683,7 +688,7 @@ void RcCalculateGomQp (sWelsEncCtx* pEncCtx, SMB* pCurMb, int32_t iSliceId) {
|
||||
|
||||
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice,
|
||||
pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame);
|
||||
if (! (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE))
|
||||
if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false)))
|
||||
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
|
||||
|
||||
pSOverRc->iGomBitsSlice = 0;
|
||||
@@ -696,6 +701,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|
||||
const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
|
||||
//condition 1: whole pBuffer fullness
|
||||
pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
|
||||
//condition 2: VGOP bits constraint
|
||||
int32_t iVGopBitsPred = 0;
|
||||
for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++)
|
||||
@@ -709,20 +715,19 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|
||||
|| (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
|
||||
pEncCtx->iSkipFrameFlag = 1;
|
||||
pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits;
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "skip one frame");
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
|
||||
}
|
||||
|
||||
if (pWelsSvcRc->iBufferFullnessSkip < 0)
|
||||
pWelsSvcRc->iBufferFullnessSkip = 0;
|
||||
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
|
||||
|
||||
if (pEncCtx->iSkipFrameFlag == 1) {
|
||||
pWelsSvcRc->iRemainingBits += WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
|
||||
pWelsSvcRc->iRemainingBits += kiOutputBits;
|
||||
pWelsSvcRc->iSkipFrameNum++;
|
||||
pWelsSvcRc->iSkipFrameInVGop++;
|
||||
}
|
||||
}
|
||||
|
||||
void WelsRcFrameDelayJudge (void* pCtx) {
|
||||
void WelsRcFrameDelayJudge (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
||||
SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
|
||||
@@ -733,7 +738,10 @@ void WelsRcFrameDelayJudge (void* pCtx) {
|
||||
pWelsSvcRc->bSkipFlag = false;
|
||||
if (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip) {
|
||||
pWelsSvcRc->bSkipFlag = true;
|
||||
pWelsSvcRc->iSkipFrameNum++;
|
||||
pWelsSvcRc->iSkipFrameInVGop++;
|
||||
pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
|
||||
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
|
||||
}
|
||||
}
|
||||
@@ -754,14 +762,17 @@ void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
|
||||
}
|
||||
|
||||
|
||||
void RcTraceFrameBits (sWelsEncCtx* pEncCtx) {
|
||||
void RcTraceFrameBits (void* pCtx, long long uiTimeStamp) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
||||
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"[Rc] encoding_qp%d, qp = %3d, index = %8d, iTid = %1d, used = %8d, target = %8d, remaingbits = %8d",
|
||||
pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp, pEncCtx->iFrameIndex, pEncCtx->uiTemporalId,
|
||||
pWelsSvcRc->iFrameDqBits,
|
||||
pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits);
|
||||
"[Rc] Frame timestamp = %8d, Frame type =%d, encoding_qp%d, average qp = %3d, max qp = %3d, min qp = %3d, index = %8d,\
|
||||
iTid = %1d, used = %8d, bitsperframe = %8d, target = %8d, remaingbits = %8d, skipbuffersize = %8d",
|
||||
(uint32_t)uiTimeStamp,pEncCtx->eSliceType, pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp,pWelsSvcRc->iMaxFrameQp,pWelsSvcRc->iMinFrameQp,
|
||||
pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits,WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY),
|
||||
pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits, pWelsSvcRc->iBufferSizeSkip);
|
||||
|
||||
}
|
||||
|
||||
void RcUpdatePictureQpBits (sWelsEncCtx* pEncCtx, int32_t iCodedBits) {
|
||||
@@ -872,10 +883,10 @@ void WelsRcPictureInitGom (void* pCtx) {
|
||||
|
||||
|
||||
|
||||
void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t layer_size) {
|
||||
void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t iLayerSize) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
||||
int32_t iCodedBits = (layer_size << 3);
|
||||
int32_t iCodedBits = (iLayerSize << 3);
|
||||
|
||||
RcUpdatePictureQpBits (pEncCtx, iCodedBits);
|
||||
|
||||
@@ -886,8 +897,6 @@ void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t layer_size) {
|
||||
}
|
||||
pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits;
|
||||
|
||||
RcTraceFrameBits (pEncCtx);
|
||||
|
||||
if (pEncCtx->pSvcParam->bEnableFrameSkip /*&&
|
||||
pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1*/) {
|
||||
RcVBufferCalculationSkip (pEncCtx);
|
||||
@@ -940,13 +949,15 @@ void WelsRcMbInfoUpdateGom (void* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice*
|
||||
SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[iSliceId];
|
||||
const int32_t kiComplexityIndex = pSOverRc->iComplexityIndexSlice;
|
||||
|
||||
int32_t cur_mb_bits = BsGetBitsPos (bs) - pSOverRc->iBsPosSlice;
|
||||
pSOverRc->iFrameBitsSlice += cur_mb_bits;
|
||||
pSOverRc->iGomBitsSlice += cur_mb_bits;
|
||||
int32_t iCurMbBits = BsGetBitsPos (bs) - pSOverRc->iBsPosSlice;
|
||||
pSOverRc->iFrameBitsSlice += iCurMbBits;
|
||||
pSOverRc->iGomBitsSlice += iCurMbBits;
|
||||
|
||||
pWelsSvcRc->pGomCost[kiComplexityIndex] += iCostLuma;
|
||||
|
||||
if (cur_mb_bits > 0) {
|
||||
pWelsSvcRc->iMinFrameQp = WELS_MIN(pWelsSvcRc->iMinFrameQp,pCurMb->uiLumaQp);
|
||||
pWelsSvcRc->iMaxFrameQp = WELS_MAX(pWelsSvcRc->iMaxFrameQp,pCurMb->uiLumaQp);
|
||||
if (iCurMbBits > 0) {
|
||||
pSOverRc->iTotalQpSlice += pCurMb->uiLumaQp;
|
||||
pSOverRc->iTotalMbSlice++;
|
||||
}
|
||||
@@ -970,7 +981,7 @@ void WelsRcPictureInitDisable (void* pCtx) {
|
||||
pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
|
||||
}
|
||||
|
||||
void WelsRcPictureInfoUpdateDisable (void* pCtx, int32_t layer_size) {
|
||||
void WelsRcPictureInfoUpdateDisable (void* pCtx, int32_t iLayerSize) {
|
||||
}
|
||||
|
||||
void WelsRcMbInitDisable (void* pCtx, SMB* pCurMb, SSlice* pSlice) {
|
||||
@@ -1011,6 +1022,147 @@ void WelRcPictureInitBufferBasedQp (void* pCtx) {
|
||||
pEncCtx->iGlobalQp += 2;
|
||||
pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, iMinQp, MAX_SCREEN_QP);
|
||||
}
|
||||
|
||||
void InitRcModuleScc (void* pCtx) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
||||
pWelsSvcRc->iBaseQp = 30;
|
||||
|
||||
pWelsSvcRc->iBufferFullnessSkip = 0;
|
||||
pWelsSvcRc->uiLastTimeStamp = 0;
|
||||
|
||||
pWelsSvcRc->iCost2BitsIntra = INT_MULTIPLY;
|
||||
pWelsSvcRc->iAvgCost2Bits = INT_MULTIPLY;
|
||||
}
|
||||
void WelRcPictureInitScc (void* pCtx) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
||||
SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa);
|
||||
SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
|
||||
int32_t iFrameCplx = pVaa->sComplexityScreenParam.iFrameComplexity;
|
||||
int32_t iBitRate = pDLayerConfig->iSpatialBitrate;// pEncCtx->pSvcParam->target_bitrate;
|
||||
|
||||
int32_t iBaseQp = pWelsSvcRc->iBaseQp;
|
||||
pEncCtx->iGlobalQp = iBaseQp;
|
||||
int32_t iDeltaQp = 0;
|
||||
if (pEncCtx->eSliceType == I_SLICE) {
|
||||
int32_t iTargetBits = iBitRate * 2 - pWelsSvcRc->iBufferFullnessSkip;
|
||||
iTargetBits = WELS_MAX (1, iTargetBits);
|
||||
int32_t iQstep = WELS_DIV_ROUND ((((int64_t)iFrameCplx) * pWelsSvcRc->iCost2BitsIntra), iTargetBits);
|
||||
int32_t iQp = RcConvertQStep2Qp (iQstep);
|
||||
|
||||
pEncCtx->iGlobalQp = WELS_CLIP3 (iQp, MIN_IDR_QP, MAX_IDR_QP);
|
||||
} else {
|
||||
int32_t iTargetBits = WELS_ROUND (((float)iBitRate / pDLayerConfig->fFrameRate)); //iBitRate / 10;
|
||||
int32_t iQstep = (int32_t)(WELS_DIV_ROUND64 (iFrameCplx * pWelsSvcRc->iAvgCost2Bits, iTargetBits));
|
||||
int32_t iQp = RcConvertQStep2Qp (iQstep);
|
||||
iDeltaQp = iQp - iBaseQp;
|
||||
if (pWelsSvcRc->iBufferFullnessSkip > iBitRate) {
|
||||
if (iDeltaQp > 0) {
|
||||
++iBaseQp;
|
||||
}
|
||||
} else if (pWelsSvcRc->iBufferFullnessSkip == 0) {
|
||||
if (iDeltaQp < 0) {
|
||||
--iBaseQp;
|
||||
}
|
||||
}
|
||||
if (iDeltaQp >= 6) {
|
||||
iBaseQp += 3;
|
||||
} else if ((iDeltaQp <= -6)) {
|
||||
--iBaseQp;
|
||||
}
|
||||
iBaseQp = WELS_CLIP3 (iBaseQp, MIN_IDR_QP, MAX_IDR_QP);
|
||||
|
||||
pEncCtx->iGlobalQp = iBaseQp;
|
||||
|
||||
|
||||
if (iDeltaQp < -6) {
|
||||
pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp - 6, MIN_SCREEN_QP, MAX_SCREEN_QP);
|
||||
}
|
||||
|
||||
if (iDeltaQp > 5) {
|
||||
if (LARGE_CHANGED_SCENE == pEncCtx->pVaa->eSceneChangeIdc || pWelsSvcRc->iBufferFullnessSkip > 2 * iBitRate
|
||||
|| iDeltaQp > 10) {
|
||||
pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp + iDeltaQp, MIN_SCREEN_QP, MAX_SCREEN_QP);
|
||||
} else if (MEDIUM_CHANGED_SCENE == pEncCtx->pVaa->eSceneChangeIdc || pWelsSvcRc->iBufferFullnessSkip > iBitRate) {
|
||||
pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp + 5, MIN_SCREEN_QP, MAX_SCREEN_QP);
|
||||
}
|
||||
}
|
||||
pWelsSvcRc->iBaseQp = iBaseQp;
|
||||
}
|
||||
pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, "WelRcPictureInitScc iLumaQp = %d\n", pEncCtx->iGlobalQp);
|
||||
|
||||
}
|
||||
void WelsRcFrameDelayJudgeScc (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
|
||||
SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
|
||||
|
||||
if (pDLayerConfig->iSpatialBitrate > pDLayerConfig->iMaxSpatialBitrate)
|
||||
pDLayerConfig->iSpatialBitrate = pDLayerConfig->iMaxSpatialBitrate;
|
||||
|
||||
int32_t iBitRate = pDLayerConfig->iSpatialBitrate;
|
||||
int32_t iEncTimeInv = (pWelsSvcRc->uiLastTimeStamp == 0) ? 0 : (int32_t) (uiTimeStamp - pWelsSvcRc->uiLastTimeStamp);
|
||||
int32_t iSentBits = (int32_t) ((double)iBitRate * iEncTimeInv * (1.0E-3) + 0.5);
|
||||
iSentBits = WELS_MAX (iSentBits, 0);
|
||||
|
||||
const int32_t iVbufferThRatio = (eFrameType == videoFrameTypeI
|
||||
|| eFrameType == videoFrameTypeIDR) ? VIRTUAL_BUFFER_HIGH_TH : VIRTUAL_BUFFER_LOW_TH;
|
||||
const int32_t iVbufferTh = WELS_DIV_ROUND ((((int64_t)iBitRate) * iVbufferThRatio), INT_MULTIPLY);
|
||||
|
||||
pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
|
||||
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip);
|
||||
|
||||
pWelsSvcRc->bSkipFlag = true;
|
||||
if (pWelsSvcRc->iBufferFullnessSkip < iVbufferTh) {
|
||||
pWelsSvcRc->bSkipFlag = false;
|
||||
}
|
||||
if (pWelsSvcRc->bSkipFlag) {
|
||||
pWelsSvcRc->iSkipFrameNum++;
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "SCC iSkipFrameNum = %d,buffer = %d,threadhold = %d,bitrate = %d,timestamp=%lld\n", pWelsSvcRc->iSkipFrameNum,pWelsSvcRc->iBufferFullnessSkip,iVbufferTh,iBitRate,uiTimeStamp);
|
||||
}
|
||||
pWelsSvcRc->uiLastTimeStamp = uiTimeStamp;
|
||||
}
|
||||
|
||||
void WelsRcDropFrameUpdate (void* pCtx, uint32_t iDropSize) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
|
||||
|
||||
pWelsSvcRc->iBufferFullnessSkip -= (int32_t)iDropSize;
|
||||
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip);
|
||||
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "[WelsRcDropFrameUpdate:\tdrop:%d\t%d\n", iDropSize,
|
||||
pWelsSvcRc->iBufferFullnessSkip);
|
||||
}
|
||||
|
||||
void WelsRcPictureInfoUpdateScc (void* pCtx, int32_t iNalSize) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
|
||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
|
||||
int32_t iFrameBits = (iNalSize << 3);
|
||||
pWelsSvcRc->iBufferFullnessSkip += iFrameBits;
|
||||
|
||||
SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa);
|
||||
|
||||
int32_t iQstep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
|
||||
int64_t iCost2Bits = WELS_DIV_ROUND64 ((((int64_t)iFrameBits * iQstep)), pVaa->sComplexityScreenParam.iFrameComplexity);
|
||||
|
||||
if (pEncCtx->eSliceType == P_SLICE) {
|
||||
pWelsSvcRc->iAvgCost2Bits = WELS_DIV_ROUND64 ((95 * pWelsSvcRc->iAvgCost2Bits + 5 * iCost2Bits), INT_MULTIPLY);
|
||||
} else {
|
||||
pWelsSvcRc->iCost2BitsIntra = WELS_DIV_ROUND64 ((90 * pWelsSvcRc->iCost2BitsIntra + 10 * iCost2Bits), INT_MULTIPLY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WelsRcMbInitScc (void* pCtx, SMB* pCurMb, SSlice* pSlice) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
|
||||
/* Get delta iQp of this MB */
|
||||
pCurMb->uiLumaQp = pEncCtx->iGlobalQp;
|
||||
pCurMb->uiChromaQp = g_kuiChromaQpTable[WELS_CLIP3 (pCurMb->uiLumaQp + pEncCtx->pPps->uiChromaQpIndexOffset, 0, 51)];
|
||||
}
|
||||
|
||||
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
SWelsRcFunc* pRcf = &pEncCtx->pFuncList->pfRc;
|
||||
@@ -1030,9 +1182,24 @@ void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) {
|
||||
pRcf->pfWelsRcMbInit = WelsRcMbInitDisable;
|
||||
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable;
|
||||
break;
|
||||
case RC_QUALITY_MODE:
|
||||
case RC_BITRATE_MODE:
|
||||
case RC_LOW_BW_MODE:
|
||||
if (pEncCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
pRcf->pfWelsRcPictureInit = WelRcPictureInitScc;
|
||||
pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudgeScc;
|
||||
pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateScc;
|
||||
pRcf->pfWelsRcMbInit = WelsRcMbInitScc;
|
||||
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable;
|
||||
InitRcModuleScc (pEncCtx);
|
||||
|
||||
} else {
|
||||
pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom;
|
||||
pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge;
|
||||
pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateGom;
|
||||
pRcf->pfWelsRcMbInit = WelsRcMbInitGom;
|
||||
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateGom;
|
||||
}
|
||||
break;
|
||||
case RC_QUALITY_MODE:
|
||||
default:
|
||||
pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom;
|
||||
pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge;
|
||||
|
||||
@@ -35,25 +35,6 @@
|
||||
#include "utils.h"
|
||||
#include "picture_handle.h"
|
||||
namespace WelsEnc {
|
||||
/*
|
||||
* set picture as unreferenced
|
||||
*/
|
||||
void SetUnref (SPicture* pRef) {
|
||||
if (NULL != pRef) {
|
||||
pRef->iFramePoc = -1;
|
||||
pRef->iFrameNum = -1;
|
||||
pRef->uiTemporalId =
|
||||
pRef->uiSpatialId =
|
||||
pRef->iLongTermPicNum = -1;
|
||||
pRef->bIsLongRef = false;
|
||||
pRef->uiRecieveConfirmed = RECIEVE_FAILED;
|
||||
pRef->iMarkFrameNum = -1;
|
||||
pRef->bUsedAsRef = false;
|
||||
|
||||
if (NULL != pRef->pScreenBlockFeatureStorage)
|
||||
pRef->pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* reset LTR marking , recovery ,feedback state to default
|
||||
@@ -87,10 +68,10 @@ void WelsResetRefList (sWelsEncCtx* pCtx) {
|
||||
|
||||
for (i = 0; i < MAX_SHORT_REF_COUNT + 1; i++)
|
||||
pRefList->pShortRefList[i] = NULL;
|
||||
for (i = 0; i < MAX_LONG_REF_COUNT + 1; i++)
|
||||
for (i = 0; i < pCtx->pSvcParam->iLTRRefNum + 1; i++)
|
||||
pRefList->pLongRefList[i] = NULL;
|
||||
for (i = 0; i < pCtx->pSvcParam->iNumRefFrame + 1; i++)
|
||||
SetUnref (pRefList->pRef[i]);
|
||||
pRefList->pRef[i]->SetUnref();
|
||||
|
||||
pRefList->uiLongRefCount = 0;
|
||||
pRefList->uiShortRefCount = 0;
|
||||
@@ -125,7 +106,7 @@ static void DeleteNonSceneLTR (sWelsEncCtx* pCtx) {
|
||||
SPicture* pRef = pRefList->pLongRefList[i];
|
||||
if (pRef != NULL && pRef->bUsedAsRef && pRef->bIsLongRef && (!pRef->bIsSceneLTR) &&
|
||||
(pCtx->uiTemporalId < pRef->uiTemporalId || pCtx->bCurFrameMarkedAsSceneLtr)) {
|
||||
SetUnref (pRef);
|
||||
pRef->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, i);
|
||||
i--;
|
||||
}
|
||||
@@ -181,7 +162,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
|
||||
iMaxFrameNumPlus1) & (FRAME_NUM_EQUAL | FRAME_NUM_SMALLER))) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "LTR ,invalid LTR delete ,long_term_idx = %d , iFrameNum =%d ",
|
||||
pLongRefList[i]->iLongTermPicNum, pLongRefList[i]->iFrameNum);
|
||||
SetUnref (pLongRefList[i]);
|
||||
pLongRefList[i]->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, i);
|
||||
pLtr->bLTRMarkEnable = true;
|
||||
if (pRefList->uiLongRefCount == 0) {
|
||||
@@ -194,7 +175,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
|
||||
&& pLtr->iLTRMarkMode == LTR_DELAY_MARK) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "LTR ,iMarkFrameNum invalid LTR delete ,long_term_idx = %d , iFrameNum =%d ",
|
||||
pLongRefList[i]->iLongTermPicNum, pLongRefList[i]->iFrameNum);
|
||||
SetUnref (pLongRefList[i]);
|
||||
pLongRefList[i]->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, i);
|
||||
pLtr->bLTRMarkEnable = true;
|
||||
if (pRefList->uiLongRefCount == 0) {
|
||||
@@ -230,7 +211,7 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
|
||||
|
||||
for (j = 0; j < pRefList->uiLongRefCount; j++) {
|
||||
if (pLongRefList[j]->iLongTermPicNum != pLtr->iCurLtrIdx) {
|
||||
SetUnref (pLongRefList[j]);
|
||||
pLongRefList[j]->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, j);
|
||||
}
|
||||
}
|
||||
@@ -247,7 +228,7 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
|
||||
} else if (pLtr->uiLtrMarkState == LTR_MARKING_FAILED) {
|
||||
for (i = 0; i < pRefList->uiLongRefCount; i++) {
|
||||
if (pLongRefList[i]->iFrameNum == pLtr->iLtrMarkFbFrameNum) {
|
||||
SetUnref (pLongRefList[i]);
|
||||
pLongRefList[i]->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, i);
|
||||
break;
|
||||
}
|
||||
@@ -316,7 +297,7 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
|
||||
pLongRefList[0] = pShortRefList[i];
|
||||
pRefList->uiLongRefCount++;
|
||||
if (pRefList->uiLongRefCount > pCtx->pSvcParam->iLTRRefNum) {
|
||||
SetUnref (pRefList->pLongRefList[pRefList->uiLongRefCount - 1]);
|
||||
pRefList->pLongRefList[pRefList->uiLongRefCount - 1]->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, pRefList->uiLongRefCount - 1);
|
||||
}
|
||||
DeleteSTRFromShortList (pCtx, i);
|
||||
@@ -330,14 +311,15 @@ static inline void LTRMarkProcessScreen (sWelsEncCtx* pCtx) {
|
||||
pCtx->pVaa->uiMarkLongTermPicIdx = pCtx->pDecPic->iLongTermPicNum;
|
||||
|
||||
if (pLongRefList[iLtrIdx] != NULL) {
|
||||
SetUnref (pLongRefList[iLtrIdx]);
|
||||
pLongRefList[iLtrIdx]->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, iLtrIdx);
|
||||
}
|
||||
pLongRefList[iLtrIdx] = pCtx->pDecPic;
|
||||
pRefList->uiLongRefCount++;
|
||||
}
|
||||
|
||||
static inline void PrefetchNextBuffer (sWelsEncCtx* pCtx) {
|
||||
static void PrefetchNextBuffer (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
|
||||
const int32_t kiNumRef = pCtx->pSvcParam->iNumRefFrame;
|
||||
int32_t i;
|
||||
@@ -352,7 +334,7 @@ static inline void PrefetchNextBuffer (sWelsEncCtx* pCtx) {
|
||||
|
||||
if (pRefList->pNextBuffer == NULL && pRefList->uiShortRefCount > 0) {
|
||||
pRefList->pNextBuffer = pRefList->pShortRefList[pRefList->uiShortRefCount - 1];
|
||||
SetUnref (pRefList->pNextBuffer);
|
||||
pRefList->pNextBuffer->SetUnref();
|
||||
}
|
||||
|
||||
pCtx->pDecPic = pRefList->pNextBuffer;
|
||||
@@ -416,12 +398,12 @@ bool WelsUpdateRefList (void* pEncCtx) {
|
||||
}
|
||||
|
||||
for (i = pRefList->uiShortRefCount - 1; i > 0; i--) {
|
||||
SetUnref (pRefList->pShortRefList[i]);
|
||||
pRefList->pShortRefList[i]->SetUnref();
|
||||
DeleteSTRFromShortList (pCtx, i);
|
||||
}
|
||||
if (pRefList->uiShortRefCount > 0 && (pRefList->pShortRefList[0]->uiTemporalId > 0
|
||||
|| pRefList->pShortRefList[0]->iFrameNum != pCtx->iFrameNum)) {
|
||||
SetUnref (pRefList->pShortRefList[0]);
|
||||
pRefList->pShortRefList[0]->SetUnref();
|
||||
DeleteSTRFromShortList (pCtx, 0);
|
||||
}
|
||||
}
|
||||
@@ -438,7 +420,7 @@ bool WelsUpdateRefList (void* pEncCtx) {
|
||||
pCtx->pVaa->uiMarkLongTermPicIdx = 0;
|
||||
}
|
||||
}
|
||||
PrefetchNextBuffer (pCtx);
|
||||
pCtx->pFuncList->pEndofUpdateRefList (pCtx);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -623,6 +605,21 @@ bool WelsBuildRefList (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx
|
||||
return (pCtx->iNumRef0 > 0 || pCtx->eSliceType == I_SLICE) ? (true) : (false);
|
||||
}
|
||||
|
||||
static void UpdateBlockStatic (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||
assert (pCtx->iNumRef0 == 1); //multi-ref is not support yet?
|
||||
for (int32_t idx = 0; idx < pCtx->iNumRef0; idx++) {
|
||||
//TODO: we need to re-factor the source picture storage first,
|
||||
//and then use original frame of the ref to do this calculation for better vaa algo implementation
|
||||
SPicture* pRef = pCtx->pRefList0[idx];
|
||||
if (pVaaExt->iVaaBestRefFrameNum != pRef->iFrameNum) {
|
||||
//re-do the calculation
|
||||
pCtx->pVpp->UpdateBlockIdcForScreen (pVaaExt->pVaaBestBlockStaticIdc, pRef, pCtx->pEncPic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* update syntax for reference base related
|
||||
*/
|
||||
@@ -679,38 +676,40 @@ void WelsUpdateRefSyntax (sWelsEncCtx* pCtx, const int32_t iPOC, const int32_t u
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t UpdateSrcPicList (sWelsEncCtx* pCtx) {
|
||||
static inline void UpdateOriginalPicInfo (SPicture* pOrigPic, SPicture* pReconPic) {
|
||||
if (!pOrigPic)
|
||||
return;
|
||||
|
||||
pOrigPic->iPictureType = pReconPic->iPictureType;
|
||||
pOrigPic->iFramePoc = pReconPic->iFramePoc;
|
||||
pOrigPic->iFrameNum = pReconPic->iFrameNum;
|
||||
pOrigPic->uiSpatialId = pReconPic->uiSpatialId;
|
||||
pOrigPic->uiTemporalId = pReconPic->uiTemporalId;
|
||||
pOrigPic->iLongTermPicNum = pReconPic->iLongTermPicNum;
|
||||
pOrigPic->bUsedAsRef = pReconPic->bUsedAsRef;
|
||||
pOrigPic->bIsLongRef = pReconPic->bIsLongRef;
|
||||
pOrigPic->bIsSceneLTR = pReconPic->bIsSceneLTR;
|
||||
pOrigPic->iFrameAverageQp = pReconPic->iFrameAverageQp;
|
||||
}
|
||||
|
||||
static void UpdateSrcPicListLosslessScreenRefSelectionWithLtr (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
int32_t iDIdx = pCtx->uiDependencyId;
|
||||
SPicture** pLongRefList = pCtx->ppRefPicListExt[iDIdx]->pLongRefList;
|
||||
SPicture** pLongRefSrcList = &pCtx->pVpp->m_pSpatialPic[iDIdx][0];
|
||||
|
||||
//update info in src list
|
||||
if (pCtx->pEncPic) {
|
||||
pCtx->pEncPic->iPictureType = pCtx->pDecPic->iPictureType;
|
||||
pCtx->pEncPic->iFramePoc = pCtx->pDecPic->iFramePoc;
|
||||
pCtx->pEncPic->iFrameNum = pCtx->pDecPic->iFrameNum;
|
||||
pCtx->pEncPic->uiSpatialId = pCtx->pDecPic->uiSpatialId;
|
||||
pCtx->pEncPic->uiTemporalId = pCtx->pDecPic->uiTemporalId;
|
||||
pCtx->pEncPic->iLongTermPicNum = pCtx->pDecPic->iLongTermPicNum;
|
||||
pCtx->pEncPic->bUsedAsRef = pCtx->pDecPic->bUsedAsRef;
|
||||
pCtx->pEncPic->bIsLongRef = pCtx->pDecPic->bIsLongRef;
|
||||
pCtx->pEncPic->bIsSceneLTR = pCtx->pDecPic->bIsSceneLTR;
|
||||
pCtx->pEncPic->iFrameAverageQp = pCtx->pDecPic->iFrameAverageQp;
|
||||
}
|
||||
UpdateOriginalPicInfo (pCtx->pEncPic, pCtx->pDecPic);
|
||||
PrefetchNextBuffer (pCtx);
|
||||
for (int32_t i = 0; i < MAX_REF_PIC_COUNT; ++i) {
|
||||
if (NULL == pLongRefSrcList[i + 1] || (NULL != pLongRefList[i] && pLongRefList[i]->bUsedAsRef
|
||||
&& pLongRefList[i]->bIsLongRef)) {
|
||||
continue;
|
||||
} else {
|
||||
SetUnref (pLongRefSrcList[i + 1]);
|
||||
}
|
||||
}
|
||||
WelsExchangeSpatialPictures (&pCtx->pVpp->m_pSpatialPic[iDIdx][0],
|
||||
&pCtx->pVpp->m_pSpatialPic[iDIdx][1 + pCtx->pVaa->uiMarkLongTermPicIdx]);
|
||||
SetUnref (pCtx->pVpp->m_pSpatialPic[iDIdx][0]);
|
||||
pCtx->pVpp->UpdateSrcListLosslessScreenRefSelectionWithLtr (pCtx->pEncPic, iDIdx, pCtx->pVaa->uiMarkLongTermPicIdx,
|
||||
pCtx->ppRefPicListExt[iDIdx]->pLongRefList);
|
||||
}
|
||||
|
||||
return 0;
|
||||
static void UpdateSrcPicList (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
int32_t iDIdx = pCtx->uiDependencyId;
|
||||
//update info in src list
|
||||
UpdateOriginalPicInfo (pCtx->pEncPic, pCtx->pDecPic);
|
||||
PrefetchNextBuffer (pCtx);
|
||||
pCtx->pVpp->UpdateSrcList (pCtx->pEncPic, iDIdx, pCtx->ppRefPicListExt[iDIdx]->pShortRefList,
|
||||
pCtx->ppRefPicListExt[iDIdx]->uiShortRefCount);
|
||||
}
|
||||
|
||||
bool WelsUpdateRefListScreen (void* pEncCtx) {
|
||||
@@ -759,7 +758,7 @@ bool WelsUpdateRefListScreen (void* pEncCtx) {
|
||||
pCtx->pVaa->uiValidLongTermPicIdx = 0;
|
||||
}
|
||||
|
||||
UpdateSrcPicList (pCtx);
|
||||
pCtx->pFuncList->pEndofUpdateRefList (pCtx);
|
||||
return true;
|
||||
}
|
||||
bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx) {
|
||||
@@ -805,8 +804,9 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of (int idx = 0; idx < pVaaExt->iNumOfAvailableRef; idx++)
|
||||
} else {
|
||||
// dealing with IDR
|
||||
WelsResetRefList (pCtx); //for IDR, SHOULD reset pRef list.
|
||||
ResetLtrState (&pCtx->pLtr[pCtx->uiDependencyId]); //SHOULD update it when IDR.
|
||||
pCtx->pRefList0[0] = NULL;
|
||||
@@ -814,7 +814,6 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
|
||||
if (pCtx->iNumRef0 > iNumRef) {
|
||||
pCtx->iNumRef0 = iNumRef;
|
||||
}
|
||||
//TBD info update for md &fme
|
||||
|
||||
return (pCtx->iNumRef0 > 0 || pCtx->eSliceType == I_SLICE) ? (true) : (false);
|
||||
}
|
||||
@@ -900,20 +899,38 @@ void WelsMarkPicScreen (void* pEncCtx) {
|
||||
|
||||
pRefPicMark->SMmcoRef[pRefPicMark->uiMmcoCount].iLongTermFrameIdx = pLtr->iCurLtrIdx;
|
||||
pRefPicMark->SMmcoRef[pRefPicMark->uiMmcoCount++].iMmcoType = MMCO_LONG;
|
||||
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, EUsageType eUsageType) {
|
||||
if (eUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
|
||||
void DoNothing (void* pointer) {
|
||||
}
|
||||
|
||||
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bWithLtr, const bool bScreenContent) {
|
||||
bool bLosslessScreenRefSelectionWithLtr = bWithLtr && bScreenContent;
|
||||
if (bLosslessScreenRefSelectionWithLtr) {
|
||||
pFuncList->pBuildRefList = WelsBuildRefListScreen;
|
||||
pFuncList->pMarkPic = WelsMarkPicScreen;
|
||||
pFuncList->pUpdateRefList = WelsUpdateRefListScreen;
|
||||
pFuncList->pEndofUpdateRefList = UpdateSrcPicList;
|
||||
} else {
|
||||
pFuncList->pBuildRefList = WelsBuildRefList;
|
||||
pFuncList->pMarkPic = WelsMarkPic;
|
||||
pFuncList->pUpdateRefList = WelsUpdateRefList;
|
||||
pFuncList->pEndofUpdateRefList = PrefetchNextBuffer;
|
||||
}
|
||||
|
||||
pFuncList->pAfterBuildRefList = DoNothing;
|
||||
if (bScreenContent) {
|
||||
if (bLosslessScreenRefSelectionWithLtr) {
|
||||
pFuncList->pEndofUpdateRefList = UpdateSrcPicListLosslessScreenRefSelectionWithLtr;
|
||||
} else {
|
||||
pFuncList->pEndofUpdateRefList = UpdateSrcPicList;
|
||||
pFuncList->pAfterBuildRefList = UpdateBlockStatic;
|
||||
}
|
||||
} else {
|
||||
pFuncList->pEndofUpdateRefList = PrefetchNextBuffer;
|
||||
}
|
||||
}
|
||||
} // namespace WelsEnc
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "sample.h"
|
||||
#include "sad_common.h"
|
||||
|
||||
#include "intra_pred_common.h"
|
||||
#include "mc.h"
|
||||
#include "cpu_core.h"
|
||||
|
||||
@@ -250,8 +250,8 @@ int32_t WelsSampleSadIntra8x8Combined3_c (uint8_t* pDecCb, int32_t iDecStride, u
|
||||
}
|
||||
|
||||
extern void WelsI16x16LumaPredDc_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
|
||||
extern void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
|
||||
extern void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
|
||||
//extern void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
|
||||
//extern void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
|
||||
|
||||
int32_t WelsSampleSatdIntra16x16Combined3_c (uint8_t* pDec, int32_t iDecStride, uint8_t* pEnc, int32_t iEncStride,
|
||||
int32_t* pBestMode, int32_t iLambda, uint8_t* pDst) {
|
||||
|
||||
@@ -705,6 +705,8 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
|
||||
pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pExitEncodeEvent[iEventIdx];
|
||||
pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pUpdateMbListEvent[iEventIdx];
|
||||
|
||||
WelsThreadSetName ("OpenH264Enc_CodingSliceThreadProc");
|
||||
|
||||
do {
|
||||
MT_TRACE_LOG (pEncPEncCtx, WELS_LOG_INFO,
|
||||
"[MT] CodingSliceThreadProc(), try to call WelsMultipleEventsWaitSingleBlocking(pEventsList= %p %p %p), pEncPEncCtx= %p!",
|
||||
|
||||
@@ -716,7 +716,7 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const
|
||||
==
|
||||
SM_DYN_SLICE);
|
||||
|
||||
assert (kiSliceIdx == pCurSlice->uiSliceIdx);
|
||||
assert (kiSliceIdx == (int) pCurSlice->uiSliceIdx);
|
||||
|
||||
if (I_SLICE == pEncCtx->eSliceType) {
|
||||
pNalHeadExt->bIdrFlag = 1;
|
||||
@@ -862,10 +862,6 @@ bool DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSli
|
||||
const bool kbCurMbNotFirstMbOfCurSlice = (pSliceCtx->pOverallMbMap[iCurMbIdx] ==
|
||||
pSliceCtx->pOverallMbMap[iCurMbIdx - 1]);
|
||||
const bool kbCurMbNotLastMbOfCurPartition = iCurMbIdx < kiLastMbIdxInPartition;
|
||||
const bool kbSliceNumNotExceedConstraint = pSliceCtx->iSliceNumInFrame <
|
||||
pSliceCtx->iMaxSliceNumConstraint; /*tmp choice to avoid complex memory operation, 100520, to be modify*/
|
||||
const bool kbSliceNumReachConstraint = (pSliceCtx->iSliceNumInFrame ==
|
||||
pSliceCtx->iMaxSliceNumConstraint);
|
||||
|
||||
if (pCurSlice->bDynamicSlicingSliceSizeCtrlFlag)
|
||||
return false;
|
||||
@@ -876,45 +872,50 @@ bool DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSli
|
||||
#endif
|
||||
uiLen = ((iPosBitOffset >> 3) + ((iPosBitOffset & 0x07) ? 1 : 0));
|
||||
|
||||
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
|
||||
WelsMutexLock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
|
||||
if ((kbCurMbNotFirstMbOfCurSlice
|
||||
&& JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx, pSliceCtx->uiSliceSizeConstraint)) /*jump_avoiding_pack_exceed*/
|
||||
&& kbCurMbNotLastMbOfCurPartition) { //decide to add new pSlice
|
||||
|
||||
//DYNAMIC_SLICING_ONE_THREAD: judge jump_avoiding_pack_exceed
|
||||
if (
|
||||
((kbCurMbNotFirstMbOfCurSlice
|
||||
&& JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx, pSliceCtx->uiSliceSizeConstraint)) /*jump_avoiding_pack_exceed*/
|
||||
&& kbCurMbNotLastMbOfCurPartition) //decide to add new pSlice
|
||||
&& (kbSliceNumNotExceedConstraint
|
||||
&& ((pCurSlice->uiSliceIdx + kiActiveThreadsNum) < pSliceCtx->iMaxSliceNumConstraint)
|
||||
)//able to add new pSlice
|
||||
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1) {
|
||||
WelsMutexLock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
|
||||
//lock the acessing to this variable: pSliceCtx->iSliceNumInFrame
|
||||
}
|
||||
const bool kbSliceNumNotExceedConstraint = pSliceCtx->iSliceNumInFrame <
|
||||
pSliceCtx->iMaxSliceNumConstraint; /*tmp choice to avoid complex memory operation, 100520, to be modify*/
|
||||
const bool kbSliceIdxNotExceedConstraint = ((int) pCurSlice->uiSliceIdx + kiActiveThreadsNum) <
|
||||
pSliceCtx->iMaxSliceNumConstraint;
|
||||
const bool kbSliceNumReachConstraint = (pSliceCtx->iSliceNumInFrame ==
|
||||
pSliceCtx->iMaxSliceNumConstraint);
|
||||
|
||||
) {
|
||||
//DYNAMIC_SLICING_ONE_THREAD: judge jump_avoiding_pack_exceed
|
||||
if (kbSliceNumNotExceedConstraint && kbSliceIdxNotExceedConstraint) {//able to add new pSlice
|
||||
|
||||
AddSliceBoundary (pEncCtx, pCurSlice, pSliceCtx, pCurMb, iCurMbIdx, kiLastMbIdxInPartition);
|
||||
AddSliceBoundary (pEncCtx, pCurSlice, pSliceCtx, pCurMb, iCurMbIdx, kiLastMbIdxInPartition);
|
||||
|
||||
++ pSliceCtx->iSliceNumInFrame;
|
||||
++ pSliceCtx->iSliceNumInFrame;
|
||||
|
||||
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
|
||||
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1) {
|
||||
WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1) {
|
||||
WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
|
||||
}
|
||||
|
||||
return true;
|
||||
if ((kbSliceNumReachConstraint || !kbSliceIdxNotExceedConstraint)
|
||||
&& kbCurMbNotLastMbOfCurPartition
|
||||
&& JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx,
|
||||
pSliceCtx->uiSliceSizeConstraint - ((kiLastMbIdxInPartition - iCurMbIdx) <<
|
||||
(pCurSlice->uiAssumeLog2BytePerMb) //assume each MB consumes these byte under largest QP
|
||||
))
|
||||
) {
|
||||
// to minimize the impact under the risk of exceeding the size constraint when pSlice num reaches constraint
|
||||
pCurSlice->bDynamicSlicingSliceSizeCtrlFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(kbSliceNumReachConstraint
|
||||
|| ((pCurSlice->uiSliceIdx + kiActiveThreadsNum) >= pSliceCtx->iMaxSliceNumConstraint)
|
||||
)
|
||||
&& ((JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx,
|
||||
pSliceCtx->uiSliceSizeConstraint - ((kiLastMbIdxInPartition - iCurMbIdx) <<
|
||||
(pCurSlice->uiAssumeLog2BytePerMb) /* assume each MB consumes two byte under largest QP */)))
|
||||
&& kbCurMbNotLastMbOfCurPartition) //risk of exceeding the size constraint when pSlice num reaches constraint
|
||||
) {
|
||||
pCurSlice->bDynamicSlicingSliceSizeCtrlFlag = true;
|
||||
}
|
||||
|
||||
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
|
||||
WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ void WelsSpatialWriteSubMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurM
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CheckBitstreamBuffer (const uint8_t kuiSliceIdx, sWelsEncCtx* pEncCtx, SBitStringAux* pBs) {
|
||||
int32_t CheckBitstreamBuffer (const uint32_t kuiSliceIdx, sWelsEncCtx* pEncCtx, SBitStringAux* pBs) {
|
||||
const intX_t iLeftLength = pBs->pBufEnd - pBs->pBufPtr - 1;
|
||||
assert (iLeftLength > 0);
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
#define WelsSafeDelete(p) if(p){ delete (p); (p) = NULL; }
|
||||
|
||||
|
||||
//***** entry API declaration ************************************************************************//
|
||||
@@ -87,7 +86,7 @@ CWelsPreProcess::~CWelsPreProcess() {
|
||||
|
||||
int32_t CWelsPreProcess::WelsPreprocessCreate() {
|
||||
if (m_pInterfaceVp == NULL) {
|
||||
CreateVpInterface ((void**) &m_pInterfaceVp, WELSVP_INTERFACE_VERION);
|
||||
WelsCreateVpInterface ((void**) &m_pInterfaceVp, WELSVP_INTERFACE_VERION);
|
||||
if (!m_pInterfaceVp)
|
||||
goto exit;
|
||||
} else
|
||||
@@ -101,7 +100,7 @@ exit:
|
||||
}
|
||||
|
||||
int32_t CWelsPreProcess::WelsPreprocessDestroy() {
|
||||
DestroyVpInterface (m_pInterfaceVp, WELSVP_INTERFACE_VERION);
|
||||
WelsDestroyVpInterface (m_pInterfaceVp, WELSVP_INTERFACE_VERION);
|
||||
m_pInterfaceVp = NULL;
|
||||
|
||||
return 0;
|
||||
@@ -186,6 +185,8 @@ int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePi
|
||||
if (WelsPreprocessReset (pCtx) != 0)
|
||||
return -1;
|
||||
|
||||
m_iAvaliableRefInSpatialPicList = pSvcParam->iNumRefFrame;
|
||||
|
||||
m_bInitDone = true;
|
||||
}
|
||||
|
||||
@@ -794,9 +795,9 @@ void CWelsPreProcess::AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCu
|
||||
|
||||
if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) {
|
||||
iComplexityAnalysisMode = FRAME_SAD;
|
||||
} else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
|
||||
} else if (pSvcParam->iRCMode == RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
|
||||
iComplexityAnalysisMode = GOM_SAD;
|
||||
} else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
|
||||
} else if (pSvcParam->iRCMode == RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
|
||||
iComplexityAnalysisMode = GOM_VAR;
|
||||
} else {
|
||||
return;
|
||||
@@ -859,10 +860,10 @@ void CWelsPreProcess::InitPixMap (const SPicture* pPicture, SPixMap* pPixMap) {
|
||||
|
||||
pPixMap->eFormat = VIDEO_FORMAT_I420;
|
||||
}
|
||||
void CWelsPreProcess::GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurTid, const int32_t iClosestLtrFrameNum,
|
||||
void CWelsPreProcess::GetAvailableRefListLosslessScreenRefSelection (SPicture** pSrcPicList, uint8_t iCurTid,
|
||||
const int32_t iClosestLtrFrameNum,
|
||||
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum) {
|
||||
SWelsSvcCodingParam* pSvcParam = m_pEncCtx->pSvcParam;
|
||||
const int32_t iSourcePicNum = pSvcParam->iNumRefFrame;
|
||||
const int32_t iSourcePicNum = m_iAvaliableRefInSpatialPicList;
|
||||
if (0 >= iSourcePicNum) {
|
||||
iAvailableRefNum = 0;
|
||||
iAvailableSceneRefNum = 0;
|
||||
@@ -908,6 +909,38 @@ void CWelsPreProcess::GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurT
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CWelsPreProcess::GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurTid, const int32_t iClosestLtrFrameNum,
|
||||
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum) {
|
||||
const int32_t iSourcePicNum = m_iAvaliableRefInSpatialPicList;
|
||||
if (0 >= iSourcePicNum) {
|
||||
iAvailableRefNum = 0;
|
||||
iAvailableSceneRefNum = 0;
|
||||
return ;
|
||||
}
|
||||
SPicture* pRefPic = NULL;
|
||||
uint8_t uiRefTid = 0;
|
||||
iAvailableRefNum = 0;
|
||||
iAvailableSceneRefNum = 0;
|
||||
|
||||
//the saving order will be depend on pSrcPicList
|
||||
//TODO: use a frame_idx to find the closer ref in time distance, and correctly sort the ref list
|
||||
for (int32_t i = iSourcePicNum - 1; i >= 0; --i) {
|
||||
pRefPic = pSrcPicList[i];
|
||||
if (NULL == pRefPic || !pRefPic->bUsedAsRef) {
|
||||
continue;
|
||||
}
|
||||
uiRefTid = pRefPic->uiTemporalId;
|
||||
|
||||
if (uiRefTid <= iCurTid) {
|
||||
pAvailableRefList[iAvailableRefNum].pRefPicture = pRefPic;
|
||||
pAvailableRefList[iAvailableRefNum].iSrcListIdx = i + 1; //in SrcList, the idx 0 is reserved for CurPic
|
||||
iAvailableRefNum ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CWelsPreProcess::InitRefJudgement (SRefJudgement* pRefJudgement) {
|
||||
pRefJudgement->iMinFrameComplexity = INT_MAX;
|
||||
pRefJudgement->iMinFrameComplexity08 = INT_MAX;
|
||||
@@ -932,8 +965,7 @@ void CWelsPreProcess::SaveBestRefToJudgement (const int32_t iRefPictureAvQP, con
|
||||
}
|
||||
void CWelsPreProcess::SaveBestRefToLocal (SRefInfoParam* pRefPicInfo, const SSceneChangeResult& sSceneChangeResult,
|
||||
SRefInfoParam* pRefSaved) {
|
||||
pRefSaved->iSrcListIdx = pRefPicInfo->iSrcListIdx;
|
||||
pRefSaved->bSceneLtrFlag = pRefPicInfo->bSceneLtrFlag;
|
||||
memcpy (pRefSaved, pRefPicInfo, sizeof (SRefInfoParam));
|
||||
pRefSaved->pBestBlockStaticIdc = sSceneChangeResult.pStaticBlockIdc;
|
||||
}
|
||||
|
||||
@@ -988,8 +1020,14 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
|
||||
const uint8_t iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[m_pEncCtx->sSpatialIndexMap[0].iDid],
|
||||
m_pEncCtx->iCodingIndex, pSvcParam->uiGopSize);
|
||||
const int32_t iClosestLtrFrameNum = pCtx->pLtr[iTargetDid].iLastLtrIdx[iCurTid];//TBD
|
||||
GetAvailableRefList (pSrcPicList, iCurTid, iClosestLtrFrameNum, &sAvailableRefList[0], iAvailableRefNum,
|
||||
iAvailableSceneRefNum);
|
||||
if (pSvcParam->bEnableLongTermReference) {
|
||||
GetAvailableRefListLosslessScreenRefSelection (pSrcPicList, iCurTid, iClosestLtrFrameNum, &sAvailableRefList[0],
|
||||
iAvailableRefNum,
|
||||
iAvailableSceneRefNum);
|
||||
} else {
|
||||
GetAvailableRefList (pSrcPicList, iCurTid, iClosestLtrFrameNum, &sAvailableRefList[0], iAvailableRefNum,
|
||||
iAvailableSceneRefNum);
|
||||
}
|
||||
//after this build, pAvailableRefList[idx].iSrcListIdx is the idx of the ref in h->spatial_pic
|
||||
if (0 == iAvailableRefNum) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "SceneChangeDetect() iAvailableRefNum=0 but not I.");
|
||||
@@ -1038,12 +1076,12 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
|
||||
const int32_t iSceneDetectIdc = sSceneChangeResult.eSceneChangeIdc;
|
||||
const int32_t iMotionBlockNum = sSceneChangeResult.iMotionBlockNum;
|
||||
|
||||
const bool bCurRefIsLtr = pRefPic->bIsSceneLTR;
|
||||
const bool bCurRefIsSceneLtr = pRefPic->bIsSceneLTR;
|
||||
const int32_t iRefPicAvQP = pRefPic->iFrameAverageQp;
|
||||
|
||||
//for scene change detection
|
||||
iNumOfLargeChange += (static_cast<int32_t> (LARGE_CHANGED_SCENE == iSceneDetectIdc));
|
||||
iNumOfMediumChangeToLtr += (static_cast<int32_t> ((bCurRefIsLtr) && (iSceneDetectIdc != SIMILAR_SCENE)));
|
||||
iNumOfMediumChangeToLtr += (static_cast<int32_t> ((bCurRefIsSceneLtr) && (iSceneDetectIdc != SIMILAR_SCENE)));
|
||||
|
||||
//for reference selection
|
||||
//this judge can only be saved when iAvailableRefNum==1, which is very limit
|
||||
@@ -1052,7 +1090,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
|
||||
SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sLtrJudgement);
|
||||
SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sLtrSaved);
|
||||
}
|
||||
if (bCurRefIsLtr && JudgeBestRef (pRefPic, sSceneLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) {
|
||||
if (bCurRefIsSceneLtr && JudgeBestRef (pRefPic, sSceneLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) {
|
||||
SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sSceneLtrJudgement);
|
||||
SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sSceneLtrSaved);
|
||||
}
|
||||
@@ -1075,6 +1113,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
|
||||
pCtx->iCodingIndex);
|
||||
|
||||
SaveBestRefToVaa (sLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[0]));
|
||||
pVaaExt->iVaaBestRefFrameNum = sLtrSaved.pRefPicture->iFrameNum;
|
||||
pVaaExt->pVaaBestBlockStaticIdc = sLtrSaved.pBestBlockStaticIdc;
|
||||
|
||||
if (0 == iAvailableSceneRefNum) {
|
||||
@@ -1120,6 +1159,83 @@ void CWelsPreProcess::Padding (uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV,
|
||||
}
|
||||
|
||||
|
||||
int32_t CWelsPreProcess::UpdateBlockIdcForScreen (uint8_t* pCurBlockStaticPointer, const SPicture* kpRefPic,
|
||||
const SPicture* kpSrcPic) {
|
||||
int32_t iSceneChangeMethodIdx = METHOD_SCENE_CHANGE_DETECTION_SCREEN;
|
||||
SSceneChangeResult sSceneChangeResult = {SIMILAR_SCENE, 0, 0, NULL};
|
||||
sSceneChangeResult.pStaticBlockIdc = pCurBlockStaticPointer;
|
||||
sSceneChangeResult.sScrollResult.bScrollDetectFlag = false;
|
||||
|
||||
SPixMap sSrcMap = { { 0 } };
|
||||
SPixMap sRefMap = { { 0 } };
|
||||
InitPixMap (kpSrcPic, &sSrcMap);
|
||||
InitPixMap (kpRefPic, &sRefMap);
|
||||
|
||||
m_pInterfaceVp->Set (iSceneChangeMethodIdx, (void*) (&sSceneChangeResult));
|
||||
int32_t iRet = m_pInterfaceVp->Process (iSceneChangeMethodIdx, &sSrcMap, &sRefMap);
|
||||
if (iRet == 0) {
|
||||
m_pInterfaceVp->Get (iSceneChangeMethodIdx, (void*)&sSceneChangeResult);
|
||||
return 0;
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief exchange two picture pData planes
|
||||
* \param ppPic1 picture pointer to picture 1
|
||||
* \param ppPic2 picture pointer to picture 2
|
||||
* \return none
|
||||
*/
|
||||
void CWelsPreProcess::WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2) {
|
||||
SPicture* tmp = *ppPic1;
|
||||
|
||||
assert (*ppPic1 != *ppPic2);
|
||||
|
||||
*ppPic1 = *ppPic2;
|
||||
*ppPic2 = tmp;
|
||||
}
|
||||
|
||||
void CWelsPreProcess::UpdateSrcListLosslessScreenRefSelectionWithLtr (SPicture* pCurPicture, const int32_t kiCurDid,
|
||||
const int32_t kuiMarkLongTermPicIdx, SPicture** pLongRefList) {
|
||||
SPicture** pLongRefSrcList = &m_pSpatialPic[kiCurDid][0];
|
||||
for (int32_t i = 0; i < MAX_REF_PIC_COUNT; ++i) {
|
||||
if (NULL == pLongRefSrcList[i + 1] || (NULL != pLongRefList[i] && pLongRefList[i]->bUsedAsRef
|
||||
&& pLongRefList[i]->bIsLongRef)) {
|
||||
continue;
|
||||
} else {
|
||||
pLongRefSrcList[i + 1]->SetUnref();
|
||||
}
|
||||
}
|
||||
WelsExchangeSpatialPictures (&m_pSpatialPic[kiCurDid][0],
|
||||
&m_pSpatialPic[kiCurDid][1 + kuiMarkLongTermPicIdx]);
|
||||
m_iAvaliableRefInSpatialPicList = MAX_REF_PIC_COUNT;
|
||||
(GetCurrentFrameFromOrigList (kiCurDid))->SetUnref();
|
||||
}
|
||||
void CWelsPreProcess::UpdateSrcList (SPicture* pCurPicture, const int32_t kiCurDid, SPicture** pShortRefList,
|
||||
const uint32_t kuiShortRefCount) {
|
||||
SPicture** pRefSrcList = &m_pSpatialPic[kiCurDid][0];
|
||||
|
||||
//pRefSrcList[0] is for current frame
|
||||
if (pCurPicture->bUsedAsRef || pCurPicture->bIsLongRef) {
|
||||
if (pCurPicture->iPictureType == P_SLICE && pCurPicture->uiTemporalId != 0) {
|
||||
for (int iRefIdx = kuiShortRefCount - 1; iRefIdx >= 0; --iRefIdx) {
|
||||
WelsExchangeSpatialPictures (&pRefSrcList[iRefIdx + 1],
|
||||
&pRefSrcList[iRefIdx]);
|
||||
}
|
||||
m_iAvaliableRefInSpatialPicList = kuiShortRefCount;
|
||||
} else {
|
||||
WelsExchangeSpatialPictures (&pRefSrcList[0], &pRefSrcList[1]);
|
||||
for (int32_t i = MAX_SHORT_REF_COUNT - 1; i > 0 ; --i) {
|
||||
if (pRefSrcList[i + 1] != NULL) {
|
||||
pRefSrcList[i + 1]->SetUnref();
|
||||
}
|
||||
}
|
||||
m_iAvaliableRefInSpatialPicList = 1;
|
||||
}
|
||||
}
|
||||
(GetCurrentFrameFromOrigList (kiCurDid))->SetUnref();
|
||||
}
|
||||
|
||||
//TODO: may opti later
|
||||
//TODO: not use this func?
|
||||
void* WelsMemcpy (void* dst, const void* kpSrc, uint32_t uiSize) {
|
||||
|
||||
@@ -306,74 +306,6 @@ get_i16x16_luma_pred_plane_sse2_1:
|
||||
pop r3
|
||||
ret
|
||||
|
||||
;***********************************************************************
|
||||
; void WelsI16x16LumaPredH_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
|
||||
;***********************************************************************
|
||||
|
||||
%macro SSE2_PRED_H_16X16_ONE_LINE 0
|
||||
add r0, 16
|
||||
add r1, r2
|
||||
movzx r3, byte [r1]
|
||||
SSE2_Copy16Times xmm0, r3d
|
||||
movdqa [r0], xmm0
|
||||
%endmacro
|
||||
|
||||
WELS_EXTERN WelsI16x16LumaPredH_sse2
|
||||
push r3
|
||||
%assign push_num 1
|
||||
LOAD_3_PARA
|
||||
SIGN_EXTENSION r2, r2d
|
||||
dec r1
|
||||
movzx r3, byte [r1]
|
||||
SSE2_Copy16Times xmm0, r3d
|
||||
movdqa [r0], xmm0
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
SSE2_PRED_H_16X16_ONE_LINE
|
||||
pop r3
|
||||
ret
|
||||
|
||||
;***********************************************************************
|
||||
; void WelsI16x16LumaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
|
||||
;***********************************************************************
|
||||
WELS_EXTERN WelsI16x16LumaPredV_sse2
|
||||
%assign push_num 0
|
||||
LOAD_3_PARA
|
||||
SIGN_EXTENSION r2, r2d
|
||||
sub r1, r2
|
||||
movdqa xmm0, [r1]
|
||||
|
||||
movdqa [r0], xmm0
|
||||
movdqa [r0+10h], xmm0
|
||||
movdqa [r0+20h], xmm0
|
||||
movdqa [r0+30h], xmm0
|
||||
movdqa [r0+40h], xmm0
|
||||
movdqa [r0+50h], xmm0
|
||||
movdqa [r0+60h], xmm0
|
||||
movdqa [r0+70h], xmm0
|
||||
movdqa [r0+80h], xmm0
|
||||
movdqa [r0+90h], xmm0
|
||||
movdqa [r0+160], xmm0
|
||||
movdqa [r0+176], xmm0
|
||||
movdqa [r0+192], xmm0
|
||||
movdqa [r0+208], xmm0
|
||||
movdqa [r0+224], xmm0
|
||||
movdqa [r0+240], xmm0
|
||||
|
||||
ret
|
||||
|
||||
;***********************************************************************
|
||||
; void WelsIChromaPredPlane_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
|
||||
;***********************************************************************
|
||||
|
||||
@@ -102,6 +102,8 @@ class CWelsH264SVCEncoder : public ISVCEncoder {
|
||||
void CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelIdc);
|
||||
void CheckReferenceNumSetting (int32_t iNumRef);
|
||||
void TraceParamInfo(SEncParamExt *pParam);
|
||||
void UpdateStatistics(const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType, const int64_t kiCurrentFrameMs);
|
||||
|
||||
sWelsEncCtx* m_pEncContext;
|
||||
|
||||
welsCodecTrace* m_pWelsTrace;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "ref_list_mgr_svc.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <measure_time.h>
|
||||
#if defined(_WIN32) /*&& defined(_DEBUG)*/
|
||||
|
||||
#include <windows.h>
|
||||
@@ -207,6 +208,7 @@ int CWelsH264SVCEncoder::Initialize (const SEncParamBase* argv) {
|
||||
if (sConfig.ParamBaseTranscode (*argv)) {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
|
||||
"CWelsH264SVCEncoder::Initialize(), parameter_translation failed.");
|
||||
TraceParamInfo (&sConfig);
|
||||
Uninitialize();
|
||||
return cmInitParaError;
|
||||
}
|
||||
@@ -230,6 +232,7 @@ int CWelsH264SVCEncoder::InitializeExt (const SEncParamExt* argv) {
|
||||
if (sConfig.ParamTranscode (*argv)) {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
|
||||
"CWelsH264SVCEncoder::InitializeExt(), parameter_translation failed.");
|
||||
TraceParamInfo (&sConfig);
|
||||
Uninitialize();
|
||||
return cmInitParaError;
|
||||
}
|
||||
@@ -325,7 +328,7 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
|
||||
if (pCfg->iNumRefFrame == AUTO_REF_PIC_COUNT) {
|
||||
pCfg->iNumRefFrame = ((pCfg->uiGopSize >> 1) > 1) ? ((pCfg->uiGopSize >> 1) + pCfg->iLTRRefNum) :
|
||||
(MIN_REF_PIC_COUNT + pCfg->iLTRRefNum);
|
||||
pCfg->iNumRefFrame = WELS_CLIP3 (pCfg->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
|
||||
pCfg->iNumRefFrame = WELS_CLIP3 (pCfg->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA);
|
||||
}
|
||||
}
|
||||
if (pCfg->iNumRefFrame > pCfg->iMaxNumRefFrame)
|
||||
@@ -346,6 +349,10 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
|
||||
TraceParamInfo (pCfg);
|
||||
if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG,
|
||||
"Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d",
|
||||
pCfg->iUsageType, pCfg->iPicWidth, pCfg->iPicHeight, pCfg->fMaxFrameRate, pCfg->iTemporalLayerNum,
|
||||
pCfg->iSpatialLayerNum);
|
||||
Uninitialize();
|
||||
return cmInitParaError;
|
||||
}
|
||||
@@ -410,8 +417,10 @@ int CWelsH264SVCEncoder::EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSIn
|
||||
}
|
||||
|
||||
|
||||
int CWelsH264SVCEncoder::EncodeFrameInternal (const SSourcePicture* pSrcPic, SFrameBSInfo* pBsInfo) {
|
||||
int CWelsH264SVCEncoder ::EncodeFrameInternal (const SSourcePicture* pSrcPic, SFrameBSInfo* pBsInfo) {
|
||||
const int64_t kiBeforeFrameUs = WelsTime();
|
||||
const int32_t kiEncoderReturn = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPic);
|
||||
const int64_t kiCurrentFrameMs = (WelsTime() - kiBeforeFrameUs) / 1000;
|
||||
|
||||
if (kiEncoderReturn == ENC_RETURN_MEMALLOCERR) {
|
||||
WelsUninitEncoderExt (&m_pEncContext);
|
||||
@@ -421,6 +430,9 @@ int CWelsH264SVCEncoder::EncodeFrameInternal (const SSourcePicture* pSrcPic, SF
|
||||
kiEncoderReturn);
|
||||
return cmUnkonwReason;
|
||||
}
|
||||
|
||||
UpdateStatistics (pSrcPic->uiTimeStamp, pBsInfo->eFrameType, kiCurrentFrameMs);
|
||||
|
||||
///////////////////for test
|
||||
#ifdef OUTPUT_BIT_STREAM
|
||||
if (pBsInfo->eFrameType != videoFrameTypeInvalid && pBsInfo->eFrameType != videoFrameTypeSkip) {
|
||||
@@ -519,8 +531,10 @@ void CWelsH264SVCEncoder::CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelId
|
||||
}
|
||||
}
|
||||
void CWelsH264SVCEncoder::CheckReferenceNumSetting (int32_t iNumRef) {
|
||||
int32_t iRefUpperBound = (m_pEncContext->pSvcParam->iUsageType == CAMERA_VIDEO_REAL_TIME) ?
|
||||
MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA : MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN;
|
||||
m_pEncContext->pSvcParam->iNumRefFrame = iNumRef;
|
||||
if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > MAX_REFERENCE_PICTURE_COUNT_NUM)) {
|
||||
if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > iRefUpperBound)) {
|
||||
m_pEncContext->pSvcParam->iNumRefFrame = AUTO_REF_PIC_COUNT;
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
|
||||
"doesn't support the number of reference frame(%d) change to auto select mode", iNumRef);
|
||||
@@ -578,6 +592,64 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
|
||||
++ i;
|
||||
}
|
||||
}
|
||||
|
||||
void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType,
|
||||
const int64_t kiCurrentFrameMs) {
|
||||
SEncoderStatistics* pStatistics = & (m_pEncContext->sEncoderStatistics);
|
||||
|
||||
int32_t iMaxDid = m_pEncContext->pSvcParam->iSpatialLayerNum - 1;
|
||||
if ((0 != pStatistics->uiWidth && 0 != pStatistics->uiHeight)
|
||||
&& (pStatistics->uiWidth != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth
|
||||
|| pStatistics->uiHeight != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight)) {
|
||||
pStatistics->uiResolutionChangeTimes ++;
|
||||
}
|
||||
pStatistics->uiWidth = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth;
|
||||
pStatistics->uiHeight = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight;
|
||||
|
||||
int32_t iProcessedFrameCount = pStatistics->uiInputFrameCount - pStatistics->uiSkippedFrameCount;
|
||||
const bool kbCurrentFrameSkipped = (videoFrameTypeSkip == eFrameType);
|
||||
if (!kbCurrentFrameSkipped && (iProcessedFrameCount + 1) != 0) {
|
||||
pStatistics->fAverageFrameSpeedInMs = (iProcessedFrameCount * pStatistics->fAverageFrameSpeedInMs +
|
||||
kiCurrentFrameMs) / (iProcessedFrameCount + 1);
|
||||
}
|
||||
pStatistics->uiInputFrameCount ++;
|
||||
pStatistics->uiSkippedFrameCount += (kbCurrentFrameSkipped ? 1 : 0);
|
||||
|
||||
// rate control related
|
||||
if (0 != m_pEncContext->uiStartTimestamp && kiCurrentFrameTs > m_pEncContext->uiStartTimestamp + 800) {
|
||||
pStatistics->fAverageFrameRate = pStatistics->uiInputFrameCount * 1000 /
|
||||
(kiCurrentFrameTs - m_pEncContext->uiStartTimestamp);
|
||||
} else {
|
||||
m_pEncContext->uiStartTimestamp = kiCurrentFrameTs;
|
||||
}
|
||||
pStatistics->fLatestFrameRate = m_pEncContext->pWelsSvcRc->fLatestFrameRate; //TODO: finish the calculation in RC
|
||||
pStatistics->uiBitRate = m_pEncContext->pWelsSvcRc->iActualBitRate; //TODO: finish the calculation in RC
|
||||
|
||||
if (videoFrameTypeIDR == eFrameType || videoFrameTypeI == eFrameType) {
|
||||
pStatistics->uiIDRSentNum ++;
|
||||
}
|
||||
if (m_pEncContext->pLtr->bLTRMarkingFlag) {
|
||||
pStatistics->uiLTRSentNum ++;
|
||||
}
|
||||
//TODO: update uiIDRReqNum in forceIDR
|
||||
|
||||
if (m_pEncContext->iStatisticsLogInterval > 0) {
|
||||
if (WELS_ABS (kiCurrentFrameTs - m_pEncContext->iLastStatisticsLogTs) > m_pEncContext->iStatisticsLogInterval) {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||
"EncoderStatistics: %dx%d, SpeedInMs: %f, AverFrameRate=%f, LastFrameRate=NA, LatestBitRate=NA, uiInputFrameCount=%d, uiSkippedFrameCount=%d, uiResolutionChangeTimes=%d, uIDRReqNum=%d, uIDRSentNum=%d, uLTRSentNum=NA",
|
||||
pStatistics->uiWidth, pStatistics->uiHeight,
|
||||
pStatistics->fAverageFrameSpeedInMs, pStatistics->fAverageFrameRate,
|
||||
pStatistics->uiInputFrameCount, pStatistics->uiSkippedFrameCount,
|
||||
pStatistics->uiResolutionChangeTimes, pStatistics->uiIDRSentNum, pStatistics->uiLTRSentNum);
|
||||
//TODO: the following statistics will be calculated and added later
|
||||
//pStatistics->fLatestFrameRate, pStatistics->uiBitRate,
|
||||
//pStatistics->uiIDRReqNum,
|
||||
m_pEncContext->iLastStatisticsLogTs = kiCurrentFrameTs;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
|
||||
************************************************************************/
|
||||
@@ -662,6 +734,11 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
if (sConfig.iSpatialLayerNum < 1) {
|
||||
return cmInitParaError;
|
||||
}
|
||||
if (sConfig.DetermineTemporalSettings()) {
|
||||
return cmInitParaError;
|
||||
}
|
||||
|
||||
/* New configuration available here */
|
||||
iTargetWidth = sConfig.iPicWidth;
|
||||
iTargetHeight = sConfig.iPicHeight;
|
||||
if (m_iMaxPicWidth != iTargetWidth
|
||||
@@ -675,11 +752,10 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
m_uiCountFrameNum, m_iCspInternal);
|
||||
#endif//REC_FRAME_COUNT
|
||||
|
||||
/* New configuration available here */
|
||||
sConfig.DetermineTemporalSettings();
|
||||
|
||||
/* Check every field whether there is new request for memory block changed or else, Oct. 24, 2008 */
|
||||
WelsEncoderParamAdjust (&m_pEncContext, &sConfig);
|
||||
if (WelsEncoderParamAdjust (&m_pEncContext, &sConfig)) {
|
||||
return cmInitParaError;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_FRAME_RATE: { // Maximal input frame rate
|
||||
@@ -809,7 +885,9 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
break;
|
||||
case ENCODER_OPTION_LTR: {
|
||||
SLTRConfig* pLTRValue = ((SLTRConfig*) (pOption));
|
||||
WelsEncoderApplyLTR (&m_pWelsTrace->m_sLogCtx, &m_pEncContext, pLTRValue);
|
||||
if (WelsEncoderApplyLTR (&m_pWelsTrace->m_sLogCtx, &m_pEncContext, pLTRValue)) {
|
||||
return cmInitParaError;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_ENABLE_SSEI: {
|
||||
@@ -905,10 +983,25 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_COMPLEXITY: {
|
||||
int32_t iValue = * ((int32_t*)pOption);
|
||||
int32_t iValue = * (static_cast<int32_t*> (pOption));
|
||||
m_pEncContext->pSvcParam->iComplexityMode = (ECOMPLEXITY_MODE)iValue;
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_GET_STATISTICS: {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
|
||||
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_GET_STATISTICS: this option is get-only!");
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: {
|
||||
int32_t iValue = * (static_cast<int32_t*> (pOption));
|
||||
m_pEncContext->iStatisticsLogInterval = iValue;
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_IS_LOSSLESS_LINK: {
|
||||
bool bValue = * (static_cast<bool*> (pOption));
|
||||
m_pEncContext->pSvcParam->bIsLosslessLink = bValue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return cmInitParaError;
|
||||
}
|
||||
@@ -1011,6 +1104,30 @@ int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_GET_STATISTICS: {
|
||||
SEncoderStatistics* pStatistics = (static_cast<SEncoderStatistics*> (pOption));
|
||||
pStatistics->uiWidth = m_pEncContext->sEncoderStatistics.uiWidth;
|
||||
pStatistics->uiHeight = m_pEncContext->sEncoderStatistics.uiHeight;
|
||||
pStatistics->fAverageFrameSpeedInMs = m_pEncContext->sEncoderStatistics.fAverageFrameSpeedInMs;
|
||||
|
||||
// rate control related
|
||||
pStatistics->fAverageFrameRate = m_pEncContext->sEncoderStatistics.fAverageFrameRate;
|
||||
pStatistics->fLatestFrameRate = m_pEncContext->sEncoderStatistics.fLatestFrameRate;
|
||||
pStatistics->uiBitRate = m_pEncContext->sEncoderStatistics.uiBitRate;
|
||||
|
||||
pStatistics->uiInputFrameCount = m_pEncContext->sEncoderStatistics.uiInputFrameCount;
|
||||
pStatistics->uiSkippedFrameCount = m_pEncContext->sEncoderStatistics.uiSkippedFrameCount;
|
||||
|
||||
pStatistics->uiResolutionChangeTimes = m_pEncContext->sEncoderStatistics.uiResolutionChangeTimes;
|
||||
pStatistics->uiIDRReqNum = m_pEncContext->sEncoderStatistics.uiIDRReqNum;
|
||||
pStatistics->uiIDRSentNum = m_pEncContext->sEncoderStatistics.uiIDRSentNum;
|
||||
pStatistics->uiLTRSentNum = m_pEncContext->sEncoderStatistics.uiLTRSentNum;
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: {
|
||||
* ((int32_t*)pOption) = m_pEncContext->iStatisticsLogInterval;
|
||||
}
|
||||
break;
|
||||
case ENCODER_OPTION_COMPLEXITY: {
|
||||
* ((int32_t*)pOption) = m_pEncContext->pSvcParam->iComplexityMode;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ ENCODER_CPP_SRCS=\
|
||||
|
||||
ENCODER_OBJS += $(ENCODER_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
ENCODER_ASM_SRCS=\
|
||||
$(ENCODER_SRCDIR)/core/x86/coeff.asm\
|
||||
$(ENCODER_SRCDIR)/core/x86/dct.asm\
|
||||
@@ -43,10 +42,12 @@ ENCODER_ASM_SRCS=\
|
||||
$(ENCODER_SRCDIR)/core/x86/sample_sc.asm\
|
||||
$(ENCODER_SRCDIR)/core/x86/score.asm\
|
||||
|
||||
ENCODER_OBJS += $(ENCODER_ASM_SRCS:.asm=.$(OBJ))
|
||||
ENCODER_OBJSASM += $(ENCODER_ASM_SRCS:.asm=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
ENCODER_OBJS += $(ENCODER_OBJSASM)
|
||||
endif
|
||||
OBJS += $(ENCODER_OBJSASM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
ENCODER_ASM_ARM_SRCS=\
|
||||
$(ENCODER_SRCDIR)/core/arm/intra_pred_neon.S\
|
||||
$(ENCODER_SRCDIR)/core/arm/intra_pred_sad_3_opt_neon.S\
|
||||
@@ -55,10 +56,12 @@ ENCODER_ASM_ARM_SRCS=\
|
||||
$(ENCODER_SRCDIR)/core/arm/reconstruct_neon.S\
|
||||
$(ENCODER_SRCDIR)/core/arm/svc_motion_estimation.S\
|
||||
|
||||
ENCODER_OBJS += $(ENCODER_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
ENCODER_OBJSARM += $(ENCODER_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
ENCODER_OBJS += $(ENCODER_OBJSARM)
|
||||
endif
|
||||
OBJS += $(ENCODER_OBJSARM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
ENCODER_ASM_ARM64_SRCS=\
|
||||
$(ENCODER_SRCDIR)/core/arm64/intra_pred_aarch64_neon.S\
|
||||
$(ENCODER_SRCDIR)/core/arm64/intra_pred_sad_3_opt_aarch64_neon.S\
|
||||
@@ -67,10 +70,14 @@ ENCODER_ASM_ARM64_SRCS=\
|
||||
$(ENCODER_SRCDIR)/core/arm64/reconstruct_aarch64_neon.S\
|
||||
$(ENCODER_SRCDIR)/core/arm64/svc_motion_estimation_aarch64_neon.S\
|
||||
|
||||
ENCODER_OBJS += $(ENCODER_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
ENCODER_OBJSARM64 += $(ENCODER_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
ENCODER_OBJS += $(ENCODER_OBJSARM64)
|
||||
endif
|
||||
OBJS += $(ENCODER_OBJSARM64)
|
||||
|
||||
OBJS += $(ENCODER_OBJS)
|
||||
|
||||
$(ENCODER_SRCDIR)/%.$(OBJ): $(ENCODER_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(ENCODER_CFLAGS) $(ENCODER_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -358,11 +358,11 @@
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\common\common.cpp"
|
||||
RelativePath="..\..\..\common\src\cpu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\src\cpu.cpp"
|
||||
RelativePath="..\..\..\common\src\intra_pred_common.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@@ -425,6 +425,10 @@
|
||||
RelativePath="..\..\..\common\inc\cpu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\inc\intra_pred_common.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\common\memory.h"
|
||||
>
|
||||
@@ -461,7 +465,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -479,7 +483,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -501,7 +505,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -519,7 +523,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -574,14 +578,14 @@
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\x86\satd_sad.asm"
|
||||
RelativePath="..\..\..\common\x86\intra_pred_com.asm"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@@ -599,7 +603,47 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\x86\satd_sad.asm"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)
"
|
||||
Outputs="$(IntDir)\$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
||||
@@ -142,14 +142,14 @@ typedef enum {
|
||||
typedef enum {
|
||||
SIMILAR_SCENE, //similar scene
|
||||
MEDIUM_CHANGED_SCENE, //medium changed scene
|
||||
LARGE_CHANGED_SCENE, //large changed scene
|
||||
LARGE_CHANGED_SCENE //large changed scene
|
||||
} ESceneChangeIdc;
|
||||
|
||||
typedef enum {
|
||||
NO_STATIC, // motion block
|
||||
COLLOCATED_STATIC, // collocated static block
|
||||
SCROLLED_STATIC, // scrolled static block
|
||||
BLOCK_STATIC_IDC_ALL,
|
||||
BLOCK_STATIC_IDC_ALL
|
||||
} EStaticBlockIdc;
|
||||
|
||||
typedef struct {
|
||||
@@ -195,7 +195,7 @@ typedef struct {
|
||||
|
||||
typedef enum {
|
||||
AQ_QUALITY_MODE, //Quality mode
|
||||
AQ_BITRATE_MODE, //Bitrate mode
|
||||
AQ_BITRATE_MODE //Bitrate mode
|
||||
} EAQModes;
|
||||
|
||||
typedef struct {
|
||||
@@ -300,8 +300,8 @@ class IWelsVP {
|
||||
#endif
|
||||
|
||||
WELSVP_EXTERNC_BEGIN
|
||||
EResult CreateVpInterface (void** ppCtx, int iVersion /*= WELSVP_INTERFACE_VERION*/);
|
||||
EResult DestroyVpInterface (void* pCtx , int iVersion /*= WELSVP_INTERFACE_VERION*/);
|
||||
EResult WelsCreateVpInterface (void** ppCtx, int iVersion /*= WELSVP_INTERFACE_VERION*/);
|
||||
EResult WelsDestroyVpInterface (void* pCtx , int iVersion /*= WELSVP_INTERFACE_VERION*/);
|
||||
WELSVP_EXTERNC_END
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -57,7 +57,7 @@ CBackgroundDetection::CBackgroundDetection (int32_t iCpuFlag) {
|
||||
}
|
||||
|
||||
CBackgroundDetection::~CBackgroundDetection() {
|
||||
FreeOUArrayMemory();
|
||||
WelsFree (m_BgdParam.pOU_array);
|
||||
}
|
||||
|
||||
EResult CBackgroundDetection::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
|
||||
@@ -80,7 +80,7 @@ EResult CBackgroundDetection::Process (int32_t iType, SPixMap* pSrcPixMap, SPixM
|
||||
|
||||
int32_t iCurFrameSize = m_BgdParam.iBgdWidth * m_BgdParam.iBgdHeight;
|
||||
if (m_BgdParam.pOU_array == NULL || iCurFrameSize > m_iLargestFrameSize) {
|
||||
FreeOUArrayMemory();
|
||||
WelsFree (m_BgdParam.pOU_array);
|
||||
m_BgdParam.pOU_array = AllocateOUArrayMemory (m_BgdParam.iBgdWidth, m_BgdParam.iBgdHeight);
|
||||
m_iLargestFrameSize = iCurFrameSize;
|
||||
}
|
||||
@@ -112,10 +112,6 @@ inline SBackgroundOU* CBackgroundDetection::AllocateOUArrayMemory (int32_t iWidt
|
||||
return (SBackgroundOU*)WelsMalloc (iMaxOUWidth * iMaxOUHeight * sizeof (SBackgroundOU));
|
||||
}
|
||||
|
||||
inline void CBackgroundDetection::FreeOUArrayMemory() {
|
||||
_SafeFree (m_BgdParam.pOU_array);
|
||||
}
|
||||
|
||||
void CBackgroundDetection::GetOUParameters (SVAACalcResult* sVaaCalcInfo, int32_t iMbIndex, int32_t iMbWidth,
|
||||
SBackgroundOU* pBgdOU) {
|
||||
int32_t iSubSD[4];
|
||||
|
||||
@@ -81,7 +81,6 @@ class CBackgroundDetection : public IStrategy {
|
||||
|
||||
private:
|
||||
inline SBackgroundOU* AllocateOUArrayMemory (int32_t iWidth, int32_t iHeight);
|
||||
inline void FreeOUArrayMemory();
|
||||
inline int32_t CalculateAsdChromaEdge (uint8_t* pOriRef, uint8_t* pOriCur, int32_t iStride);
|
||||
inline bool ForegroundDilation23Luma (SBackgroundOU* pBackgroundOU,
|
||||
SBackgroundOU* pOUNeighbours[]); //Foreground_Dilation_2_3_Luma
|
||||
|
||||
@@ -44,20 +44,20 @@
|
||||
|
||||
/* interface API implement */
|
||||
|
||||
EResult CreateVpInterface (void** ppCtx, int iVersion) {
|
||||
EResult WelsCreateVpInterface (void** ppCtx, int iVersion) {
|
||||
if (iVersion & 0x8000)
|
||||
return nsWelsVP::CreateSpecificVpInterface ((IWelsVP**)ppCtx);
|
||||
return WelsVP::CreateSpecificVpInterface ((IWelsVP**)ppCtx);
|
||||
else if (iVersion & 0x7fff)
|
||||
return nsWelsVP::CreateSpecificVpInterface ((IWelsVPc**)ppCtx);
|
||||
return WelsVP::CreateSpecificVpInterface ((IWelsVPc**)ppCtx);
|
||||
else
|
||||
return RET_INVALIDPARAM;
|
||||
}
|
||||
|
||||
EResult DestroyVpInterface (void* pCtx, int iVersion) {
|
||||
EResult WelsDestroyVpInterface (void* pCtx, int iVersion) {
|
||||
if (iVersion & 0x8000)
|
||||
return nsWelsVP::DestroySpecificVpInterface ((IWelsVP*)pCtx);
|
||||
return WelsVP::DestroySpecificVpInterface ((IWelsVP*)pCtx);
|
||||
else if (iVersion & 0x7fff)
|
||||
return nsWelsVP::DestroySpecificVpInterface ((IWelsVPc*)pCtx);
|
||||
return WelsVP::DestroySpecificVpInterface ((IWelsVPc*)pCtx);
|
||||
else
|
||||
return RET_INVALIDPARAM;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ EResult CreateSpecificVpInterface (IWelsVP** ppCtx) {
|
||||
}
|
||||
|
||||
EResult DestroySpecificVpInterface (IWelsVP* pCtx) {
|
||||
_SafeDelete (pCtx);
|
||||
delete pCtx;
|
||||
|
||||
return RET_SUCCESS;
|
||||
}
|
||||
@@ -105,7 +105,7 @@ CVpFrameWork::~CVpFrameWork() {
|
||||
for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++) {
|
||||
if (m_pStgChain[i]) {
|
||||
Uninit (m_pStgChain[i]->m_eMethod);
|
||||
_SafeDelete (m_pStgChain[i]);
|
||||
delete m_pStgChain[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class IStrategy : public IWelsVP {
|
||||
m_eFormat = VIDEO_FORMAT_I420;
|
||||
m_iIndex = 0;
|
||||
m_bInit = false;
|
||||
};
|
||||
}
|
||||
|
||||
virtual ~IStrategy() {}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ EResult CreateSpecificVpInterface (IWelsVPc** pCtx) {
|
||||
EResult DestroySpecificVpInterface (IWelsVPc* pCtx) {
|
||||
if (pCtx) {
|
||||
DestroySpecificVpInterface (WelsStaticCast (IWelsVP*, pCtx->pCtx));
|
||||
_SafeDelete (pCtx);
|
||||
delete pCtx;
|
||||
}
|
||||
|
||||
return RET_SUCCESS;
|
||||
|
||||
@@ -32,5 +32,5 @@
|
||||
|
||||
LIBRARY welsvp.dll
|
||||
EXPORTS
|
||||
CreateVpInterface
|
||||
DestroyVpInterface
|
||||
WelsCreateVpInterface
|
||||
WelsDestroyVpInterface
|
||||
@@ -38,14 +38,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WELSVP_SCENECHANGEDETECTIONCOMMON_H
|
||||
#define WELSVP_SCENECHANGEDETECTIONCOMMON_H
|
||||
#ifndef WELSVP_COMMON_H
|
||||
#define WELSVP_COMMON_H
|
||||
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "WelsFrameWork.h"
|
||||
#include "IWelsVP.h"
|
||||
#include "sad_common.h"
|
||||
#include "intra_pred_common.h"
|
||||
|
||||
|
||||
|
||||
typedef void (GetIntraPred) (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
|
||||
typedef GetIntraPred* GetIntraPredPtr;
|
||||
|
||||
GetIntraPred WelsI16x16LumaPredV_c;
|
||||
GetIntraPred WelsI16x16LumaPredH_c;
|
||||
|
||||
WELSVP_NAMESPACE_BEGIN
|
||||
|
||||
@@ -56,12 +66,6 @@ typedef SadFunc* SadFuncPtr;
|
||||
typedef int32_t (Sad16x16Func) (uint8_t* pSrcY, int32_t iSrcStrideY, uint8_t* pRefY, int32_t iRefStrideY);
|
||||
typedef Sad16x16Func* PSad16x16Func;
|
||||
|
||||
typedef void (GetIntraPred) (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
|
||||
|
||||
typedef GetIntraPred* GetIntraPredPtr;
|
||||
|
||||
GetIntraPred WelsI16x16LumaPredV_c;
|
||||
GetIntraPred WelsI16x16LumaPredH_c;
|
||||
|
||||
#ifdef HAVE_NEON
|
||||
WELSVP_EXTERN_C_BEGIN
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#define WELSVP_EXTERN_C_BEGIN extern "C" {
|
||||
#define WELSVP_EXTERN_C_END }
|
||||
|
||||
#define WELSVP_NAMESPACE_BEGIN namespace nsWelsVP {
|
||||
#define WELSVP_NAMESPACE_BEGIN namespace WelsVP {
|
||||
#define WELSVP_NAMESPACE_END }
|
||||
|
||||
// Get the stdint type definitions from typedefs.h in the common lib
|
||||
|
||||
@@ -102,9 +102,6 @@ inline EMethods WelsVpGetValidMethod (int32_t a) {
|
||||
}
|
||||
|
||||
|
||||
#define _SafeFree(p) if (p) { WelsFree(p); (p) = NULL; }
|
||||
#define _SafeDelete(p) if (p) { delete (p); (p) = NULL; }
|
||||
|
||||
|
||||
WELSVP_NAMESPACE_END
|
||||
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
#include "ComplexityAnalysis.h"
|
||||
#include "cpu.h"
|
||||
#include "macros.h"
|
||||
#include "intra_pred_common.h"
|
||||
|
||||
WELSVP_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CComplexityAnalysis::CComplexityAnalysis (int32_t iCpuFlag) {
|
||||
@@ -280,8 +280,29 @@ CComplexityAnalysisScreen::CComplexityAnalysisScreen (int32_t iCpuFlag) {
|
||||
#ifdef X86_ASM
|
||||
if (iCpuFlag & WELS_CPU_SSE2) {
|
||||
m_pSadFunc = WelsSampleSad16x16_sse2;
|
||||
m_pIntraFunc[0] = WelsI16x16LumaPredV_sse2;
|
||||
m_pIntraFunc[1] = WelsI16x16LumaPredH_sse2;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_NEON)
|
||||
if (iCpuFlag & WELS_CPU_NEON) {
|
||||
m_pSadFunc = WelsSampleSad16x16_neon;
|
||||
m_pIntraFunc[0] = WelsI16x16LumaPredV_neon;
|
||||
m_pIntraFunc[1] = WelsI16x16LumaPredH_neon;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_NEON_AARCH64)
|
||||
if (iCpuFlag & WELS_CPU_NEON) {
|
||||
m_pSadFunc = WelsSampleSad16x16_AArch64_neon;
|
||||
m_pIntraFunc[0] = WelsI16x16LumaPredV_AArch64_neon;
|
||||
m_pIntraFunc[1] = WelsI16x16LumaPredH_AArch64_neon;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
CComplexityAnalysisScreen::~CComplexityAnalysisScreen() {
|
||||
|
||||
@@ -51,7 +51,7 @@ class CScrollDetection : public IStrategy {
|
||||
CScrollDetection (int32_t iCpuFlag) {
|
||||
m_eMethod = METHOD_SCROLL_DETECTION;
|
||||
WelsMemset (&m_sScrollDetectionParam, 0, sizeof (m_sScrollDetectionParam));
|
||||
};
|
||||
}
|
||||
~CScrollDetection() {
|
||||
}
|
||||
EResult Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap);
|
||||
|
||||
@@ -2,7 +2,6 @@ PROCESSING_SRCDIR=codec/processing
|
||||
PROCESSING_CPP_SRCS=\
|
||||
$(PROCESSING_SRCDIR)/src/adaptivequantization/AdaptiveQuantization.cpp\
|
||||
$(PROCESSING_SRCDIR)/src/backgrounddetection/BackgroundDetection.cpp\
|
||||
$(PROCESSING_SRCDIR)/src/common/common.cpp\
|
||||
$(PROCESSING_SRCDIR)/src/common/memory.cpp\
|
||||
$(PROCESSING_SRCDIR)/src/common/WelsFrameWork.cpp\
|
||||
$(PROCESSING_SRCDIR)/src/common/WelsFrameWorkEx.cpp\
|
||||
@@ -21,36 +20,43 @@ PROCESSING_CPP_SRCS=\
|
||||
|
||||
PROCESSING_OBJS += $(PROCESSING_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
PROCESSING_ASM_SRCS=\
|
||||
$(PROCESSING_SRCDIR)/src/x86/denoisefilter.asm\
|
||||
$(PROCESSING_SRCDIR)/src/x86/downsample_bilinear.asm\
|
||||
$(PROCESSING_SRCDIR)/src/x86/vaa.asm\
|
||||
|
||||
PROCESSING_OBJS += $(PROCESSING_ASM_SRCS:.asm=.$(OBJ))
|
||||
PROCESSING_OBJSASM += $(PROCESSING_ASM_SRCS:.asm=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
PROCESSING_OBJS += $(PROCESSING_OBJSASM)
|
||||
endif
|
||||
OBJS += $(PROCESSING_OBJSASM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
PROCESSING_ASM_ARM_SRCS=\
|
||||
$(PROCESSING_SRCDIR)/src/arm/adaptive_quantization.S\
|
||||
$(PROCESSING_SRCDIR)/src/arm/down_sample_neon.S\
|
||||
$(PROCESSING_SRCDIR)/src/arm/pixel_sad_neon.S\
|
||||
$(PROCESSING_SRCDIR)/src/arm/vaa_calc_neon.S\
|
||||
|
||||
PROCESSING_OBJS += $(PROCESSING_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
PROCESSING_OBJSARM += $(PROCESSING_ASM_ARM_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm)
|
||||
PROCESSING_OBJS += $(PROCESSING_OBJSARM)
|
||||
endif
|
||||
OBJS += $(PROCESSING_OBJSARM)
|
||||
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
PROCESSING_ASM_ARM64_SRCS=\
|
||||
$(PROCESSING_SRCDIR)/src/arm64/adaptive_quantization_aarch64_neon.S\
|
||||
$(PROCESSING_SRCDIR)/src/arm64/down_sample_aarch64_neon.S\
|
||||
$(PROCESSING_SRCDIR)/src/arm64/pixel_sad_aarch64_neon.S\
|
||||
$(PROCESSING_SRCDIR)/src/arm64/vaa_calc_aarch64_neon.S\
|
||||
|
||||
PROCESSING_OBJS += $(PROCESSING_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
PROCESSING_OBJSARM64 += $(PROCESSING_ASM_ARM64_SRCS:.S=.$(OBJ))
|
||||
ifeq ($(ASM_ARCH), arm64)
|
||||
PROCESSING_OBJS += $(PROCESSING_OBJSARM64)
|
||||
endif
|
||||
OBJS += $(PROCESSING_OBJSARM64)
|
||||
|
||||
OBJS += $(PROCESSING_OBJS)
|
||||
|
||||
$(PROCESSING_SRCDIR)/%.$(OBJ): $(PROCESSING_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(PROCESSING_CFLAGS) $(PROCESSING_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ MODULE_CPP_SRCS=\
|
||||
MODULE_OBJS += $(MODULE_CPP_SRCS:.cpp=.$(OBJ))
|
||||
|
||||
OBJS += $(MODULE_OBJS)
|
||||
|
||||
$(MODULE_SRCDIR)/%.$(OBJ): $(MODULE_SRCDIR)/%.cpp
|
||||
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(MODULE_CFLAGS) $(MODULE_INCLUDES) -c $(CXX_O) $<
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ class BaseEncoderTest {
|
||||
void SetUp();
|
||||
void TearDown();
|
||||
void EncodeFile (const char* fileName, EUsageType usageType, int width, int height, float frameRate,
|
||||
SliceModeEnum slices, bool denoise, int layers, Callback* cbk);
|
||||
SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk);
|
||||
void EncodeStream (InputStream* in, EUsageType usageType, int width, int height, float frameRate, SliceModeEnum slices,
|
||||
bool denoise, int layers, Callback* cbk);
|
||||
bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk);
|
||||
|
||||
ISVCEncoder* encoder_;
|
||||
private:
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "BaseEncoderTest.h"
|
||||
|
||||
static int InitWithParam (ISVCEncoder* encoder, EUsageType usageType, int width,
|
||||
int height, float frameRate, SliceModeEnum sliceMode, bool denoise, int layers) {
|
||||
if (SM_SINGLE_SLICE == sliceMode && !denoise && layers == 1) {
|
||||
int height, float frameRate, SliceModeEnum sliceMode, bool denoise, int layers, bool losslessLink, bool enableLtr) {
|
||||
if (SM_SINGLE_SLICE == sliceMode && !denoise && layers == 1 && !losslessLink && !enableLtr) {
|
||||
SEncParamBase param;
|
||||
memset (¶m, 0, sizeof (SEncParamBase));
|
||||
|
||||
@@ -29,6 +29,8 @@ static int InitWithParam (ISVCEncoder* encoder, EUsageType usageType, int width,
|
||||
param.iTargetBitrate = 5000000;
|
||||
param.bEnableDenoise = denoise;
|
||||
param.iSpatialLayerNum = layers;
|
||||
param.bIsLosslessLink = losslessLink;
|
||||
param.bEnableLongTermReference = enableLtr;
|
||||
|
||||
if (sliceMode != SM_SINGLE_SLICE && sliceMode != SM_DYN_SLICE) //SM_DYN_SLICE don't support multi-thread now
|
||||
param.iMultipleThreadIdc = 2;
|
||||
@@ -67,8 +69,9 @@ void BaseEncoderTest::TearDown() {
|
||||
}
|
||||
|
||||
void BaseEncoderTest::EncodeStream (InputStream* in, EUsageType usageType, int width, int height,
|
||||
float frameRate, SliceModeEnum slices, bool denoise, int layers, Callback* cbk) {
|
||||
int rv = InitWithParam (encoder_, usageType, width, height, frameRate, slices, denoise, layers);
|
||||
float frameRate, SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk) {
|
||||
int rv = InitWithParam (encoder_, usageType, width, height, frameRate, slices, denoise, layers, losslessLink,
|
||||
enableLtr);
|
||||
ASSERT_TRUE (rv == cmResultSuccess);
|
||||
|
||||
// I420: 1(Y) + 1/4(U) + 1/4(V)
|
||||
@@ -101,8 +104,8 @@ void BaseEncoderTest::EncodeStream (InputStream* in, EUsageType usageType, int w
|
||||
}
|
||||
|
||||
void BaseEncoderTest::EncodeFile (const char* fileName, EUsageType usageType, int width, int height,
|
||||
float frameRate, SliceModeEnum slices, bool denoise, int layers, Callback* cbk) {
|
||||
float frameRate, SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk) {
|
||||
FileInputStream fileStream;
|
||||
ASSERT_TRUE (fileStream.Open (fileName));
|
||||
EncodeStream (&fileStream, usageType, width, height, frameRate, slices, denoise, layers, cbk);
|
||||
EncodeStream (&fileStream, usageType, width, height, frameRate, slices, denoise, layers, losslessLink, enableLtr, cbk);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user