Compare commits
335 Commits
openh264v1
...
v1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef5f1c46b9 | ||
|
|
7d8bb6f290 | ||
|
|
809adc4129 | ||
|
|
f0934c7bf3 | ||
|
|
c3de0f99c5 | ||
|
|
3ae2507c99 | ||
|
|
afd82b2cfa | ||
|
|
0dc461541a | ||
|
|
8bfeae27a4 | ||
|
|
4fb442a983 | ||
|
|
91574afca4 | ||
|
|
b8ce2eb40e | ||
|
|
e6134b5972 | ||
|
|
5b2469c0b5 | ||
|
|
4db34bdf43 | ||
|
|
b208cac1c5 | ||
|
|
916d24d99e | ||
|
|
7f27198c68 | ||
|
|
208400eeb4 | ||
|
|
ab480fe387 | ||
|
|
58e868c074 | ||
|
|
8dbdb418ca | ||
|
|
1b26bd4b88 | ||
|
|
3c08f04993 | ||
|
|
030d320e43 | ||
|
|
182ae421a1 | ||
|
|
9f0ed3fc4b | ||
|
|
ac992acaa9 | ||
|
|
490a3e5562 | ||
|
|
590eef6059 | ||
|
|
affa753d5d | ||
|
|
f89780ddd8 | ||
|
|
6f876d79a6 | ||
|
|
ee5896e4a1 | ||
|
|
4746ce8fd4 | ||
|
|
f90cd367d2 | ||
|
|
47df411b1a | ||
|
|
9692f6cb20 | ||
|
|
f4b3724976 | ||
|
|
59fefbe7c7 | ||
|
|
a9c2e1b431 | ||
|
|
a4370b8ca8 | ||
|
|
0612b07a6f | ||
|
|
6a10553dce | ||
|
|
f132745882 | ||
|
|
89f78e9211 | ||
|
|
fdb938a2c2 | ||
|
|
b932547fe8 | ||
|
|
d387ebc358 | ||
|
|
026ce4030a | ||
|
|
2c69638773 | ||
|
|
812b57c704 | ||
|
|
ca2436bb5e | ||
|
|
827c7b2aef | ||
|
|
d87663b913 | ||
|
|
c0633a147e | ||
|
|
91736e85e8 | ||
|
|
54cc3daaa7 | ||
|
|
8a2237751a | ||
|
|
3aac5e0fae | ||
|
|
8fb4048241 | ||
|
|
57043d16ad | ||
|
|
d422ee59ad | ||
|
|
ac061fe635 | ||
|
|
091e5cba0a | ||
|
|
eeee1a2e95 | ||
|
|
c20e1c6795 | ||
|
|
509727e225 | ||
|
|
5ab5fe155b | ||
|
|
7dcaaf5328 | ||
|
|
ad38cfe46c | ||
|
|
cc1f3ade3a | ||
|
|
984497cc09 | ||
|
|
06c251fa48 | ||
|
|
93265d7a44 | ||
|
|
1bdf00ddf4 | ||
|
|
41339f3023 | ||
|
|
0ff1eb482f | ||
|
|
ec99819ce8 | ||
|
|
3be8ae7a4e | ||
|
|
2e85e3c7d9 | ||
|
|
f1a7a1a966 | ||
|
|
3e57fdc448 | ||
|
|
5ff55a6ec2 | ||
|
|
44e4531897 | ||
|
|
44bd61683a | ||
|
|
d20a3bdb28 | ||
|
|
32d6193f97 | ||
|
|
5ba9e409ba | ||
|
|
2c468b96a9 | ||
|
|
ecc8ae6ebb | ||
|
|
065c3a7769 | ||
|
|
7da17b5abd | ||
|
|
af97f2d4bb | ||
|
|
4e88de1755 | ||
|
|
87c83c0d36 | ||
|
|
44017193ed | ||
|
|
b65410ebdb | ||
|
|
354eee3e2b | ||
|
|
155a91406c | ||
|
|
e47a3638af | ||
|
|
944a041066 | ||
|
|
14eeaf2278 | ||
|
|
e041bc6938 | ||
|
|
901a599b36 | ||
|
|
cc5978b252 | ||
|
|
c2d585761a | ||
|
|
317ac1ca85 | ||
|
|
56c895ffb4 | ||
|
|
c01606c28a | ||
|
|
ea93f3943e | ||
|
|
a8159c89d1 | ||
|
|
befd5bdd56 | ||
|
|
fc895c13ce | ||
|
|
054b8eeb3a | ||
|
|
60b6ce1454 | ||
|
|
928a7eac2a | ||
|
|
a5cabf0be4 | ||
|
|
91ae2dab7a | ||
|
|
dd24edc8ff | ||
|
|
5d4eb63d52 | ||
|
|
f4af5d2fda | ||
|
|
6981aec743 | ||
|
|
8b9be2b3dc | ||
|
|
f668e1be98 | ||
|
|
607d814e0f | ||
|
|
3d263d1087 | ||
|
|
9b59e50292 | ||
|
|
a48b632aed | ||
|
|
e132658346 | ||
|
|
59c30f8952 | ||
|
|
575b6fb570 | ||
|
|
2c9b5b98c0 | ||
|
|
8e419e41d3 | ||
|
|
80beaed5c6 | ||
|
|
8f7e10ab12 | ||
|
|
a7d8142a44 | ||
|
|
397e20b0f3 | ||
|
|
852ed8a2d0 | ||
|
|
2e15351d6d | ||
|
|
b1dccaa627 | ||
|
|
8c7aaa8421 | ||
|
|
9a08b7f97c | ||
|
|
a100fb8031 | ||
|
|
8e39cb3a3a | ||
|
|
d58f90947c | ||
|
|
8028fe7130 | ||
|
|
c592d18dfd | ||
|
|
30820fd8b5 | ||
|
|
7cea82bdf8 | ||
|
|
e7debe7351 | ||
|
|
59e782a8a5 | ||
|
|
1526de3ae5 | ||
|
|
0bae0f869a | ||
|
|
24cd934ba9 | ||
|
|
90eee67eb7 | ||
|
|
b9dc310857 | ||
|
|
504cabf106 | ||
|
|
c44d4a7f07 | ||
|
|
917d41bd47 | ||
|
|
7c0369da23 | ||
|
|
82b70b34fe | ||
|
|
3a73179cab | ||
|
|
69f6db1b90 | ||
|
|
c2c861f199 | ||
|
|
3f69873c99 | ||
|
|
92bc88eacb | ||
|
|
80ce939d7a | ||
|
|
a43fa3aec2 | ||
|
|
e1262a9ac9 | ||
|
|
fe7faf768a | ||
|
|
aa5e7f7927 | ||
|
|
9da19758cf | ||
|
|
f131b4540b | ||
|
|
2e5243e5fc | ||
|
|
4a6de5bb13 | ||
|
|
347e4893a9 | ||
|
|
94dde141fa | ||
|
|
f48b2e55ba | ||
|
|
7be8d200d5 | ||
|
|
1ff9de36ce | ||
|
|
22cc0a88c6 | ||
|
|
0d426b826d | ||
|
|
d543ae89db | ||
|
|
29da6a600a | ||
|
|
cef85118b5 | ||
|
|
305a2421be | ||
|
|
f1fb0d6b69 | ||
|
|
9425c2ab10 | ||
|
|
3be7e90221 | ||
|
|
48e79d51b5 | ||
|
|
336b2d1537 | ||
|
|
b231e3f000 | ||
|
|
53c14dccf0 | ||
|
|
3025c58a67 | ||
|
|
a0b0866597 | ||
|
|
1359583c55 | ||
|
|
7175d3c90e | ||
|
|
cdd410ca66 | ||
|
|
24fb213d6e | ||
|
|
0b2c82d92b | ||
|
|
810b9770fc | ||
|
|
b18e905946 | ||
|
|
c13bfe6407 | ||
|
|
0252f3f346 | ||
|
|
b05a52be7a | ||
|
|
7e24efc620 | ||
|
|
02853a9a96 | ||
|
|
cbb6e993cf | ||
|
|
bfee07dde4 | ||
|
|
deefdcee10 | ||
|
|
45c322a8ae | ||
|
|
606da1a97d | ||
|
|
9ec743c156 | ||
|
|
0d16fd61b2 | ||
|
|
703bbef128 | ||
|
|
b56b8725fc | ||
|
|
aed7b2316c | ||
|
|
2453676960 | ||
|
|
7a2e536e44 | ||
|
|
66165a65d5 | ||
|
|
b3922b1d3a | ||
|
|
e4f114e006 | ||
|
|
429ccb38a8 | ||
|
|
9ba0a1d977 | ||
|
|
2527cf5d0b | ||
|
|
cd5928d397 | ||
|
|
f42c9fae42 | ||
|
|
a37f1abe5e | ||
|
|
128546b992 | ||
|
|
560fcf17fd | ||
|
|
fd45e7ff15 | ||
|
|
9512515a41 | ||
|
|
24823621e1 | ||
|
|
c31511257b | ||
|
|
1c44c43b8a | ||
|
|
0aa77d2985 | ||
|
|
8b49f98475 | ||
|
|
fc811a80fb | ||
|
|
843955bc06 | ||
|
|
a7b22795bf | ||
|
|
3c753c42b8 | ||
|
|
067fa09781 | ||
|
|
c8afd15681 | ||
|
|
80bfc43df5 | ||
|
|
50e2eb5e3c | ||
|
|
2b9f4f6607 | ||
|
|
08c07e4b8f | ||
|
|
ac404ce69d | ||
|
|
44013d4cd5 | ||
|
|
789603a8b1 | ||
|
|
7fa6c576e3 | ||
|
|
0fa667ac5f | ||
|
|
1a7826c6eb | ||
|
|
5cb5c28331 | ||
|
|
45ef803e4d | ||
|
|
3d21825901 | ||
|
|
ba0351f569 | ||
|
|
63180b9b36 | ||
|
|
8ed4e83e93 | ||
|
|
32697b046b | ||
|
|
b896faa47c | ||
|
|
103fa5bbed | ||
|
|
fe55d5a208 | ||
|
|
18ed25fbb3 | ||
|
|
783daf3d8a | ||
|
|
54c677cdd7 | ||
|
|
08baf65251 | ||
|
|
ca1c357058 | ||
|
|
8ffacf0918 | ||
|
|
0e9541247a | ||
|
|
c1b48640fb | ||
|
|
c5029ef275 | ||
|
|
e061bb3fc9 | ||
|
|
2951a7f3a3 | ||
|
|
7478714ac9 | ||
|
|
9ac2d2ad85 | ||
|
|
dbd4330508 | ||
|
|
938f441751 | ||
|
|
880e0fff06 | ||
|
|
c19db25043 | ||
|
|
cf85745752 | ||
|
|
c7b5051738 | ||
|
|
07bf80ba39 | ||
|
|
53e2f67e80 | ||
|
|
3abd54ca73 | ||
|
|
8e49898243 | ||
|
|
66b1610114 | ||
|
|
24192cc235 | ||
|
|
655f3b43b6 | ||
|
|
a291470072 | ||
|
|
ec0d151879 | ||
|
|
3b5448cbbc | ||
|
|
055915d720 | ||
|
|
100de97b49 | ||
|
|
3a1f0a3d95 | ||
|
|
41ed734674 | ||
|
|
b8e0a3fa38 | ||
|
|
7ce4da8a41 | ||
|
|
1c2940479d | ||
|
|
2907cb2875 | ||
|
|
a625dc836d | ||
|
|
9be23c7821 | ||
|
|
7f645bf2f7 | ||
|
|
54c24dfd60 | ||
|
|
c83ab3bca1 | ||
|
|
58cc29225e | ||
|
|
d3a971e32c | ||
|
|
329ccd7d6f | ||
|
|
f10f6a788f | ||
|
|
f84560474c | ||
|
|
f2c1395ab6 | ||
|
|
9a9f92bcfe | ||
|
|
26615fffd0 | ||
|
|
a2d5254bc3 | ||
|
|
4fab8c2ee7 | ||
|
|
292d2511e2 | ||
|
|
4292f91ae5 | ||
|
|
5cefad2d3f | ||
|
|
fcb84f5fb6 | ||
|
|
fe621b92bf | ||
|
|
1ad797a81e | ||
|
|
9a72378c34 | ||
|
|
ec901a14d6 | ||
|
|
abc01e6b81 | ||
|
|
d3c8ade8d0 | ||
|
|
46d30cd33c | ||
|
|
2dbb757d30 | ||
|
|
34cb0d60aa | ||
|
|
6a2a4efef6 | ||
|
|
ea9b80adb3 | ||
|
|
468fce0887 | ||
|
|
f0c6891627 | ||
|
|
50fd617e86 | ||
|
|
ac290d65c7 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -44,3 +44,6 @@ testbin/test_vd_rc.264
|
||||
testbin/test_vd_rc.yuv
|
||||
testbin/test.264
|
||||
testbin/test.yuv
|
||||
|
||||
# pkg-config file
|
||||
*.pc
|
||||
|
||||
39
Makefile
39
Makefile
@@ -22,10 +22,12 @@ V=Yes
|
||||
PREFIX=/usr/local
|
||||
SHARED=-shared
|
||||
OBJ=o
|
||||
SHAREDLIB_DIR=$(PREFIX)/lib
|
||||
PROJECT_NAME=openh264
|
||||
MODULE_NAME=gmpopenh264
|
||||
GMP_API_BRANCH=master
|
||||
GMP_API_BRANCH=Firefox36
|
||||
CCASFLAGS=$(CFLAGS)
|
||||
VERSION=1.2
|
||||
|
||||
ifeq (,$(wildcard $(SRC_PATH)gmp-api))
|
||||
HAVE_GMP_API=No
|
||||
@@ -53,6 +55,7 @@ CFLAGS += -fsanitize=address
|
||||
LDFLAGS += -fsanitize=address
|
||||
endif
|
||||
|
||||
SHAREDLIBVERSION=0
|
||||
include $(SRC_PATH)build/platform-$(OS).mk
|
||||
|
||||
|
||||
@@ -122,7 +125,7 @@ API_TEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) -I$(SRC_PATH)test -I$(SRC_PATH)t
|
||||
COMMON_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(DECODER_INCLUDES) -I$(SRC_PATH)test -I$(SRC_PATH)test/common
|
||||
MODULE_INCLUDES += -I$(SRC_PATH)gmp-api
|
||||
|
||||
.PHONY: test gtest-bootstrap clean
|
||||
.PHONY: test gtest-bootstrap clean $(PROJECT_NAME).pc
|
||||
|
||||
all: libraries binaries
|
||||
|
||||
@@ -183,29 +186,42 @@ else
|
||||
libraries: $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX)
|
||||
endif
|
||||
|
||||
LIBRARIES += $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX) $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX)
|
||||
LIBRARIES += $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX) $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER)
|
||||
|
||||
$(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
|
||||
$(QUIET)rm -f $@
|
||||
$(QUIET_AR)$(AR) $(AR_OPTS) $+
|
||||
|
||||
$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
|
||||
$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
|
||||
$(QUIET)rm -f $@
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(SHLDFLAGS)
|
||||
|
||||
ifneq ($(SHAREDLIBSUFFIXVER),$(SHAREDLIBSUFFIX))
|
||||
$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX): $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER)
|
||||
$(QUIET)ln -sfn $+ $@
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_GMP_API),Yes)
|
||||
plugin: $(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX)
|
||||
LIBRARIES += $(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX)
|
||||
LIBRARIES += $(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIXVER)
|
||||
else
|
||||
plugin:
|
||||
@echo "./gmp-api : No such file or directory."
|
||||
@echo "You do not have gmp-api. Run make gmp-bootstrap to get the gmp-api headers."
|
||||
endif
|
||||
|
||||
$(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX): $(MODULE_OBJS) $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
|
||||
$(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIXVER): $(MODULE_OBJS) $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
|
||||
$(QUIET)rm -f $@
|
||||
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(SHLDFLAGS) $(MODULE_LDFLAGS)
|
||||
|
||||
ifneq ($(SHAREDLIBSUFFIXVER),$(SHAREDLIBSUFFIX))
|
||||
$(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX): $(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIXVER)
|
||||
$(QUIET)ln -sfn $+ $@
|
||||
endif
|
||||
|
||||
$(PROJECT_NAME).pc: $(PROJECT_NAME).pc.in
|
||||
@sed -e 's;@prefix@;$(PREFIX);' -e 's;@VERSION@;$(VERSION);' < $(PROJECT_NAME).pc.in > $(PROJECT_NAME).pc
|
||||
|
||||
install-headers:
|
||||
mkdir -p $(PREFIX)/include/wels
|
||||
install -m 644 codec/api/svc/codec*.h $(PREFIX)/include/wels
|
||||
@@ -214,9 +230,14 @@ install-static: $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX) install-headers
|
||||
mkdir -p $(PREFIX)/lib
|
||||
install -m 644 $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX) $(PREFIX)/lib
|
||||
|
||||
install-shared: $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX) install-headers
|
||||
mkdir -p $(PREFIX)/lib
|
||||
install -m 755 $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX) $(PREFIX)/lib
|
||||
install-shared: $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX) install-headers $(PROJECT_NAME).pc
|
||||
mkdir -p $(SHAREDLIB_DIR)
|
||||
install -m 755 $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER) $(SHAREDLIB_DIR)
|
||||
if [ "$(SHAREDLIBSUFFIXVER)" != "$(SHAREDLIBSUFFIX)" ]; then \
|
||||
cp -a $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX) $(SHAREDLIB_DIR); \
|
||||
fi
|
||||
mkdir -p $(PREFIX)/lib/pkgconfig
|
||||
install -m 444 $(PROJECT_NAME).pc $(PREFIX)/lib/pkgconfig
|
||||
ifneq ($(EXTRA_LIBRARY),)
|
||||
install -m 644 $(EXTRA_LIBRARY) $(PREFIX)/lib
|
||||
endif
|
||||
|
||||
44
RELEASES
44
RELEASES
@@ -1,5 +1,35 @@
|
||||
|
||||
Releases
|
||||
-----------
|
||||
v1.3.0
|
||||
------
|
||||
- Removed manual API document, now using wiki: https://github.com/cisco/openh264/wiki (0af48e5 for v1.3.0)
|
||||
- Added API version in API header files
|
||||
- Added pkg-config file
|
||||
- Added decoder support of parsing only (bParseOnly) for only parsing bit stream but not decoding
|
||||
- Added timestamp and max nal size in gmp-openh264.cpp when calling encoding
|
||||
- Added timestamp info in decoder input and return structure
|
||||
- Added support of level 9 in decoder
|
||||
- Added total length of the encoded frame in encoder return structure
|
||||
- Added SetOption(ENCODER_OPTION_SVC_ENCODE_PARAM_BASE,&base) for encoder
|
||||
- Set constraint set 0 and 1 flags for non-scalable
|
||||
- Improved error concealment algorithms and provide more modes of error-concealment
|
||||
- Improved rate control algorithms and reference selection algorithms for screen content encoding
|
||||
- Added encoder and decoder statistics interface
|
||||
- Improved input parameter checking and logging
|
||||
- Bug fixes, warning reductions, and test improvements
|
||||
|
||||
-----------
|
||||
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
|
||||
------
|
||||
@@ -15,6 +45,20 @@ Binaries
|
||||
These binary releases are distributed under this license:
|
||||
http://www.openh264.org/BINARY_LICENSE.txt
|
||||
|
||||
v1.3.0
|
||||
------
|
||||
// to be added
|
||||
|
||||
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
|
||||
|
||||
@@ -35,7 +35,9 @@ LIBSUFFIX=lib
|
||||
LIBPREFIX=
|
||||
EXEEXT=.exe
|
||||
OBJ=obj
|
||||
SHAREDLIB_DIR = $(PREFIX)/bin
|
||||
SHAREDLIBSUFFIX=dll
|
||||
SHAREDLIBSUFFIXVER=$(SHAREDLIBSUFFIX)
|
||||
SHARED=-LD
|
||||
SHLDFLAGS=-link -def:openh264.def -implib:$(PROJECT_NAME)_dll.lib
|
||||
EXTRA_LIBRARY=$(PROJECT_NAME)_dll.lib
|
||||
SHLDFLAGS=-link -def:openh264.def -implib:$(EXTRA_LIBRARY)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
ARCH = arm
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIBSUFFIX = so
|
||||
# Android APK/JARs expect libraries to be unversioned
|
||||
SHAREDLIBSUFFIXVER=$(SHAREDLIBSUFFIX)
|
||||
SHLDFLAGS =
|
||||
NDKLEVEL = 12
|
||||
ifeq ($(ARCH), arm)
|
||||
ifneq ($(APP_ABI), armeabi)
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIB_DIR = $(PREFIX)/lib
|
||||
SHAREDLIBSUFFIX = dylib
|
||||
SHAREDLIBSUFFIXVER=$(SHAREDLIBVERSION).$(SHAREDLIBSUFFIX)
|
||||
SHLDFLAGS = -dynamiclib -twolevel_namespace -undefined dynamic_lookup \
|
||||
-fno-common -headerpad_max_install_names -install_name \
|
||||
$(SHAREDLIB_DIR)/$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER)
|
||||
SHARED = -dynamiclib
|
||||
CFLAGS += -Wall -fPIC -MMD -MP
|
||||
LDFLAGS += -lpthread
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIBSUFFIX = so
|
||||
SHAREDLIBSUFFIXVER=$(SHAREDLIBSUFFIX).$(SHAREDLIBVERSION)
|
||||
SHLDFLAGS = -Wl,-soname,$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER)
|
||||
CFLAGS += -fPIC
|
||||
LDFLAGS += -lpthread
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
include $(SRC_PATH)build/arch.mk
|
||||
SHAREDLIBSUFFIX = so
|
||||
SHAREDLIBSUFFIXVER=$(SHAREDLIBSUFFIX).$(SHAREDLIBVERSION)
|
||||
SHLDFLAGS = -Wl,-soname,$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER)
|
||||
CFLAGS += -Wall -fno-strict-aliasing -fPIC -MMD -MP
|
||||
LDFLAGS += -lpthread
|
||||
ifeq ($(ASM_ARCH), x86)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
include $(SRC_PATH)build/x86-common.mk
|
||||
SHAREDLIB_DIR = $(PREFIX)/bin
|
||||
SHAREDLIBSUFFIX = dll
|
||||
SHAREDLIBSUFFIXVER=$(SHAREDLIBSUFFIX)
|
||||
EXTRA_LIBRARY=$(LIBPREFIX)$(PROJECT_NAME).dll.a
|
||||
SHLDFLAGS = -Wl,--out-implib,$(EXTRA_LIBRARY)
|
||||
CFLAGS += -MMD -MP
|
||||
LDFLAGS +=
|
||||
ifeq ($(ENABLE64BIT), Yes)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*!
|
||||
*@page License
|
||||
*
|
||||
* \copy
|
||||
* Copyright (c) 2013, Cisco Systems
|
||||
* All rights reserved.
|
||||
@@ -50,73 +52,363 @@ typedef unsigned char bool;
|
||||
#define EXTAPI
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file codec_api.h
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page Overview
|
||||
* * This page is for openh264 codec API usage.
|
||||
* * For how to use the encoder,please refer to page UsageExampleForEncoder
|
||||
* * For how to use the decoder,please refer to page UsageExampleForDecoder
|
||||
* * For more detail about ISVEncoder,please refer to page ISVCEnoder
|
||||
* * For more detail about ISVDecoder,please refer to page ISVCDecoder
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page DecoderUsageExample
|
||||
*
|
||||
* @brief
|
||||
* * An example for using the decoder for Decoding only or Parsing only
|
||||
*
|
||||
* Step 1:decoder declaration
|
||||
* @code
|
||||
*
|
||||
* //decoder declaration
|
||||
* ISVCDecoder *pSvcDecoder;
|
||||
* //input: encoded bitstream start position; should include start code prefix
|
||||
* unsigned char *pBuf =...;
|
||||
* //input: encoded bit stream length; should include the size of start code prefix
|
||||
* int iSize =...;
|
||||
* //output: [0~2] for Y,U,V buffer for Decoding only
|
||||
* unsigned char *pData[3] =...;
|
||||
* //in-out: for Decoding only: declare and initialize the output buffer info, this should never co-exist with Parsing only
|
||||
* SBufferInfo sDstBufInfo;
|
||||
* memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
|
||||
* //in-out: for Parsing only: declare and initialize the output bitstream buffer info for parse only, this should never co-exist with Decoding only
|
||||
* SParserBsInfo sDstParseInfo;
|
||||
* memset(&sDstParseInfo, 0, sizeof(SParserBsInfo));
|
||||
* sDstParseInfo.pDstBuff = new unsigned char[PARSE_SIZE]; //In Parsing only, allocate enough buffer to save transcoded bitstream for a frame
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* Step 2:decoder creation
|
||||
* @code
|
||||
* CreateDecoder(pSvcDecoder);
|
||||
* @endcode
|
||||
*
|
||||
* Step 3:declare required parameter, used to differentiate Decoding only and Parsing only
|
||||
* @code
|
||||
* SDecodingParam sDecParam = {0};
|
||||
* sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC;
|
||||
* //for Parsing only, the assignment is mandatory
|
||||
* sDecParam.bParseOnly = true;
|
||||
* @endcode
|
||||
*
|
||||
* Step 4:initialize the parameter and decoder context, allocate memory
|
||||
* @code
|
||||
* Initialize(&sDecParam);
|
||||
* @endcode
|
||||
*
|
||||
* Step 5:do actual decoding process in slice level;
|
||||
* this can be done in a loop until data ends
|
||||
* @code
|
||||
* //for Decoding only
|
||||
* iRet = DecodeFrame2(pBuf, iSize, pData, &sDstBufInfo);
|
||||
* //for Parsing only
|
||||
* iRet = DecodeParser(pBuf, iSize, &sDstParseInfo);
|
||||
* //decode failed
|
||||
* If (iRet != 0){
|
||||
* RequestIDR or something like that.
|
||||
* }
|
||||
* //for Decoding only, pData can be used for render.
|
||||
* if (sDstBufInfo.iBufferStatus==1){
|
||||
* output pData[0], pData[1], pData[2];
|
||||
* }
|
||||
* //for Parsing only, sDstParseInfo can be used for, e.g., HW decoding
|
||||
* if (sDstBufInfo.iBufferStatus==1){
|
||||
* Hardware decoding sDstParseInfo;
|
||||
* }
|
||||
* //no-delay decoding can be realized by directly calling decoder again with NULL input, as in the following. In this case, decoder would immediately reconstruct the input data. This can also be used similarly for Parsing only. Consequent decoding error and output indication should also be considered as above.
|
||||
* iRet = DecodeFrame2(NULL, 0, pData, &sDstBufInfo);
|
||||
* judge iRet, sDstBufInfo.iBufferStatus ...
|
||||
* @endcode
|
||||
*
|
||||
* Step 6:uninitialize the decoder and memory free
|
||||
* @code
|
||||
* Uninitialize();
|
||||
* @endcode
|
||||
*
|
||||
* Step 7:destroy the decoder
|
||||
* @code
|
||||
* DestroyDecoder();
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page EncoderUsageExample1
|
||||
*
|
||||
* @brief
|
||||
* * An example for using encoder with basic parameter
|
||||
*
|
||||
* Step1:setup encoder
|
||||
* @code
|
||||
* int rv = WelsCreateSVCEncoder (&encoder_);
|
||||
* ASSERT_EQ (0, rv);
|
||||
* ASSERT_TRUE (encoder_ != NULL);
|
||||
* @endcode
|
||||
*
|
||||
* Step2:initilize with basic parameter
|
||||
* @code
|
||||
* SEncParamBase param;
|
||||
* memset (¶m, 0, sizeof (SEncParamBase));
|
||||
* param.iUsageType = usageType;
|
||||
* param.fMaxFrameRate = frameRate;
|
||||
* param.iPicWidth = width;
|
||||
* param.iPicHeight = height;
|
||||
* param.iTargetBitrate = 5000000;
|
||||
* encoder_->Initialize (¶m);
|
||||
* @endcode
|
||||
*
|
||||
* Step3:set option, set option during encoding process
|
||||
* @code
|
||||
* encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting);
|
||||
* int videoFormat = videoFormatI420;
|
||||
* encoder_->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat);
|
||||
* @endcode
|
||||
*
|
||||
* Step4: encode and store ouput bistream
|
||||
* @code
|
||||
* int frameSize = width * height * 3 / 2;
|
||||
* BufferedData buf;
|
||||
* buf.SetLength (frameSize);
|
||||
* ASSERT_TRUE (buf.Length() == (size_t)frameSize);
|
||||
* SFrameBSInfo info;
|
||||
* memset (&info, 0, sizeof (SFrameBSInfo));
|
||||
* SSourcePicture pic;
|
||||
* memset (&pic, 0, sizeof (SsourcePicture));
|
||||
* pic.iPicWidth = width;
|
||||
* pic.iPicHeight = height;
|
||||
* pic.iColorFormat = videoFormatI420;
|
||||
* pic.iStride[0] = pic.iPicWidth;
|
||||
* pic.iStride[1] = pic.iStride[2] = pic.iPicWidth >> 1;
|
||||
* pic.pData[0] = buf.data();
|
||||
* pic.pData[1] = pic.pData[0] + width * height;
|
||||
* pic.pData[2] = pic.pData[1] + (width * height >> 2);
|
||||
* for(int num = 0;num<total_num;num++) {
|
||||
* //prepare input data
|
||||
* rv = encoder_->EncodeFrame (&pic, &info);
|
||||
* ASSERT_TRUE (rv == cmResultSuccess);
|
||||
* if (info.eFrameType != videoFrameTypeSkip && cbk != NULL) {
|
||||
* //output bitstream
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Step5:teardown encoder
|
||||
* @code
|
||||
* if (encoder_) {
|
||||
* encoder_->Uninitialize();
|
||||
* WelsDestroySVCEncoder (encoder_);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page EncoderUsageExample2
|
||||
*
|
||||
* @brief
|
||||
* * An example for using the encoder with extension parameter.
|
||||
* * The same operation on Step 1,3,4,5 with Example-1
|
||||
*
|
||||
* Step 2:initialize with extension parameter
|
||||
* @code
|
||||
* SEncParamExt param;
|
||||
* encoder->GetDefaultParams (¶m);
|
||||
* param.iUsageType = usageType;
|
||||
* param.fMaxFrameRate = frameRate;
|
||||
* param.iPicWidth = width;
|
||||
* param.iPicHeight = height;
|
||||
* param.iTargetBitrate = 5000000;
|
||||
* param.bEnableDenoise = denoise;
|
||||
* param.iSpatialLayerNum = layers;
|
||||
* //SM_DYN_SLICE don't support multi-thread now
|
||||
* if (sliceMode != SM_SINGLE_SLICE && sliceMode != SM_DYN_SLICE)
|
||||
* param.iMultipleThreadIdc = 2;
|
||||
*
|
||||
* for (int i = 0; i < param.iSpatialLayerNum; i++) {
|
||||
* param.sSpatialLayers[i].iVideoWidth = width >> (param.iSpatialLayerNum - 1 - i);
|
||||
* param.sSpatialLayers[i].iVideoHeight = height >> (param.iSpatialLayerNum - 1 - i);
|
||||
* param.sSpatialLayers[i].fFrameRate = frameRate;
|
||||
* param.sSpatialLayers[i].iSpatialBitrate = param.iTargetBitrate;
|
||||
*
|
||||
* param.sSpatialLayers[i].sSliceCfg.uiSliceMode = sliceMode;
|
||||
* if (sliceMode == SM_DYN_SLICE) {
|
||||
* param.sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 600;
|
||||
* param.uiMaxNalSize = 1500;
|
||||
* }
|
||||
* }
|
||||
* param.iTargetBitrate *= param.iSpatialLayerNum;
|
||||
* encoder_->InitializeExt (¶m);
|
||||
* int videoFormat = videoFormatI420;
|
||||
* encoder_->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat);
|
||||
*
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
* @brief Endocder definition
|
||||
*/
|
||||
class ISVCEncoder {
|
||||
public:
|
||||
/*
|
||||
* return: CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
/**
|
||||
* @brief Initialize the encoder
|
||||
* @param pParam basic encoder parameter
|
||||
* @return CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual int EXTAPI Initialize (const SEncParamBase* pParam) = 0;
|
||||
|
||||
/**
|
||||
* @brief Initilaize encoder by using extension parameters.
|
||||
* @param pParam extension parameter for encoder
|
||||
* @return CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual int EXTAPI InitializeExt (const SEncParamExt* pParam) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the default extension parameters.
|
||||
* If you want to change some parameters of encoder, firstly you need to get the default encoding parameters,
|
||||
* after that you can change part of parameters you want to.
|
||||
* @param pParam extension parameter for encoder
|
||||
* @return CM_RETURN: 0 - success; otherwise - failed;
|
||||
* */
|
||||
virtual int EXTAPI GetDefaultParams (SEncParamExt* pParam) = 0;
|
||||
|
||||
/// uninitialize the encoder
|
||||
virtual int EXTAPI Uninitialize() = 0;
|
||||
|
||||
/*
|
||||
* return: 0 - success; otherwise -failed;
|
||||
*/
|
||||
/**
|
||||
* @brief Encode one frame
|
||||
* @param kpSrcPic the pointer to the source luminance plane
|
||||
* chrominance data:
|
||||
* CbData = kpSrc + m_iMaxPicWidth * m_iMaxPicHeight;
|
||||
* CrData = CbData + (m_iMaxPicWidth * m_iMaxPicHeight)/4;
|
||||
* the application calling this interface needs to ensure the data validation between the location
|
||||
* @param pBsInfo output bit stream
|
||||
* @return 0 - success; otherwise -failed;
|
||||
*/
|
||||
virtual int EXTAPI EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSInfo* pBsInfo) = 0;
|
||||
/*
|
||||
* return: 0 - success; otherwise - failed;
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Encode the parameters from output bit stream
|
||||
* @param pBsInfo output bit stream
|
||||
* @return 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual int EXTAPI EncodeParameterSets (SFrameBSInfo* pBsInfo) = 0;
|
||||
/*
|
||||
* return: 0 - success; otherwise - failed;
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Force encoder to encoder frame as IDR if bIDR set as true
|
||||
* @param bIDR true: force encoder to encode frame as IDR frame;false, return 1 and nothing to do
|
||||
* @return 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual int EXTAPI ForceIntraFrame (bool bIDR) = 0;
|
||||
|
||||
/************************************************************************
|
||||
* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
|
||||
************************************************************************/
|
||||
/*
|
||||
* return: CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
/**
|
||||
* @brief Set option for encoder, detail option type, please refer to enumurate ENCODER_OPTION.
|
||||
* @param pOption option for encoder such as InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,...
|
||||
* @return CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual int EXTAPI SetOption (ENCODER_OPTION eOptionId, void* pOption) = 0;
|
||||
|
||||
/**
|
||||
* @brief Set option for encoder, detail option type, please refer to enumurate ENCODER_OPTION.
|
||||
* @param pOption option for encoder such as InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,...
|
||||
* @return CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual int EXTAPI GetOption (ENCODER_OPTION eOptionId, void* pOption) = 0;
|
||||
virtual ~ISVCEncoder() {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Decoder definition
|
||||
*/
|
||||
class ISVCDecoder {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Initilaize decoder
|
||||
* @param pParam parameter for decoder
|
||||
* @return 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual long EXTAPI Initialize (const SDecodingParam* pParam) = 0;
|
||||
|
||||
/// Uninitialize the decoder
|
||||
virtual long EXTAPI Uninitialize() = 0;
|
||||
|
||||
/**
|
||||
* @brief Decode one frame
|
||||
* @param pSrc the h264 stream to be decoded
|
||||
* @param iSrcLen the length of h264 stream
|
||||
* @param ppDst buffer pointer of decoded data (YUV)
|
||||
* @param pStride output stride
|
||||
* @param iWidth output width
|
||||
* @param iHeight output height
|
||||
* @return 0 - success; otherwise -failed;
|
||||
*/
|
||||
virtual DECODING_STATE EXTAPI DecodeFrame (const unsigned char* pSrc,
|
||||
const int iSrcLen,
|
||||
unsigned char** ppDst,
|
||||
int* pStride,
|
||||
int& iWidth,
|
||||
int& iHeight) = 0;
|
||||
/*
|
||||
* return: 0 - success; otherwise -failed;
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief For slice level DecodeFrame2() (4 parameters input),
|
||||
* whatever the function return value is, the output data
|
||||
* of I420 format will only be available when pDstInfo->iBufferStatus == 1,.
|
||||
* (e.g., in multi-slice cases, only when the whole picture
|
||||
* is completely reconstructed, this variable would be set equal to 1.)
|
||||
* @param pSrc the h264 stream to be decoded
|
||||
* @param iSrcLen the length of h264 stream
|
||||
* @param ppDst buffer pointer of decoded data (YUV)
|
||||
* @param pDstInfo information provided to API(width, height, etc.)
|
||||
* @return 0 - success; otherwise -failed;
|
||||
*/
|
||||
virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* pSrc,
|
||||
const int iSrcLen,
|
||||
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;
|
||||
*/
|
||||
/**
|
||||
* @brief This function parse input bitstream only, and rewrite possible SVC syntax to AVC syntax
|
||||
* @param pSrc the h264 stream to be decoded
|
||||
* @param iSrcLen the length of h264 stream
|
||||
* @param pDstInfo bit stream info
|
||||
* @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.
|
||||
*/
|
||||
/**
|
||||
* @brief This API does not work for now!! This is for future use to support non-I420 color format output.
|
||||
* @param pSrc the h264 stream to be decoded
|
||||
* @param iSrcLen the length of h264 stream
|
||||
* @param pDst buffer pointer of decoded data (YUV)
|
||||
* @param iDstStride output stride
|
||||
* @param iDstLen bit stream info
|
||||
* @param iWidth output width
|
||||
* @param iHeight output height
|
||||
* @param iColorFormat output color format
|
||||
* @return to do ...
|
||||
*/
|
||||
virtual DECODING_STATE EXTAPI DecodeFrameEx (const unsigned char* pSrc,
|
||||
const int iSrcLen,
|
||||
unsigned char* pDst,
|
||||
@@ -126,10 +418,18 @@ class ISVCDecoder {
|
||||
int& iHeight,
|
||||
int& iColorFormat) = 0;
|
||||
|
||||
/*************************************************************************
|
||||
* OutDataFormat, Eos Flag, EC method, ...
|
||||
*************************************************************************/
|
||||
/**
|
||||
* @brief Set option for decoder, detail option type, please refer to enumurate DECODER_OPTION.
|
||||
* @param pOption option for decoder such as OutDataFormat, Eos Flag, EC method, ...
|
||||
* @return CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual long EXTAPI SetOption (DECODER_OPTION eOptionId, void* pOption) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get option for decoder, detail option type, please refer to enumurate DECODER_OPTION.
|
||||
* @param pOption option for decoder such as OutDataFormat, Eos Flag, EC method, ...
|
||||
* @return CM_RETURN: 0 - success; otherwise - failed;
|
||||
*/
|
||||
virtual long EXTAPI GetOption (DECODER_OPTION eOptionId, void* pOption) = 0;
|
||||
virtual ~ISVCDecoder() {}
|
||||
};
|
||||
@@ -197,13 +497,45 @@ long (*GetOption) (ISVCDecoder*, DECODER_OPTION eOptionId, void* pOption);
|
||||
|
||||
typedef void (*WelsTraceCallback) (void* ctx, int level, const char* string);
|
||||
|
||||
/** @brief Create encoder
|
||||
* @param ppEncoder encoder
|
||||
* @return 0 - success; otherwise - failed;
|
||||
*/
|
||||
int WelsCreateSVCEncoder (ISVCEncoder** ppEncoder);
|
||||
|
||||
|
||||
/** @brief Destroy encoder
|
||||
* @param pEncoder encoder
|
||||
* @return void
|
||||
*/
|
||||
void WelsDestroySVCEncoder (ISVCEncoder* pEncoder);
|
||||
|
||||
|
||||
/** @brief Get the capability of decoder
|
||||
* @param pDecCapability decoder capability
|
||||
* @return 0 - success; otherwise - failed;
|
||||
*/
|
||||
int WelsGetDecoderCapability (SDecoderCapability* pDecCapability);
|
||||
|
||||
|
||||
/** @brief Create decoder
|
||||
* @param ppDecoder decoder
|
||||
* @return 0 - success; otherwise - failed;
|
||||
*/
|
||||
long WelsCreateDecoder (ISVCDecoder** ppDecoder);
|
||||
|
||||
|
||||
/** @brief Destroy decoder
|
||||
* @param pDecoder decoder
|
||||
* @return void
|
||||
*/
|
||||
void WelsDestroyDecoder (ISVCDecoder* pDecoder);
|
||||
|
||||
/** @brief Get codec version
|
||||
* @return The linked codec version
|
||||
*/
|
||||
OpenH264Version WelsGetCodecVersion ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -30,9 +30,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
|
||||
#define WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
|
||||
////////////////Data and /or structures introduced in Cisco OpenH264 application////////////////
|
||||
/**
|
||||
* @file codec_app_def.h
|
||||
* @brief Data and /or structures introduced in Cisco OpenH264 application
|
||||
*/
|
||||
|
||||
#include "codec_def.h"
|
||||
/* Constants */
|
||||
#define MAX_TEMPORAL_LAYER_NUM 4
|
||||
@@ -40,114 +46,158 @@
|
||||
#define MAX_QUALITY_LAYER_NUM 4
|
||||
|
||||
#define MAX_LAYER_NUM_OF_FRAME 128
|
||||
#define MAX_NAL_UNITS_IN_LAYER 128 // predetermined here, adjust it later if need
|
||||
#define MAX_NAL_UNITS_IN_LAYER 128 ///< predetermined here, adjust it later if need
|
||||
|
||||
#define MAX_RTP_PAYLOAD_LEN 1000
|
||||
#define AVERAGE_RTP_PAYLOAD_LEN 800
|
||||
|
||||
|
||||
#define SAVED_NALUNIT_NUM_TMP ( (MAX_SPATIAL_LAYER_NUM*MAX_QUALITY_LAYER_NUM) + 1 + MAX_SPATIAL_LAYER_NUM ) //SPS/PPS + SEI/SSEI + PADDING_NAL
|
||||
#define SAVED_NALUNIT_NUM_TMP ( (MAX_SPATIAL_LAYER_NUM*MAX_QUALITY_LAYER_NUM) + 1 + MAX_SPATIAL_LAYER_NUM ) ///< SPS/PPS + SEI/SSEI + PADDING_NAL
|
||||
#define MAX_SLICES_NUM_TMP ( ( MAX_NAL_UNITS_IN_LAYER - SAVED_NALUNIT_NUM_TMP ) / 3 )
|
||||
|
||||
#define AUTO_REF_PIC_COUNT -1 // encoder selects the number of reference frame automatically
|
||||
typedef enum {
|
||||
/* Errors derived from bitstream parsing */
|
||||
dsErrorFree = 0x00, /* Bitstream error-free */
|
||||
dsFramePending = 0x01, /* Need more throughput to generate a frame output, */
|
||||
dsRefLost = 0x02, /* layer lost at reference frame with temporal id 0 */
|
||||
dsBitstreamError = 0x04, /* Error bitstreams(maybe broken internal frame) the decoder cared */
|
||||
dsDepLayerLost = 0x08, /* Dependented layer is ever lost */
|
||||
dsNoParamSets = 0x10, /* No parameter set NALs involved */
|
||||
dsDataErrorConcealed = 0x20, /* current data Error concealed specified */
|
||||
|
||||
/* Errors derived from logic level */
|
||||
dsInvalidArgument = 0x1000, /* Invalid argument specified */
|
||||
dsInitialOptExpected = 0x2000, /* Initializing operation is expected */
|
||||
dsOutOfMemory = 0x4000, /* Out of memory due to new request */
|
||||
/* ANY OTHERS? */
|
||||
dsDstBufNeedExpand = 0x8000 /* Actual picture size exceeds size of dst pBuffer feed in decoder, so need expand its size */
|
||||
#define AUTO_REF_PIC_COUNT -1 ///< encoder selects the number of reference frame automatically
|
||||
#define UNSPECIFIED_BIT_RATE 0 ///< to do: add detail comment
|
||||
|
||||
/**
|
||||
* @brief Struct of OpenH264 version
|
||||
*/
|
||||
///
|
||||
/// E.g. SDK version is 1.2.0.0, major version number is 1, minor version number is 2, and revision number is 0.
|
||||
typedef struct _tagVersion
|
||||
{
|
||||
unsigned int uMajor; ///< The major version number
|
||||
unsigned int uMinor; ///< The minor version number
|
||||
unsigned int uRevision; ///< The revision number
|
||||
unsigned int uReserved; ///< The reserved number, it should be 0.
|
||||
} OpenH264Version;
|
||||
|
||||
/**
|
||||
* @brief Decoding status
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* Errors derived from bitstream parsing
|
||||
*/
|
||||
dsErrorFree = 0x00, ///< bit stream error-free
|
||||
dsFramePending = 0x01, ///< need more throughput to generate a frame output,
|
||||
dsRefLost = 0x02, ///< layer lost at reference frame with temporal id 0
|
||||
dsBitstreamError = 0x04, ///< error bitstreams(maybe broken internal frame) the decoder cared
|
||||
dsDepLayerLost = 0x08, ///< dependented layer is ever lost
|
||||
dsNoParamSets = 0x10, ///< no parameter set NALs involved
|
||||
dsDataErrorConcealed = 0x20, ///< current data error concealed specified
|
||||
|
||||
/**
|
||||
* Errors derived from logic level
|
||||
*/
|
||||
dsInvalidArgument = 0x1000, ///< invalid argument specified
|
||||
dsInitialOptExpected = 0x2000, ///< initializing operation is expected
|
||||
dsOutOfMemory = 0x4000, ///< out of memory due to new request
|
||||
/**
|
||||
* ANY OTHERS?
|
||||
*/
|
||||
dsDstBufNeedExpan = 0x8000 ///< actual picture size exceeds size of dst pBuffer feed in decoder, so need expand its size
|
||||
|
||||
} DECODING_STATE;
|
||||
|
||||
/* Option types introduced in SVC encoder application */
|
||||
/**
|
||||
* @brief Option types introduced in SVC encoder application
|
||||
*/
|
||||
typedef enum {
|
||||
ENCODER_OPTION_DATAFORMAT = 0,
|
||||
ENCODER_OPTION_IDR_INTERVAL,
|
||||
ENCODER_OPTION_SVC_ENCODE_PARAM_BASE,
|
||||
ENCODER_OPTION_SVC_ENCODE_PARAM_EXT,
|
||||
ENCODER_OPTION_FRAME_RATE,
|
||||
ENCODER_OPTION_IDR_INTERVAL, ///< IDR period,0/-1 means no Intra period (only the first frame); lager than 0 means the desired IDR period, must be multiple of (2^temporal_layer)
|
||||
ENCODER_OPTION_SVC_ENCODE_PARAM_BASE, ///< structure of Base Param
|
||||
ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, ///< structure of Extension Param
|
||||
ENCODER_OPTION_FRAME_RATE, ///< maximal input frame rate, current supported range: MAX_FRAME_RATE = 30,MIN_FRAME_RATE = 1
|
||||
ENCODER_OPTION_BITRATE,
|
||||
ENCODER_OPTION_MAX_BITRATE,
|
||||
ENCODER_OPTION_INTER_SPATIAL_PRED,
|
||||
ENCODER_OPTION_RC_MODE,
|
||||
ENCODER_PADDING_PADDING,
|
||||
ENCODER_PADDING_PADDING, ///< 0:disable padding;1:padding
|
||||
|
||||
ENCODER_OPTION_PROFILE,
|
||||
ENCODER_OPTION_LEVEL,
|
||||
ENCODER_OPTION_NUMBER_REF,
|
||||
ENCODER_OPTION_DELIVERY_STATUS,
|
||||
ENCODER_OPTION_PROFILE, ///< assgin the profile for each layer
|
||||
ENCODER_OPTION_LEVEL, ///< assgin the level for each layer
|
||||
ENCODER_OPTION_NUMBER_REF, ///< the number of refererence frame
|
||||
ENCODER_OPTION_DELIVERY_STATUS, ///< the delivery info which is a feedback from app level
|
||||
|
||||
ENCODER_LTR_RECOVERY_REQUEST,
|
||||
ENCODER_LTR_MARKING_FEEDBACK,
|
||||
ENCODER_LTR_MARKING_PERIOD,
|
||||
ENCODER_OPTION_LTR,
|
||||
ENCODER_OPTION_LTR, ///< 0:disable LTR;larger than 0 enable LTR; LTR number is fixed to be 2 in current encoder
|
||||
ENCODER_OPTION_COMPLEXITY,
|
||||
|
||||
ENCODER_OPTION_ENABLE_SSEI, //enable SSEI: true--enable ssei; false--disable ssei
|
||||
ENCODER_OPTION_ENABLE_PREFIX_NAL_ADDING, //enable prefix: true--enable prefix; false--disable prefix
|
||||
ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, //enable pSps/pPps id addition: true--enable pSps/pPps id; false--disable pSps/pPps id addistion
|
||||
ENCODER_OPTION_ENABLE_SSEI, ///< enable SSEI: true--enable ssei; false--disable ssei
|
||||
ENCODER_OPTION_ENABLE_PREFIX_NAL_ADDING, ///< enable prefix: true--enable prefix; false--disable prefix
|
||||
ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, ///< enable pSps/pPps id addition: true--enable pSps/pPps id; false--disable pSps/pPps id addistion
|
||||
|
||||
ENCODER_OPTION_CURRENT_PATH,
|
||||
ENCODER_OPTION_DUMP_FILE,
|
||||
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_DUMP_FILE, ///< dump layer reconstruct frame to a specified file
|
||||
ENCODER_OPTION_TRACE_LEVEL, ///< trace info based on the 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, ///< context info of trace callback
|
||||
|
||||
ENCODER_OPTION_GET_STATISTICS, //read only
|
||||
ENCODER_OPTION_STATISTICS_LOG_INTERVAL, // log interval in milliseconds
|
||||
ENCODER_OPTION_GET_STATISTICS, ///< read only
|
||||
ENCODER_OPTION_STATISTICS_LOG_INTERVAL, ///< log interval in millisecond
|
||||
|
||||
// advanced algorithmetic settings
|
||||
ENCODER_OPTION_IS_LOSSLESS_LINK
|
||||
ENCODER_OPTION_IS_LOSSLESS_LINK, ///< advanced algorithmetic settings
|
||||
|
||||
ENCODER_OPTION_BITS_VARY_PERCENTAGE ///< bit vary percentage
|
||||
} ENCODER_OPTION;
|
||||
|
||||
/* Option types introduced in decoder application */
|
||||
/**
|
||||
* @brief Option types introduced in decoder application
|
||||
*/
|
||||
typedef enum {
|
||||
DECODER_OPTION_DATAFORMAT = 0, /* Set color space of decoding output frame */
|
||||
DECODER_OPTION_END_OF_STREAM, /* Indicate bitstream of the final frame to be decoded */
|
||||
DECODER_OPTION_VCL_NAL, //feedback whether or not have VCL NAL in current AU for application layer
|
||||
DECODER_OPTION_TEMPORAL_ID, //feedback temporal id for application layer
|
||||
DECODER_OPTION_FRAME_NUM, //feedback current decoded frame number
|
||||
DECODER_OPTION_IDR_PIC_ID, // feedback current frame belong to which IDR period
|
||||
DECODER_OPTION_LTR_MARKING_FLAG, // feedback wether current frame mark a LTR
|
||||
DECODER_OPTION_LTR_MARKED_FRAME_NUM, // feedback frame num marked by current Frame
|
||||
DECODER_OPTION_ERROR_CON_IDC, //not finished yet, indicate decoder error concealment status, in progress
|
||||
DECODER_OPTION_DATAFORMAT = 0, ///< color format, now supports 23 only (I420)
|
||||
DECODER_OPTION_END_OF_STREAM, ///< end of stream flag
|
||||
DECODER_OPTION_VCL_NAL, ///< feedback whether or not have VCL NAL in current AU for application layer
|
||||
DECODER_OPTION_TEMPORAL_ID, ///< feedback temporal id for application layer
|
||||
DECODER_OPTION_FRAME_NUM, ///< feedback current decoded frame number
|
||||
DECODER_OPTION_IDR_PIC_ID, ///< feedback current frame belong to which IDR period
|
||||
DECODER_OPTION_LTR_MARKING_FLAG, ///< feedback wether current frame mark a LTR
|
||||
DECODER_OPTION_LTR_MARKED_FRAME_NUM, ///< feedback frame num marked by current Frame
|
||||
DECODER_OPTION_ERROR_CON_IDC, ///< not finished yet, indicate decoder error concealment status, in progress
|
||||
DECODER_OPTION_TRACE_LEVEL,
|
||||
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_TRACE_CALLBACK, ///< a void (*)(void* context, int level, const char* message) function which receives log messages
|
||||
DECODER_OPTION_TRACE_CALLBACK_CONTEXT,///< context info of trace callbac
|
||||
|
||||
DECODER_OPTION_GET_STATISTICS
|
||||
|
||||
} DECODER_OPTION;
|
||||
|
||||
//enuerate the types of error concealment methods
|
||||
/**
|
||||
* @brief Enumerate the type of error concealment methods
|
||||
*/
|
||||
typedef enum {
|
||||
ERROR_CON_DISABLE = 0,
|
||||
ERROR_CON_FRAME_COPY,
|
||||
ERROR_CON_SLICE_COPY
|
||||
ERROR_CON_SLICE_COPY,
|
||||
ERROR_CON_FRAME_COPY_CROSS_IDR,
|
||||
ERROR_CON_SLICE_COPY_CROSS_IDR,
|
||||
ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE,
|
||||
ERROR_CON_SLICE_MV_COPY_CROSS_IDR,
|
||||
ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE
|
||||
} ERROR_CON_IDC;
|
||||
|
||||
typedef enum { //feedback that whether or not have VCL NAL in current AU
|
||||
/**
|
||||
* @brief Feedback that whether or not have VCL NAL in current AU
|
||||
*/
|
||||
typedef enum {
|
||||
FEEDBACK_NON_VCL_NAL = 0,
|
||||
FEEDBACK_VCL_NAL,
|
||||
FEEDBACK_UNKNOWN_NAL
|
||||
} FEEDBACK_VCL_NAL_IN_AU;
|
||||
|
||||
/* Type of layer being encoded */
|
||||
/**
|
||||
* @brief Type of layer being encoded
|
||||
*/
|
||||
typedef enum {
|
||||
NON_VIDEO_CODING_LAYER = 0,
|
||||
VIDEO_CODING_LAYER = 1
|
||||
} LAYER_TYPE;
|
||||
|
||||
/**
|
||||
* @brief Spatial layer num
|
||||
*/
|
||||
typedef enum {
|
||||
SPATIAL_LAYER_0 = 0,
|
||||
SPATIAL_LAYER_1 = 1,
|
||||
@@ -156,13 +206,18 @@ typedef enum {
|
||||
SPATIAL_LAYER_ALL = 4
|
||||
} LAYER_NUM;
|
||||
|
||||
//enumerate the type of video bitstream which is provided to decoder
|
||||
/**
|
||||
* @brief 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_TYPE;
|
||||
|
||||
/**
|
||||
* @brief Enumerate the type of key frame request
|
||||
*/
|
||||
typedef enum {
|
||||
NO_RECOVERY_REQUSET = 0,
|
||||
LTR_RECOVERY_REQUEST = 1,
|
||||
@@ -172,62 +227,87 @@ typedef enum {
|
||||
LTR_MARKING_FAILED = 5
|
||||
} KEY_FRAME_REQUEST_TYPE;
|
||||
|
||||
/**
|
||||
* @brief Structure for LTR recover request
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int uiFeedbackType; //IDR request or LTR recovery request
|
||||
unsigned int uiIDRPicId; // distinguish request from different IDR
|
||||
int iLastCorrectFrameNum;
|
||||
int iCurrentFrameNum; //specify current decoder frame_num.
|
||||
unsigned int uiFeedbackType; ///< IDR request or LTR recovery request
|
||||
unsigned int uiIDRPicId; ///< distinguish request from different IDR
|
||||
int iLastCorrectFrameNum;
|
||||
int iCurrentFrameNum; ///< specify current decoder frame_num.
|
||||
} SLTRRecoverRequest;
|
||||
|
||||
/**
|
||||
* @brief Structure for LTR marking feedback
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int uiFeedbackType; //mark failed or successful
|
||||
unsigned int uiIDRPicId; // distinguish request from different IDR
|
||||
int iLTRFrameNum; //specify current decoder frame_num
|
||||
unsigned int uiFeedbackType; ///< mark failed or successful
|
||||
unsigned int uiIDRPicId; ///< distinguish request from different IDR
|
||||
int iLTRFrameNum; ///< specify current decoder frame_num
|
||||
} SLTRMarkingFeedback;
|
||||
|
||||
/**
|
||||
* @brief Structure for LTR configuration
|
||||
*/
|
||||
typedef struct {
|
||||
bool bEnableLongTermReference; // 1: on, 0: off
|
||||
int iLTRRefNum; //TODO: not supported to set it arbitrary yet
|
||||
bool bEnableLongTermReference; ///< 1: on, 0: off
|
||||
int iLTRRefNum; ///< TODO: not supported to set it arbitrary yet
|
||||
} SLTRConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure for slice argument
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int
|
||||
uiSliceMbNum[MAX_SLICES_NUM_TMP]; //here we use a tmp fixed value since MAX_SLICES_NUM is not defined here and its definition may be changed;
|
||||
unsigned int uiSliceNum;
|
||||
unsigned int uiSliceSizeConstraint;
|
||||
} SSliceArgument;//not all the elements in this argument will be used, how it will be used depends on uiSliceMode; see below
|
||||
uiSliceMbNum[MAX_SLICES_NUM_TMP]; ///< only used when uiSliceMode=2;here we use a tmp fixed value since MAX_SLICES_NUM is not defined here and its definition may be changed;
|
||||
unsigned int uiSliceNum; ///< only used when uiSliceMode=1
|
||||
unsigned int uiSliceSizeConstraint; ///< only used when uiSliceMode=4
|
||||
} SSliceArgument; ///< not all the elements in this argument will be used, how it will be used depends on uiSliceMode; please refer to SliceModeEnum
|
||||
|
||||
/**
|
||||
* @brief Enumerate the type of slice mode
|
||||
*/
|
||||
typedef enum {
|
||||
SM_SINGLE_SLICE = 0, // | SliceNum==1
|
||||
SM_FIXEDSLCNUM_SLICE = 1, // | according to SliceNum | Enabled dynamic slicing for multi-thread
|
||||
SM_RASTER_SLICE = 2, // | according to SlicesAssign | Need input of MB numbers each slice. In addition, if other constraint in SSliceArgument is presented, need to follow the constraints. Typically if MB num and slice size are both constrained, re-encoding may be involved.
|
||||
SM_ROWMB_SLICE = 3, // | according to PictureMBHeight | Typical of single row of mbs each slice?+ slice size constraint which including re-encoding
|
||||
SM_DYN_SLICE = 4, // | according to SliceSize | Dynamic slicing (have no idea about slice_nums until encoding current frame)
|
||||
SM_AUTO_SLICE = 5, // | according to thread number
|
||||
SM_SINGLE_SLICE = 0, ///< | SliceNum==1
|
||||
SM_FIXEDSLCNUM_SLICE = 1, ///< | according to SliceNum | enabled dynamic slicing for multi-thread
|
||||
SM_RASTER_SLICE = 2, ///< | according to SlicesAssign | need input of MB numbers each slice. In addition, if other constraint in SSliceArgument is presented, need to follow the constraints. Typically if MB num and slice size are both constrained, re-encoding may be involved.
|
||||
SM_ROWMB_SLICE = 3, ///< | according to PictureMBHeight | typical of single row of mbs each slice + slice size constraint which including re-encoding
|
||||
SM_DYN_SLICE = 4, ///< | according to SliceSize | dynamic slicing (have no idea about slice_nums until encoding current frame)
|
||||
SM_AUTO_SLICE = 5, ///< | according to thread number
|
||||
SM_RESERVED = 6
|
||||
} SliceModeEnum;
|
||||
|
||||
/**
|
||||
* @brief Enumerate the type of rate control mode
|
||||
*/
|
||||
typedef enum {
|
||||
RC_QUALITY_MODE = 0, //Quality mode
|
||||
RC_BITRATE_MODE = 1, //Bitrate 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_QUALITY_MODE = 0, ///< quality mode
|
||||
RC_BITRATE_MODE = 1, ///< bitrate 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;
|
||||
|
||||
/**
|
||||
* @brief Enumerate the type of profile id
|
||||
*/
|
||||
typedef enum {
|
||||
PRO_UNKNOWN = 0,
|
||||
PRO_UNKNOWN = 0,
|
||||
PRO_BASELINE = 66,
|
||||
PRO_MAIN = 77,
|
||||
PRO_EXTENDED = 88,
|
||||
PRO_HIGH = 100,
|
||||
PRO_HIGH10 = 110,
|
||||
PRO_HIGH422 = 122,
|
||||
PRO_HIGH444 = 144,
|
||||
PRO_HIGH10 = 110,
|
||||
PRO_HIGH422 = 122,
|
||||
PRO_HIGH444 = 144,
|
||||
PRO_CAVLC444 = 244,
|
||||
|
||||
PRO_SCALABLE_BASELINE = 83,
|
||||
PRO_SCALABLE_HIGH = 86
|
||||
} EProfileIdc;
|
||||
|
||||
/**
|
||||
* @brief Enumerate the type of level id
|
||||
*/
|
||||
typedef enum {
|
||||
LEVEL_UNKNOWN,
|
||||
LEVEL_1_0,
|
||||
@@ -249,136 +329,159 @@ typedef enum {
|
||||
LEVEL_5_2
|
||||
} ELevelIdc;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enumerate the type of wels log
|
||||
*/
|
||||
enum {
|
||||
WELS_LOG_QUIET = 0x00, // Quiet mode
|
||||
WELS_LOG_ERROR = 1 << 0, // Error log iLevel
|
||||
WELS_LOG_WARNING = 1 << 1, // Warning log iLevel
|
||||
WELS_LOG_INFO = 1 << 2, // Information log iLevel
|
||||
WELS_LOG_DEBUG = 1 << 3, // Debug log, critical algo log
|
||||
WELS_LOG_DETAIL = 1 << 4, // per packet/frame log
|
||||
WELS_LOG_RESV = 1 << 5, // Resversed log iLevel
|
||||
WELS_LOG_QUIET = 0x00, ///< quiet mode
|
||||
WELS_LOG_ERROR = 1 << 0, ///< error log iLevel
|
||||
WELS_LOG_WARNING = 1 << 1, ///< Warning log iLevel
|
||||
WELS_LOG_INFO = 1 << 2, ///< information log iLevel
|
||||
WELS_LOG_DEBUG = 1 << 3, ///< debug log, critical algo log
|
||||
WELS_LOG_DETAIL = 1 << 4, ///< per packet/frame log
|
||||
WELS_LOG_RESV = 1 << 5, ///< resversed log iLevel
|
||||
WELS_LOG_LEVEL_COUNT = 6,
|
||||
WELS_LOG_DEFAULT = WELS_LOG_DEBUG // Default log iLevel in Wels codec
|
||||
WELS_LOG_DEFAULT = WELS_LOG_WARNING ///< default log iLevel in Wels codec
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Structure for slice configuration
|
||||
*/
|
||||
typedef struct {
|
||||
SliceModeEnum uiSliceMode; //by default, uiSliceMode will be SM_SINGLE_SLICE
|
||||
SliceModeEnum uiSliceMode; ///< by default, uiSliceMode will be SM_SINGLE_SLICE
|
||||
SSliceArgument sSliceArgument;
|
||||
} SSliceConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure for spatial layer configuration
|
||||
*/
|
||||
typedef struct {
|
||||
int iVideoWidth; // video size in cx specified for a layer
|
||||
int iVideoHeight; // video size in cy specified for a layer
|
||||
float fFrameRate; // frame rate specified for a layer
|
||||
int iSpatialBitrate; // target bitrate for a spatial layer
|
||||
int iMaxSpatialBitrate;
|
||||
EProfileIdc uiProfileIdc; // value of profile IDC (PRO_UNKNOWN for auto-detection)
|
||||
ELevelIdc uiLevelIdc;
|
||||
int iDLayerQp;
|
||||
int iVideoWidth; ///< width of picture in luminance samples of a layer
|
||||
int iVideoHeight; ///< height of picture in luminance samples of a layer
|
||||
float fFrameRate; ///< frame rate specified for a layer
|
||||
int iSpatialBitrate; ///< target bitrate for a spatial layer
|
||||
int iMaxSpatialBitrate; ///< maximum bitrate for a spatial layer
|
||||
EProfileIdc uiProfileIdc; ///< value of profile IDC (PRO_UNKNOWN for auto-detection)
|
||||
ELevelIdc uiLevelIdc; ///< value of profile IDC (0 for auto-detection)
|
||||
int iDLayerQp; ///< value of level IDC (0 for auto-detection)
|
||||
|
||||
SSliceConfig sSliceCfg;
|
||||
SSliceConfig sSliceCfg; ///< slice configuration for a layer
|
||||
} SSpatialLayerConfig;
|
||||
|
||||
/**
|
||||
* @brief Encoder usage type
|
||||
*/
|
||||
typedef enum {
|
||||
CAMERA_VIDEO_REAL_TIME, //camera video signal
|
||||
SCREEN_CONTENT_REAL_TIME //screen content signal
|
||||
CAMERA_VIDEO_REAL_TIME, ///< camera video signal
|
||||
SCREEN_CONTENT_REAL_TIME ///< screen content signal
|
||||
} EUsageType;
|
||||
|
||||
/**
|
||||
* @brief Enumulate the complexity mode
|
||||
*/
|
||||
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
|
||||
LOW_COMPLEXITY, ///< the lowest compleixty,the fastest speed,
|
||||
MEDIUM_COMPLEXITY, ///< medium complexity, medium speed,medium quality
|
||||
HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality
|
||||
} ECOMPLEXITY_MODE;
|
||||
|
||||
// TODO: Refine the parameters definition.
|
||||
// SVC Encoding Parameters
|
||||
/**
|
||||
* @brief SVC Encoding Parameters
|
||||
*/
|
||||
typedef struct TagEncParamBase {
|
||||
EUsageType
|
||||
iUsageType; //application type;// CAMERA_VIDEO_REAL_TIME: //camera video signal; SCREEN_CONTENT_REAL_TIME: screen content signal;
|
||||
iUsageType; ///< application type;1.CAMERA_VIDEO_REAL_TIME:camera video signal; 2.SCREEN_CONTENT_REAL_TIME:screen content signal;
|
||||
|
||||
int iPicWidth; // width of picture in samples
|
||||
int iPicHeight; // height of picture in samples
|
||||
int iTargetBitrate; // target bitrate desired
|
||||
RC_MODES iRCMode; // RC mode
|
||||
float fMaxFrameRate; // input maximal frame rate
|
||||
int iPicWidth; ///< width of picture in luminance samples (the maximum of all layers if multiple spatial layers presents)
|
||||
int iPicHeight; ///< height of picture in luminance samples((the maximum of all layers if multiple spatial layers presents)
|
||||
int iTargetBitrate; ///< target bitrate desired
|
||||
RC_MODES iRCMode; ///< rate control mode
|
||||
float fMaxFrameRate; ///< maximal input frame rate
|
||||
|
||||
} SEncParamBase, *PEncParamBase;
|
||||
|
||||
|
||||
/**
|
||||
* @brief SVC Encoding Parameters extention
|
||||
*/
|
||||
typedef struct TagEncParamExt {
|
||||
EUsageType
|
||||
iUsageType; //application type;// CAMERA_VIDEO_REAL_TIME: //camera video signal; SCREEN_CONTENT_REAL_TIME: screen content signal;
|
||||
iUsageType; ///< application type;1.CAMERA_VIDEO_REAL_TIME:camera video signal;2.SCREEN_CONTENT_REAL_TIME:screen content signal;
|
||||
|
||||
int iPicWidth; // width of picture in samples
|
||||
int iPicHeight; // height of picture in samples
|
||||
int iTargetBitrate; // target bitrate desired
|
||||
RC_MODES iRCMode; // RC mode
|
||||
float fMaxFrameRate; // input maximal frame rate
|
||||
int iPicWidth; ///< width of picture in luminance samples (the maximum of all layers if multiple spatial layers presents)
|
||||
int iPicHeight; ///< height of picture in luminance samples((the maximum of all layers if multiple spatial layers presents)
|
||||
int iTargetBitrate; ///< target bitrate desired
|
||||
RC_MODES iRCMode; ///< rate control mode
|
||||
float fMaxFrameRate; ///< maximal input frame rate
|
||||
|
||||
int iTemporalLayerNum; // layer number at temporal level
|
||||
int iSpatialLayerNum; // layer number at spatial level
|
||||
int iTemporalLayerNum; ///< temporal layer number, max temporal layer = 4
|
||||
int iSpatialLayerNum; ///< spatial layer number,1<= iSpatialLayerNum <= MAX_SPATIAL_LAYER_NUM, MAX_SPATIAL_LAYER_NUM = 4
|
||||
SSpatialLayerConfig sSpatialLayers[MAX_SPATIAL_LAYER_NUM];
|
||||
|
||||
ECOMPLEXITY_MODE iComplexityMode;
|
||||
unsigned int uiIntraPeriod; // period of Intra frame
|
||||
int iNumRefFrame; // number of reference frame used
|
||||
bool bEnableSpsPpsIdAddition;
|
||||
bool bPrefixNalAddingCtrl;
|
||||
bool bEnableSSEI;
|
||||
int iPaddingFlag; // 0:disable padding;1:padding
|
||||
int iEntropyCodingModeFlag;
|
||||
unsigned int uiIntraPeriod; ///< period of Intra frame
|
||||
int iNumRefFrame; ///< number of reference frame used
|
||||
bool bEnableSpsPpsIdAddition; ///< false:not adjust ID in SPS/PPS; true: adjust ID in SPS/PPS
|
||||
bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL
|
||||
bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI
|
||||
int iPaddingFlag; ///< 0:disable padding;1:padding
|
||||
int iEntropyCodingModeFlag; ///< 0:CAVLC 1:CABAC.
|
||||
|
||||
/* rc control */
|
||||
bool bEnableFrameSkip; // allow skipping frames to keep the bitrate within limits
|
||||
int iMaxBitrate; // max bitrate desired
|
||||
int iMaxQp;
|
||||
int iMinQp;
|
||||
unsigned int uiMaxNalSize;
|
||||
bool bEnableFrameSkip; ///< False: don't skip frame even if VBV buffer overflow.True: allow skipping frames to keep the bitrate within limits
|
||||
int iMaxBitrate; ///< the maximum bitrate
|
||||
int iMaxQp; ///< the maximum QP encoder supports
|
||||
int iMinQp; ///< the minmum QP encoder supports
|
||||
unsigned int uiMaxNalSize; ///< the maximum NAL size. This value should be not 0 for dynamic slice mode
|
||||
|
||||
/*LTR settings*/
|
||||
bool bEnableLongTermReference; // 1: on, 0: off
|
||||
int iLTRRefNum; //TODO: not supported to set it arbitrary yet
|
||||
unsigned int iLtrMarkPeriod;
|
||||
|
||||
bool bEnableLongTermReference; ///< 1: on, 0: off
|
||||
int iLTRRefNum; ///< the number of LTR(long term reference),TODO: not supported to set it arbitrary yet
|
||||
unsigned int iLtrMarkPeriod; ///< the LTR marked period that is used in feedback.
|
||||
/* multi-thread settings*/
|
||||
unsigned short
|
||||
iMultipleThreadIdc; // 1 # 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; > 1: count number of threads;
|
||||
iMultipleThreadIdc; ///< 1 # 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; lager than 1: count number of threads;
|
||||
|
||||
/* Deblocking loop filter */
|
||||
int iLoopFilterDisableIdc; // 0: on, 1: off, 2: on except for slice boundaries
|
||||
int iLoopFilterAlphaC0Offset;// AlphaOffset: valid range [-6, 6], default 0
|
||||
int iLoopFilterBetaOffset; // BetaOffset: valid range [-6, 6], default 0
|
||||
int iLoopFilterDisableIdc; ///< 0: on, 1: off, 2: on except for slice boundaries
|
||||
int iLoopFilterAlphaC0Offset; ///< AlphaOffset: valid range [-6, 6], default 0
|
||||
int iLoopFilterBetaOffset; ///< BetaOffset: valid range [-6, 6], default 0
|
||||
/*pre-processing feature*/
|
||||
bool bEnableDenoise; // denoise control
|
||||
bool bEnableBackgroundDetection;// background detection control //VAA_BACKGROUND_DETECTION //BGD cmd
|
||||
bool bEnableAdaptiveQuant; // adaptive quantization control
|
||||
bool bEnableFrameCroppingFlag;// enable frame cropping flag: TRUE always in application
|
||||
bool bEnableDenoise; ///< denoise control
|
||||
bool bEnableBackgroundDetection; ///< background detection control //VAA_BACKGROUND_DETECTION //BGD cmd
|
||||
bool bEnableAdaptiveQuant; ///< adaptive quantization control
|
||||
bool bEnableFrameCroppingFlag; ///< enable frame cropping flag: TRUE always in application
|
||||
bool bEnableSceneChangeDetect;
|
||||
|
||||
/*LTR advanced setting*/
|
||||
bool bIsLosslessLink;
|
||||
bool bIsLosslessLink; ///< LTR advanced setting
|
||||
} SEncParamExt;
|
||||
|
||||
//Define a new struct to show the property of video bitstream.
|
||||
/**
|
||||
* @brief Define a new struct to show the property of video bitstream.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int size; //size of the struct
|
||||
VIDEO_BITSTREAM_TYPE eVideoBsType;
|
||||
unsigned int size; ///< size of the struct
|
||||
VIDEO_BITSTREAM_TYPE eVideoBsType; ///< video stream type (AVC/SVC)
|
||||
} SVideoProperty;
|
||||
|
||||
/* SVC Decoding Parameters, reserved here and potential applicable in the future */
|
||||
/**
|
||||
* @brief SVC Decoding Parameters, reserved here and potential applicable in the future
|
||||
*/
|
||||
typedef struct TagSVCDecodingParam {
|
||||
char* pFileNameRestructed; // File name of restructed frame used for PSNR calculation based debug
|
||||
char* pFileNameRestructed; ///< file name of reconstructed frame used for PSNR calculation based debug
|
||||
|
||||
EVideoFormatType eOutputColorFormat; // color space format to be outputed, EVideoFormatType specified in codec_def.h
|
||||
unsigned int uiCpuLoad; // CPU load
|
||||
unsigned char uiTargetDqLayer; // Setting target dq layer id
|
||||
EVideoFormatType eOutputColorFormat; ///< color space format to be outputed, EVideoFormatType specified in codec_def.h
|
||||
unsigned int uiCpuLoad; ///< CPU load
|
||||
unsigned char uiTargetDqLayer; ///< setting target dq layer id
|
||||
|
||||
ERROR_CON_IDC eEcActiveIdc; // Whether active error concealment feature in decoder
|
||||
ERROR_CON_IDC eEcActiveIdc; ///< whether active error concealment feature in decoder
|
||||
bool bParseOnly; ///< decoder for parse only, no reconstruction. When it is true, SPS/PPS size should not exceed SPS_PPS_BS_SIZE (128). Otherwise, it will return error info
|
||||
|
||||
SVideoProperty sVideoProperty;
|
||||
SVideoProperty sVideoProperty; ///< video stream property
|
||||
} SDecodingParam, *PDecodingParam;
|
||||
|
||||
/* Bitstream inforamtion of a layer being encoded */
|
||||
/**
|
||||
* @brief Bitstream inforamtion of a layer being encoded
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char uiTemporalId;
|
||||
unsigned char uiSpatialId;
|
||||
@@ -386,112 +489,160 @@ typedef struct {
|
||||
|
||||
unsigned char uiLayerType;
|
||||
|
||||
int iNalCount; // Count number of NAL coded already
|
||||
int* pNalLengthInByte; // Length of NAL size in byte from 0 to iNalCount-1
|
||||
unsigned char* pBsBuf; // Buffer of bitstream contained
|
||||
int iNalCount; ///< count number of NAL coded already
|
||||
int* pNalLengthInByte; ///< length of NAL size in byte from 0 to iNalCount-1
|
||||
unsigned char* pBsBuf; ///< buffer of bitstream contained
|
||||
} SLayerBSInfo, *PLayerBSInfo;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Frame bit stream info
|
||||
*/
|
||||
typedef struct {
|
||||
int iTemporalId; // Temporal ID
|
||||
//The sub sequence layers are ordered hierarchically based on their dependency on each other so that any picture in a layer shall not be
|
||||
//predicted from any picture on any higher layer.
|
||||
int iSubSeqId; //refer to D.2.11 Sub-sequence information SEI message semantics
|
||||
int iTemporalId; ///< temporal ID
|
||||
|
||||
/**
|
||||
* The sub sequence layers are ordered hierarchically based on their dependency on each other so that any picture in a layer shall not be
|
||||
* predicted from any picture on any higher layer.
|
||||
*/
|
||||
int iSubSeqId; ///< refer to D.2.11 Sub-sequence information SEI message semantics
|
||||
|
||||
int iLayerNum;
|
||||
SLayerBSInfo sLayerInfo[MAX_LAYER_NUM_OF_FRAME];
|
||||
|
||||
EVideoFrameType eFrameType;
|
||||
int iFrameSizeInBytes;
|
||||
long long uiTimeStamp;
|
||||
} SFrameBSInfo, *PFrameBSInfo;
|
||||
|
||||
/**
|
||||
* @brief Structure for source picture
|
||||
*/
|
||||
typedef struct Source_Picture_s {
|
||||
int iColorFormat; // color space type
|
||||
int iStride[4]; // stride for each plane pData
|
||||
unsigned char* pData[4]; // plane pData
|
||||
int iPicWidth; // luma picture width in x coordinate
|
||||
int iPicHeight; // luma picture height in y coordinate
|
||||
int iColorFormat; ///< color space type
|
||||
int iStride[4]; ///< stride for each plane pData
|
||||
unsigned char* pData[4]; ///< plane pData
|
||||
int iPicWidth; ///< luma picture width in x coordinate
|
||||
int iPicHeight; ///< luma picture height in y coordinate
|
||||
long long uiTimeStamp;
|
||||
} SSourcePicture;
|
||||
|
||||
/**
|
||||
* @brief Structure for bit rate info
|
||||
*/
|
||||
typedef struct TagBitrateInfo {
|
||||
LAYER_NUM iLayer;
|
||||
int iBitrate; //the maximum bitrate
|
||||
int iBitrate; ///< the maximum bitrate
|
||||
} SBitrateInfo;
|
||||
|
||||
/**
|
||||
* @brief Structure for dump layer info
|
||||
*/
|
||||
typedef struct TagDumpLayer {
|
||||
int iLayer;
|
||||
char* pFileName;
|
||||
} SDumpLayer;
|
||||
|
||||
/**
|
||||
* @brief Structure for profile info in layer
|
||||
*
|
||||
*/
|
||||
typedef struct TagProfileInfo {
|
||||
int iLayer;
|
||||
EProfileIdc uiProfileIdc; //the profile info
|
||||
EProfileIdc uiProfileIdc; ///< the profile info
|
||||
} SProfileInfo;
|
||||
|
||||
/**
|
||||
* @brief Structure for level info in layer
|
||||
*
|
||||
*/
|
||||
typedef struct TagLevelInfo {
|
||||
int iLayer;
|
||||
ELevelIdc uiLevelIdc; //the level info
|
||||
ELevelIdc uiLevelIdc; ///< the level info
|
||||
} SLevelInfo;
|
||||
|
||||
/**
|
||||
* @brief Structure for dilivery status
|
||||
*
|
||||
*/
|
||||
typedef struct TagDeliveryStatus {
|
||||
bool bDeliveryFlag; //0: the previous frame isn't delivered,1: the previous frame is delivered
|
||||
int iDropFrameType; // the frame type that is dropped; reserved
|
||||
int iDropFrameSize; // the frame size that is dropped; reserved
|
||||
bool bDeliveryFlag; ///< 0: the previous frame isn't delivered,1: the previous frame is delivered
|
||||
int iDropFrameType; ///< the frame type that is dropped; reserved
|
||||
int iDropFrameSize; ///< the frame size that is dropped; reserved
|
||||
} SDeliveryStatus;
|
||||
|
||||
/**
|
||||
* @brief The capability of decoder, for SDP negotiation
|
||||
*/
|
||||
typedef struct TagDecoderCapability {
|
||||
int iProfileIdc;
|
||||
int iProfileIop;
|
||||
int iLevelIdc;
|
||||
int iMaxMbps;
|
||||
int iMaxFs;
|
||||
int iMaxCpb;
|
||||
int iMaxDpb;
|
||||
int iMaxBr;
|
||||
bool bRedPicCap;
|
||||
int iProfileIdc; ///< profile_idc
|
||||
int iProfileIop; ///< profile-iop
|
||||
int iLevelIdc; ///< level_idc
|
||||
int iMaxMbps; ///< max-mbps
|
||||
int iMaxFs; ///< max-fs
|
||||
int iMaxCpb; ///< max-cpb
|
||||
int iMaxDpb; ///< max-dpb
|
||||
int iMaxBr; ///< max-br
|
||||
bool bRedPicCap; ///< redundant-pic-cap
|
||||
} SDecoderCapability;
|
||||
|
||||
/**
|
||||
* @brief to do
|
||||
*/
|
||||
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;
|
||||
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
|
||||
unsigned long long uiInBsTimeStamp; ///< input BS timestamp
|
||||
unsigned long long uiOutBsTimeStamp; ///< output BS timestamp
|
||||
} SParserBsInfo, *PParserBsInfo;
|
||||
|
||||
/**
|
||||
* @brief Structure for encoder statistics
|
||||
*/
|
||||
typedef struct TagVideoEncoderStatistics {
|
||||
unsigned int uWidth; // the width of encoded frame
|
||||
unsigned int uHeight; // the height of encoded frame
|
||||
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
|
||||
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
|
||||
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 uiAverageFrameQP; ///< the average QP of last encoded frame
|
||||
|
||||
unsigned int uiInputFrameCount; // number of frames
|
||||
unsigned int uiSkippedFrameCount; // number of frames
|
||||
unsigned int uiInputFrameCount; ///< number of frames
|
||||
unsigned int uiSkippedFrameCount; ///< number of frames
|
||||
|
||||
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
|
||||
unsigned int uIDRReqNum; // number of IDR requests
|
||||
unsigned int uIDRSentNum; // number of actual IDRs sent
|
||||
unsigned int uLTRSentNum; // number of LTR sent/marked
|
||||
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
|
||||
|
||||
/**
|
||||
* @brief Structure for decoder statistics
|
||||
*/
|
||||
typedef struct TagVideoDecoderStatistics {
|
||||
unsigned int uWidth; // the width of encode/decode frame
|
||||
unsigned int uHeight; // the height of encode/decode frame
|
||||
float fAverageFrameSpeedInMs; // Average_Decoding_Time
|
||||
|
||||
unsigned int uiDecodedFrameCount; // number of frames
|
||||
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
|
||||
unsigned int uiWidth; ///< the width of encode/decode frame
|
||||
unsigned int uiHeight; ///< the height of encode/decode frame
|
||||
float fAverageFrameSpeedInMs; ///< average_Decoding_Time
|
||||
float fActualAverageFrameSpeedInMs; ///< actual average_Decoding_Time, including freezing pictures
|
||||
unsigned int uiDecodedFrameCount; ///< number of frames
|
||||
unsigned int uiResolutionChangeTimes; ///< uiResolutionChangeTimes
|
||||
unsigned int uiIDRCorrectNum; ///< number of correct IDR received
|
||||
//EC on related
|
||||
unsigned int
|
||||
uiAvgEcRatio; // when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
|
||||
unsigned int uIDRReqNum; // number of actual IDR request
|
||||
unsigned int uLTRReqNum; // number of actual LTR request
|
||||
unsigned int uIDRRecvNum; // number of actual IDR received
|
||||
uiAvgEcRatio; ///< when EC is on, the average ratio of total EC areas, can be an indicator of reconstruction quality
|
||||
unsigned int
|
||||
uiAvgEcPropRatio; ///< when EC is on, the rough average ratio of propogate EC areas, can be an indicator of reconstruction quality
|
||||
unsigned int uiEcIDRNum; ///< number of actual unintegrity IDR or not received but eced
|
||||
unsigned int uiEcFrameNum; ///<
|
||||
unsigned int uiIDRLostNum; ///< number of whole lost IDR
|
||||
unsigned int uiFreezingIDRNum; ///< number of freezing IDR with error (partly received), under resolution change
|
||||
unsigned int uiFreezingNonIDRNum; ///< number of freezing non-IDR with error
|
||||
int iAvgLumaQp; ///< average luma QP. default: -1, no correct frame outputted
|
||||
|
||||
} SDecoderStatistics; // in building, coming soon
|
||||
|
||||
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
|
||||
|
||||
@@ -33,9 +33,15 @@
|
||||
#ifndef WELS_VIDEO_CODEC_DEFINITION_H__
|
||||
#define WELS_VIDEO_CODEC_DEFINITION_H__
|
||||
|
||||
/**
|
||||
* @file codec_def.h
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enumerate the type of video format
|
||||
*/
|
||||
typedef enum {
|
||||
/*rgb color formats*/
|
||||
videoFormatRGB = 1,
|
||||
videoFormatRGB = 1, ///< rgb color formats
|
||||
videoFormatRGBA = 2,
|
||||
videoFormatRGB555 = 3,
|
||||
videoFormatRGB565 = 4,
|
||||
@@ -44,51 +50,61 @@ typedef enum {
|
||||
videoFormatABGR = 7,
|
||||
videoFormatARGB = 8,
|
||||
|
||||
/*yuv color formats*/
|
||||
videoFormatYUY2 = 20,
|
||||
videoFormatYUY2 = 20, ///< yuv color formats
|
||||
videoFormatYVYU = 21,
|
||||
videoFormatUYVY = 22,
|
||||
videoFormatI420 = 23, //same as IYUV
|
||||
videoFormatI420 = 23, ///< the same as IYUV
|
||||
videoFormatYV12 = 24,
|
||||
videoFormatInternal = 25, // Only Used for SVC decoder testbed
|
||||
videoFormatInternal = 25, ///< only used in SVC decoder testbed
|
||||
|
||||
videoFormatNV12 = 26, // new format for output by DXVA decoding
|
||||
videoFormatNV12 = 26, ///< new format for output by DXVA decoding
|
||||
|
||||
videoFormatVFlip = 0x80000000
|
||||
} EVideoFormatType;
|
||||
|
||||
/**
|
||||
* @brief Enumerate video frame type
|
||||
*/
|
||||
typedef enum {
|
||||
videoFrameTypeInvalid, /* Encoder not ready or parameters are invalidate */
|
||||
videoFrameTypeIDR, /* This type is only available for H264 if this frame is key frame, then return this type */
|
||||
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 */
|
||||
videoFrameTypeInvalid, ///< encoder not ready or parameters are invalidate
|
||||
videoFrameTypeIDR, ///< IDR frame in H.264
|
||||
videoFrameTypeI, ///< I frame type
|
||||
videoFrameTypeP, ///< P frame type
|
||||
videoFrameTypeSkip, ///< skip the frame based encoder kernel
|
||||
videoFrameTypeIPMixed ///< a frame where I and P slices are mixing, not supported yet
|
||||
} EVideoFrameType;
|
||||
|
||||
/**
|
||||
* @brief Enumerate return type
|
||||
*/
|
||||
typedef enum {
|
||||
cmResultSuccess,
|
||||
cmInitParaError, /*Parameters are invalid */
|
||||
cmResultSuccess, ///< successful
|
||||
cmInitParaError, ///< parameters are invalid
|
||||
cmUnkonwReason,
|
||||
cmMallocMemeError, /*Malloc a memory error*/
|
||||
cmInitExpected, /*Initial action is expected*/
|
||||
cmMallocMemeError, ///< malloc a memory error
|
||||
cmInitExpected, ///< initial action is expected
|
||||
cmUnsupportedData
|
||||
} CM_RETURN;
|
||||
|
||||
/* nal unit type */
|
||||
/**
|
||||
* @brief Enumulate the nal unit type
|
||||
*/
|
||||
enum ENalUnitType {
|
||||
NAL_UNKNOWN = 0,
|
||||
NAL_SLICE = 1,
|
||||
NAL_UNKNOWN = 0,
|
||||
NAL_SLICE = 1,
|
||||
NAL_SLICE_DPA = 2,
|
||||
NAL_SLICE_DPB = 3,
|
||||
NAL_SLICE_DPC = 4,
|
||||
NAL_SLICE_IDR = 5, /* ref_idc != 0 */
|
||||
NAL_SEI = 6, /* ref_idc == 0 */
|
||||
NAL_SLICE_IDR = 5, ///< ref_idc != 0
|
||||
NAL_SEI = 6, ///< ref_idc == 0
|
||||
NAL_SPS = 7,
|
||||
NAL_PPS = 8
|
||||
/* ref_idc == 0 for 6,9,10,11,12 */
|
||||
///< ref_idc == 0 for 6,9,10,11,12
|
||||
};
|
||||
/* NRI: eNalRefIdc */
|
||||
|
||||
/**
|
||||
* @brief NRI: eNalRefIdc
|
||||
*/
|
||||
enum ENalPriority {
|
||||
NAL_PRIORITY_DISPOSABLE = 0,
|
||||
NAL_PRIORITY_LOW = 1,
|
||||
@@ -107,82 +123,80 @@ enum ENalPriority {
|
||||
|
||||
/* Error Tools definition */
|
||||
typedef unsigned short ERR_TOOL;
|
||||
|
||||
/**
|
||||
@brief to do
|
||||
*/
|
||||
enum {
|
||||
ET_NONE = 0x00, // NONE Error Tools
|
||||
ET_IP_SCALE = 0x01, // IP Scalable
|
||||
ET_FMO = 0x02, // Flexible Macroblock Ordering
|
||||
ET_IR_R1 = 0x04, // Intra Refresh in predifined 2% MB
|
||||
ET_IR_R2 = 0x08, // Intra Refresh in predifined 5% MB
|
||||
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_NONE = 0x00, ///< NONE Error Tools
|
||||
ET_IP_SCALE = 0x01, ///< IP Scalable
|
||||
ET_FMO = 0x02, ///< Flexible Macroblock Ordering
|
||||
ET_IR_R1 = 0x04, ///< Intra Refresh in predifined 2% MB
|
||||
ET_IR_R2 = 0x08, ///< Intra Refresh in predifined 5% MB
|
||||
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
|
||||
};
|
||||
|
||||
/* information of coded Slice(=NAL)(s) */
|
||||
/**
|
||||
* @brief Information of coded Slice(=NAL)(s)
|
||||
*/
|
||||
typedef struct SliceInformation {
|
||||
unsigned char* pBufferOfSlices; // base buffer of coded slice(s)
|
||||
int iCodedSliceCount; // number of coded slices
|
||||
unsigned int* pLengthOfSlices; // array of slices length accordingly by number of slice
|
||||
int iFecType; // FEC type[0, 50%FEC, 100%FEC]
|
||||
unsigned char uiSliceIdx; // index of slice in frame [FMO: 0,..,uiSliceCount-1; No FMO: 0]
|
||||
unsigned char uiSliceCount; // count number of slice in frame [FMO: 2-8; No FMO: 1]
|
||||
char iFrameIndex; // index of frame[-1, .., idr_interval-1]
|
||||
unsigned char uiNalRefIdc; // NRI, priority level of slice(NAL)
|
||||
unsigned char uiNalType; // NAL type
|
||||
unsigned char* pBufferOfSlices; ///< base buffer of coded slice(s)
|
||||
int iCodedSliceCount; ///< number of coded slices
|
||||
unsigned int* pLengthOfSlices; ///< array of slices length accordingly by number of slice
|
||||
int iFecType; ///< FEC type[0, 50%FEC, 100%FEC]
|
||||
unsigned char uiSliceIdx; ///< index of slice in frame [FMO: 0,..,uiSliceCount-1; No FMO: 0]
|
||||
unsigned char uiSliceCount; ///< count number of slice in frame [FMO: 2-8; No FMO: 1]
|
||||
char iFrameIndex; ///< index of frame[-1, .., idr_interval-1]
|
||||
unsigned char uiNalRefIdc; ///< NRI, priority level of slice(NAL)
|
||||
unsigned char uiNalType; ///< NAL type
|
||||
unsigned char
|
||||
uiContainingFinalNal; // whether final NAL is involved in buffer of coded slices, flag used in Pause feature in T27
|
||||
uiContainingFinalNal; ///< whether final NAL is involved in buffer of coded slices, flag used in Pause feature in T27
|
||||
} SliceInfo, *PSliceInfo;
|
||||
|
||||
|
||||
|
||||
#define CIF_WIDTH 352
|
||||
#define CIF_HEIGHT 288
|
||||
#define QVGA_WIDTH 320
|
||||
#define QVGA_HEIGHT 240
|
||||
#define QCIF_WIDTH 176
|
||||
#define QCIF_HEIGHT 144
|
||||
#define SQCIF_WIDTH 128
|
||||
#define SQCIF_HEIGHT 96
|
||||
|
||||
/* thresholds of the initial, maximal and minimal rate */
|
||||
/**
|
||||
* @brief thresholds of the initial, maximal and minimal rate
|
||||
*/
|
||||
typedef struct {
|
||||
int iWidth; // frame width
|
||||
int iHeight; // frame height
|
||||
int iThresholdOfInitRate; // threshold of initial rate
|
||||
int iThresholdOfMaxRate; // threshold of maximal rate
|
||||
int iThresholdOfMinRate; // threshold of minimal rate
|
||||
int iMinThresholdFrameRate; //min frame rate min
|
||||
int iSkipFrameRate; //skip to frame rate min
|
||||
int iSkipFrameStep; //how many frames to skip
|
||||
int iWidth; ///< frame width
|
||||
int iHeight; ///< frame height
|
||||
int iThresholdOfInitRate; ///< threshold of initial rate
|
||||
int iThresholdOfMaxRate; ///< threshold of maximal rate
|
||||
int iThresholdOfMinRate; ///< threshold of minimal rate
|
||||
int iMinThresholdFrameRate; ///< min frame rate min
|
||||
int iSkipFrameRate; ///< skip to frame rate min
|
||||
int iSkipFrameStep; ///< how many frames to skip
|
||||
} SRateThresholds, *PRateThresholds;
|
||||
|
||||
/**
|
||||
* @brief Structure for decoder memery
|
||||
*/
|
||||
typedef struct TagSysMemBuffer {
|
||||
int iWidth; //width of decoded pic for display
|
||||
int iHeight; //height of decoded pic for display
|
||||
int iFormat; // type is "EVideoFormatType"
|
||||
int iStride[2]; //stride of 2 component
|
||||
int iWidth; ///< width of decoded pic for display
|
||||
int iHeight; ///< height of decoded pic for display
|
||||
int iFormat; ///< type is "EVideoFormatType"
|
||||
int iStride[2]; ///< stride of 2 component
|
||||
} SSysMEMBuffer;
|
||||
|
||||
/**
|
||||
* @brief Buffer info
|
||||
*/
|
||||
typedef struct TagBufferInfo {
|
||||
int iBufferStatus; // 0: one frame data is not ready; 1: one frame data is ready
|
||||
int iBufferStatus; ///< 0: one frame data is not ready; 1: one frame data is ready
|
||||
unsigned long long uiInBsTimeStamp; ///< input BS timestamp
|
||||
unsigned long long uiOutYuvTimeStamp; ///< output YUV timestamp, when bufferstatus is 1
|
||||
union {
|
||||
SSysMEMBuffer sSystemBuffer;
|
||||
} UsrData;
|
||||
SSysMEMBuffer sSystemBuffer; ///< memory info for one picture
|
||||
} UsrData; ///< output buffer info
|
||||
} SBufferInfo;
|
||||
|
||||
/* Constants related to transmission rate at various resolutions */
|
||||
static const SRateThresholds ksRateThrMap[4] = {
|
||||
// initial-maximal-minimal
|
||||
{CIF_WIDTH, CIF_HEIGHT, 225000, 384000, 96000, 3, 1, 1}, // CIF
|
||||
{QVGA_WIDTH, QVGA_HEIGHT, 192000, 320000, 80000, -1, -1, -1}, // QVGA
|
||||
{QCIF_WIDTH, QCIF_HEIGHT, 150000, 256000, 64000, 8, 4, 2}, // QCIF
|
||||
{SQCIF_WIDTH, SQCIF_HEIGHT, 120000, 192000, 48000, 5, 3, 1} // SQCIF
|
||||
};
|
||||
|
||||
|
||||
// In a GOP, multiple of the key frame number, derived from
|
||||
// the number of layers(index or array below)
|
||||
/**
|
||||
* @brief In a GOP, multiple of the key frame number, derived from
|
||||
* the number of layers(index or array below)
|
||||
*/
|
||||
static const char kiKeyNumMultiple[] = {
|
||||
1, 1, 2, 4, 8, 16,
|
||||
};
|
||||
|
||||
15
codec/api/svc/codec_ver.h
Normal file
15
codec/api/svc/codec_ver.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//The current file is auto-generated by script: generate_codec_ver.sh
|
||||
#ifndef CODEC_VER_H
|
||||
#define CODEC_VER_H
|
||||
|
||||
#include "codec_app_def.h"
|
||||
|
||||
static const OpenH264Version g_stCodecVersion = {1,3,0,0};
|
||||
static const char* g_strCodecVer = "OpenH264 version:1.3.0.0";
|
||||
|
||||
#define OPENH264_MAJOR (1)
|
||||
#define OPENH264_MINOR (3)
|
||||
#define OPENH264_REVISION (0)
|
||||
#define OPENH264_RESERVED (0)
|
||||
|
||||
#endif // CODEC_VER_H
|
||||
54
codec/build/generate_codec_ver.sh
Executable file
54
codec/build/generate_codec_ver.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
# Run this to update the codec_ver.h at changes of api
|
||||
|
||||
#!/bin/sh
|
||||
#
|
||||
|
||||
if [ "$1"x = ""x ]; then
|
||||
echo "Please input the version number as : major_ver.minor_ver.patch.reserve"
|
||||
exit 127
|
||||
fi
|
||||
|
||||
codec_ver=`echo "$1" | egrep "^([0-9]+[.]){3}[0-9]+$"`
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Please input the version number as : major_ver.minor_ver.patch.reserve"
|
||||
exit 127
|
||||
fi
|
||||
|
||||
revision=`git show | head -n 1`
|
||||
revision=`echo $revision|cut -d' ' -f2|sed -e 's#[ ]*\(.*\)[ ]*#\1#'`
|
||||
revision=${revision:0:7}
|
||||
|
||||
echo "//The current file is auto-generated by script: generate_codec_ver.sh" >>codec_ver.h
|
||||
echo "#ifndef CODEC_VER_H" >>codec_ver.h
|
||||
echo "#define CODEC_VER_H" >>codec_ver.h
|
||||
echo "" >>codec_ver.h
|
||||
|
||||
echo "#include \"codec_app_def.h\"" >>codec_ver.h
|
||||
echo "" >>codec_ver.h
|
||||
|
||||
echo "static const OpenH264Version g_stCodecVersion = {$1};"|tr '.' ',' >>codec_ver.h
|
||||
echo "static const char* g_strCodecVer = \"OpenH264 version:$1\";" >>codec_ver.h
|
||||
#if [ "$2"x = ""x ]; then
|
||||
#echo "static const char* g_strCodecBuildNum = \"OpenH264 revision:$revision\";" >> codec_ver.h
|
||||
#else
|
||||
#echo "static const char* g_strCodecBuildNum = \"OpenH264 build:$2, OpenH264 revision:$revision\";" >> codec_ver.h
|
||||
#fi
|
||||
echo "" >>codec_ver.h
|
||||
|
||||
#define OPENH264_MAJOR 1, #define OPENH264_MINOR 2 #define OPENH264_REVISION 3 #define OPENH264_RESERVED 0
|
||||
echo "#define OPENH264_MAJOR (${1%%.*})" >>codec_ver.h
|
||||
|
||||
tmp=${1#*.}
|
||||
echo "#define OPENH264_MINOR (${tmp%%.*})" >>codec_ver.h
|
||||
|
||||
tmp=${tmp#*.}
|
||||
echo "#define OPENH264_REVISION (${tmp%%.*})" >>codec_ver.h
|
||||
|
||||
tmp=${tmp#*.}
|
||||
echo "#define OPENH264_RESERVED (${tmp%%.*})" >>codec_ver.h
|
||||
echo "" >>codec_ver.h
|
||||
|
||||
echo "#endif // CODEC_VER_H" >>codec_ver.h
|
||||
|
||||
mv -f codec_ver.h ../api/svc/codec_ver.h
|
||||
@@ -368,6 +368,11 @@
|
||||
HAVE_NEON,
|
||||
);
|
||||
"GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*]" = APPLE_IOS;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../../api/svc",
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -395,6 +400,11 @@
|
||||
HAVE_NEON,
|
||||
);
|
||||
"GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*]" = APPLE_IOS;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../../api/svc",
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
4CE4469F18BC5EAB0017DF25 /* welsDecoderExt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4468518BC5EAB0017DF25 /* welsDecoderExt.cpp */; };
|
||||
4CE447AC18BC6BE90017DF25 /* block_add_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4CE447A718BC6BE90017DF25 /* block_add_neon.S */; };
|
||||
4CE447AE18BC6BE90017DF25 /* intra_pred_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4CE447A918BC6BE90017DF25 /* intra_pred_neon.S */; };
|
||||
6A3E814219D79AE900C19C1F /* cabac_decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A3E814119D79AE900C19C1F /* cabac_decoder.cpp */; };
|
||||
6A3E814419D7A40600C19C1F /* parse_mb_syn_cabac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A3E814319D7A40600C19C1F /* parse_mb_syn_cabac.cpp */; };
|
||||
6C749B6A197CC6E600A111F9 /* block_add_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C749B69197CC6E600A111F9 /* block_add_aarch64_neon.S */; };
|
||||
9ABF4382193EB60900A6BD61 /* expand_pic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9ABF4381193EB60900A6BD61 /* expand_pic.cpp */; };
|
||||
9AED66561946A1DE009A3567 /* welsCodecTrace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AED66551946A1DE009A3567 /* welsCodecTrace.cpp */; };
|
||||
@@ -109,6 +111,10 @@
|
||||
4CE4468518BC5EAB0017DF25 /* welsDecoderExt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = welsDecoderExt.cpp; sourceTree = "<group>"; };
|
||||
4CE447A718BC6BE90017DF25 /* block_add_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = block_add_neon.S; sourceTree = "<group>"; };
|
||||
4CE447A918BC6BE90017DF25 /* intra_pred_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_neon.S; sourceTree = "<group>"; };
|
||||
6A3E814019D79AD900C19C1F /* cabac_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cabac_decoder.h; sourceTree = "<group>"; };
|
||||
6A3E814119D79AE900C19C1F /* cabac_decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cabac_decoder.cpp; sourceTree = "<group>"; };
|
||||
6A3E814319D7A40600C19C1F /* parse_mb_syn_cabac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_mb_syn_cabac.cpp; sourceTree = "<group>"; };
|
||||
6A3E814519D7A40D00C19C1F /* parse_mb_syn_cabac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parse_mb_syn_cabac.h; sourceTree = "<group>"; };
|
||||
6C749B69197CC6E600A111F9 /* block_add_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = block_add_aarch64_neon.S; path = arm64/block_add_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
9ABF4380193EB5F700A6BD61 /* expand_pic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = expand_pic.h; path = ../../../common/inc/expand_pic.h; sourceTree = "<group>"; };
|
||||
9ABF4381193EB60900A6BD61 /* expand_pic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = expand_pic.cpp; path = ../../../common/src/expand_pic.cpp; sourceTree = "<group>"; };
|
||||
@@ -191,6 +197,8 @@
|
||||
4CE4464418BC5EAA0017DF25 /* inc */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6A3E814519D7A40D00C19C1F /* parse_mb_syn_cabac.h */,
|
||||
6A3E814019D79AD900C19C1F /* cabac_decoder.h */,
|
||||
9AED665A1946A21D009A3567 /* utils.h */,
|
||||
9ABF4380193EB5F700A6BD61 /* expand_pic.h */,
|
||||
F0B204FA18FD23CF005DA23F /* error_concealment.h */,
|
||||
@@ -232,6 +240,8 @@
|
||||
4CE4466618BC5EAA0017DF25 /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6A3E814319D7A40600C19C1F /* parse_mb_syn_cabac.cpp */,
|
||||
6A3E814119D79AE900C19C1F /* cabac_decoder.cpp */,
|
||||
9AED66581946A203009A3567 /* utils.cpp */,
|
||||
9ABF4381193EB60900A6BD61 /* expand_pic.cpp */,
|
||||
F0B204FB18FD23D8005DA23F /* error_concealment.cpp */,
|
||||
@@ -346,6 +356,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6A3E814419D7A40600C19C1F /* parse_mb_syn_cabac.cpp in Sources */,
|
||||
4CE4469B18BC5EAB0017DF25 /* pic_queue.cpp in Sources */,
|
||||
4CE4469F18BC5EAB0017DF25 /* welsDecoderExt.cpp in Sources */,
|
||||
4CE4469318BC5EAB0017DF25 /* fmo.cpp in Sources */,
|
||||
@@ -355,6 +366,7 @@
|
||||
4CE4469518BC5EAB0017DF25 /* manage_dec_ref.cpp in Sources */,
|
||||
4CE4468A18BC5EAB0017DF25 /* au_parser.cpp in Sources */,
|
||||
4CE4469918BC5EAB0017DF25 /* mv_pred.cpp in Sources */,
|
||||
6A3E814219D79AE900C19C1F /* cabac_decoder.cpp in Sources */,
|
||||
4CE447AC18BC6BE90017DF25 /* block_add_neon.S in Sources */,
|
||||
6C749B6A197CC6E600A111F9 /* block_add_aarch64_neon.S in Sources */,
|
||||
4CE4469418BC5EAB0017DF25 /* get_intra_predictor.cpp in Sources */,
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
9AED66661946A2B3009A3567 /* utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AED66651946A2B3009A3567 /* utils.cpp */; };
|
||||
F5617A50196A833A006E2B20 /* reconstruct_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5617A4F196A833A006E2B20 /* reconstruct_aarch64_neon.S */; };
|
||||
F5BE8005196B913200ED02ED /* memory_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5BE8004196B913200ED02ED /* memory_aarch64_neon.S */; };
|
||||
F7E9994519EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7E9994419EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp */; };
|
||||
F7E9994919EBD1F8009B1021 /* set_mb_syn_cabac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7E9994819EBD1F8009B1021 /* set_mb_syn_cabac.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -164,6 +166,10 @@
|
||||
9AED66671946A2C4009A3567 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utils.h; path = ../../../common/inc/utils.h; sourceTree = "<group>"; };
|
||||
F5617A4F196A833A006E2B20 /* reconstruct_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = reconstruct_aarch64_neon.S; path = arm64/reconstruct_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
F5BE8004196B913200ED02ED /* memory_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = memory_aarch64_neon.S; path = arm64/memory_aarch64_neon.S; sourceTree = "<group>"; };
|
||||
F7E9994419EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = svc_set_mb_syn_cabac.cpp; sourceTree = "<group>"; };
|
||||
F7E9994819EBD1F8009B1021 /* set_mb_syn_cabac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = set_mb_syn_cabac.cpp; sourceTree = "<group>"; };
|
||||
F7E9997E19EBD3C6009B1021 /* set_mb_syn_cabac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = set_mb_syn_cabac.h; sourceTree = "<group>"; };
|
||||
F7E9997F19EBD3CE009B1021 /* svc_set_mb_syn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svc_set_mb_syn.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -254,6 +260,8 @@
|
||||
4CE446A918BC605C0017DF25 /* inc */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F7E9997F19EBD3CE009B1021 /* svc_set_mb_syn.h */,
|
||||
F7E9997E19EBD3C6009B1021 /* set_mb_syn_cabac.h */,
|
||||
9AED66671946A2C4009A3567 /* utils.h */,
|
||||
4CDBFB9D18E5068D0025A767 /* wels_transpose_matrix.h */,
|
||||
4CE446AA18BC605C0017DF25 /* as264_common.h */,
|
||||
@@ -309,6 +317,8 @@
|
||||
4CE446DC18BC605C0017DF25 /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F7E9994819EBD1F8009B1021 /* set_mb_syn_cabac.cpp */,
|
||||
F7E9994419EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp */,
|
||||
9AED66651946A2B3009A3567 /* utils.cpp */,
|
||||
4CE446DD18BC605C0017DF25 /* au_set.cpp */,
|
||||
4CE446DE18BC605C0017DF25 /* deblocking.cpp */,
|
||||
@@ -446,6 +456,7 @@
|
||||
F5BE8005196B913200ED02ED /* memory_aarch64_neon.S in Sources */,
|
||||
4CBC1B83194ACBB400214D9E /* intra_pred_aarch64_neon.S in Sources */,
|
||||
4CE4471718BC605C0017DF25 /* mc.cpp in Sources */,
|
||||
F7E9994519EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp in Sources */,
|
||||
F5617A50196A833A006E2B20 /* reconstruct_aarch64_neon.S in Sources */,
|
||||
4CE4472918BC605C0017DF25 /* svc_set_mb_syn_cavlc.cpp in Sources */,
|
||||
4CE4471818BC605C0017DF25 /* md.cpp in Sources */,
|
||||
@@ -465,6 +476,7 @@
|
||||
6CA38DA51991D31A003EAAE0 /* svc_motion_estimation_aarch64_neon.S in Sources */,
|
||||
4CE4471418BC605C0017DF25 /* encoder_ext.cpp in Sources */,
|
||||
4C34067218C57D0400DFA14A /* reconstruct_neon.S in Sources */,
|
||||
F7E9994919EBD1F8009B1021 /* set_mb_syn_cabac.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -655,6 +655,10 @@
|
||||
RelativePath="..\..\..\decoder\core\inc\bit_stream.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\decoder\core\inc\cabac_decoder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\inc\copy_mb.h"
|
||||
>
|
||||
@@ -775,6 +779,10 @@
|
||||
RelativePath="..\..\..\decoder\core\inc\parameter_sets.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\decoder\core\inc\parse_mb_syn_cabac.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\decoder\core\inc\parse_mb_syn_cavlc.h"
|
||||
>
|
||||
@@ -832,6 +840,10 @@
|
||||
RelativePath="..\..\..\decoder\core\src\bit_stream.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\decoder\core\src\cabac_decoder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\common\src\common_tables.cpp"
|
||||
>
|
||||
@@ -912,6 +924,10 @@
|
||||
RelativePath="..\..\..\decoder\core\src\mv_pred.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\decoder\core\src\parse_mb_syn_cabac.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\decoder\core\src\parse_mb_syn_cavlc.cpp"
|
||||
>
|
||||
|
||||
@@ -429,6 +429,10 @@
|
||||
RelativePath="..\..\..\encoder\core\src\sample.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\src\set_mb_syn_cabac.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\src\set_mb_syn_cavlc.cpp"
|
||||
>
|
||||
@@ -461,6 +465,10 @@
|
||||
RelativePath="..\..\..\encoder\core\src\svc_motion_estimate.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\src\svc_set_mb_syn_cabac.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\src\svc_set_mb_syn_cavlc.cpp"
|
||||
>
|
||||
@@ -626,6 +634,10 @@
|
||||
RelativePath="..\..\..\encoder\core\inc\sample.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\inc\set_mb_syn_cabac.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\inc\set_mb_syn_cavlc.h"
|
||||
>
|
||||
@@ -678,6 +690,10 @@
|
||||
RelativePath="..\..\..\encoder\core\inc\svc_motion_estimate.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\inc\svc_set_mb_syn.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\encoder\core\inc\svc_set_mb_syn_cavlc.h"
|
||||
>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/bin/bash
|
||||
rm -f codec/common/inc/version.h
|
||||
git rev-list HEAD | sort > config.git-hash
|
||||
LOCALVER=`wc -l config.git-hash | awk '{print $1}'`
|
||||
if [ $LOCALVER \> 1 ] ; then
|
||||
@@ -15,6 +14,13 @@ fi
|
||||
GIT_VERSION='"'$GIT_VERSION'"'
|
||||
rm -f config.git-hash
|
||||
|
||||
cat codec/common/inc/version.h.template | sed "s/\$FULL_VERSION/$GIT_VERSION/g" > codec/common/inc/version.h
|
||||
cat codec/common/inc/version.h.template | sed "s/\$FULL_VERSION/$GIT_VERSION/g" > codec/common/inc/version.h.new
|
||||
if cmp codec/common/inc/version.h.new codec/common/inc/version.h > /dev/null 2>&1; then
|
||||
# Identical to old version, don't touch it (to avoid unnecessary rebuilds)
|
||||
rm codec/common/inc/version.h.new
|
||||
echo "Keeping existing codec/common/inc/version.h"
|
||||
exit 0
|
||||
fi
|
||||
mv codec/common/inc/version.h.new codec/common/inc/version.h
|
||||
|
||||
echo "Generated codec/common/inc/version.h"
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "typedefs.h"
|
||||
|
||||
|
||||
@@ -116,6 +117,10 @@
|
||||
#define WELS_ROUND(x) ((int32_t)(0.5+(x)))
|
||||
#endif//WELS_ROUND
|
||||
|
||||
#ifndef WELS_ROUND64
|
||||
#define WELS_ROUND64(x) ((int64_t)(0.5+(x)))
|
||||
#endif//WELS_ROUND
|
||||
|
||||
#ifndef WELS_DIV_ROUND
|
||||
#define WELS_DIV_ROUND(x,y) ((int32_t)((y)==0?((x)/((y)+1)):(((y)/2+(x))/(y))))
|
||||
#endif//WELS_DIV_ROUND
|
||||
@@ -192,6 +197,14 @@ static inline uint8_t WelsClip1 (int32_t iX) {
|
||||
#define WELS_CLIP3(iX, iY, iZ) ((iX) < (iY) ? (iY) : ((iX) > (iZ) ? (iZ) : (iX)))
|
||||
#endif //WELS_CLIP3
|
||||
|
||||
template<typename T> T WelsClip3(T iX, T iY, T iZ) {
|
||||
if (iX < iY)
|
||||
return iY;
|
||||
if (iX > iZ)
|
||||
return iZ;
|
||||
return iX;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: to check variable validation and return the specified result
|
||||
* iResult: value to be checked
|
||||
@@ -268,6 +281,37 @@ static inline bool WELS_POWER2_IF (uint32_t v) {
|
||||
#define WELS_GCC_UNUSED
|
||||
#endif
|
||||
|
||||
inline bool CheckInRangeCloseOpen (const int16_t kiCurrent, const int16_t kiMin, const int16_t kiMax) {
|
||||
return ((kiCurrent >= kiMin) && (kiCurrent < kiMax));
|
||||
}
|
||||
|
||||
static inline void WelsSetMemUint32_c (uint32_t* pDst, uint32_t iValue, int32_t iSizeOfData) {
|
||||
for (int i = 0; i < iSizeOfData; i++) {
|
||||
pDst[i] = iValue;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void WelsSetMemUint16_c (uint16_t* pDst, uint16_t iValue, int32_t iSizeOfData) {
|
||||
for (int i = 0; i < iSizeOfData; i++) {
|
||||
pDst[i] = iValue;
|
||||
}
|
||||
}
|
||||
|
||||
inline void WelsSetMemMultiplebytes_c (void* pDst, uint32_t iValue, int32_t iSizeOfData, int32_t iDataLengthOfData) {
|
||||
assert (4 == iDataLengthOfData || 2 == iDataLengthOfData || 1 == iDataLengthOfData);
|
||||
|
||||
// TODO: consider add assembly for these functions
|
||||
if (0 != iValue) {
|
||||
if (4 == iDataLengthOfData) {
|
||||
WelsSetMemUint32_c (static_cast<uint32_t*> (pDst), static_cast<uint32_t> (iValue), iSizeOfData);
|
||||
} else if (2 == iDataLengthOfData) {
|
||||
WelsSetMemUint16_c (static_cast<uint16_t*> (pDst), static_cast<uint16_t> (iValue), iSizeOfData);
|
||||
} else {
|
||||
memset (static_cast<uint8_t*> (pDst), static_cast<uint8_t> (iValue), iSizeOfData);
|
||||
}
|
||||
} else {
|
||||
memset (static_cast<uint8_t*> (pDst), 0, iSizeOfData * iDataLengthOfData);
|
||||
}
|
||||
}
|
||||
|
||||
#endif//WELS_MACRO_UTILIZATIONS_H__
|
||||
|
||||
@@ -54,6 +54,7 @@ typedef void (*PWelsLogCallbackFunc) (void* pCtx, const int32_t iLevel, const ch
|
||||
typedef struct TagLogContext {
|
||||
PWelsLogCallbackFunc pfLog;
|
||||
void* pLogCtx;
|
||||
void* pCodecInstance;
|
||||
} SLogContext;
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -44,6 +44,7 @@ class welsCodecTrace {
|
||||
welsCodecTrace();
|
||||
~welsCodecTrace();
|
||||
|
||||
void SetCodecInstance (void* pCodecInstance);
|
||||
void SetTraceLevel (const int32_t kiLevel);
|
||||
void SetTraceCallback (WelsTraceCallback func);
|
||||
void SetTraceCallbackContext (void* pCtx);
|
||||
|
||||
@@ -36,15 +36,17 @@
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "macros.h"
|
||||
|
||||
#include "codec_app_def.h"
|
||||
|
||||
|
||||
namespace WelsCommon {
|
||||
/*common use table*/
|
||||
|
||||
#define CTX_NA 0
|
||||
#define WELS_CONTEXT_COUNT 460
|
||||
#define LEVEL_NUMBER 17
|
||||
typedef struct TagLevelLimits {
|
||||
uint8_t uiLevelIdc; // level idc
|
||||
ELevelIdc uiLevelIdc; // level idc
|
||||
uint32_t uiMaxMBPS; // Max macroblock processing rate(MB/s)
|
||||
uint32_t uiMaxFS; // Max frame sizea(MBs)
|
||||
uint32_t uiMaxDPBMbs;// Max decoded picture buffer size(MBs)
|
||||
@@ -56,7 +58,9 @@ typedef struct TagLevelLimits {
|
||||
int16_t iMaxMvsPer2Mb; // Max number of motion vectors per two consecutive MBs
|
||||
} SLevelLimits;
|
||||
|
||||
#define CpbBrNalFactor 1200 //baseline,main,and extended profiles.
|
||||
extern const SLevelLimits g_ksLevelLimits[LEVEL_NUMBER];
|
||||
extern const uint32_t g_kuiLevelMaps[LEVEL_NUMBER];
|
||||
extern const uint8_t g_kuiMbCountScan4Idx[24];
|
||||
extern const uint8_t g_kuiCache30ScanIdx[16];
|
||||
extern const uint8_t g_kuiCache48CountScan4Idx[24];
|
||||
@@ -64,6 +68,9 @@ extern const uint8_t g_kuiCache48CountScan4Idx[24];
|
||||
extern const ALIGNED_DECLARE (uint16_t, g_kuiDequantCoeff[52][8], 16);
|
||||
extern const uint8_t g_kuiChromaQpTable[52];
|
||||
|
||||
extern const uint8_t g_kuiCabacRangeLps[64][4];
|
||||
extern const int8_t g_kiCabacGlobalContextIdx[WELS_CONTEXT_COUNT][4][2];
|
||||
extern const uint8_t g_kuiStateTransTable[64][2];
|
||||
/*
|
||||
* NAL Unit Type (5 Bits)
|
||||
*/
|
||||
|
||||
@@ -151,27 +151,543 @@ ALIGNED_DECLARE (const uint16_t, g_kuiDequantCoeff[52][8], 16) = {
|
||||
|
||||
// table A-1 - Level limits
|
||||
const SLevelLimits g_ksLevelLimits[LEVEL_NUMBER] = {
|
||||
{10, 1485, 99, 396, 64, 175, -256, 255, 2, 0x7fff}, /* level 1 */
|
||||
{9, 1485, 99, 396, 128, 350, -256, 255, 2, 0x7fff}, /* level 1.b */
|
||||
{11, 3000, 396, 900, 192, 500, -512, 511, 2, 0x7fff}, /* level 1.1 */
|
||||
{12, 6000, 396, 2376, 384, 1000, -512, 511, 2, 0x7fff}, /* level 1.2 */
|
||||
{13, 11880, 396, 2376, 768, 2000, -512, 511, 2, 0x7fff}, /* level 1.3 */
|
||||
{LEVEL_1_0, 1485, 99, 396, 64, 175, -256, 255, 2, 0x7fff}, /* level 1 */
|
||||
{LEVEL_1_B, 1485, 99, 396, 128, 350, -256, 255, 2, 0x7fff}, /* level 1.b */
|
||||
{LEVEL_1_1, 3000, 396, 900, 192, 500, -512, 511, 2, 0x7fff}, /* level 1.1 */
|
||||
{LEVEL_1_2, 6000, 396, 2376, 384, 1000, -512, 511, 2, 0x7fff}, /* level 1.2 */
|
||||
{LEVEL_1_3, 11880, 396, 2376, 768, 2000, -512, 511, 2, 0x7fff}, /* level 1.3 */
|
||||
|
||||
{20, 11880, 396, 2376, 2000, 2000, -512, 511, 2, 0x7fff}, /* level 2 */
|
||||
{21, 19800, 792, 4752, 4000, 4000, -1024, 1023, 2, 0x7fff}, /* level 2.1 */
|
||||
{22, 20250, 1620, 8100, 4000, 4000, -1024, 1023, 2, 0x7fff}, /* level 2.2 */
|
||||
{LEVEL_2_0, 11880, 396, 2376, 2000, 2000, -512, 511, 2, 0x7fff}, /* level 2 */
|
||||
{LEVEL_2_1, 19800, 792, 4752, 4000, 4000, -1024, 1023, 2, 0x7fff}, /* level 2.1 */
|
||||
{LEVEL_2_2, 20250, 1620, 8100, 4000, 4000, -1024, 1023, 2, 0x7fff}, /* level 2.2 */
|
||||
|
||||
{30, 40500, 1620, 8100, 10000, 10000, -1024, 1023, 2, 32 }, /* level 3 */
|
||||
{31, 108000, 3600, 18000, 14000, 14000, -2048, 2047, 4, 16}, /* level 3.1 */
|
||||
{32, 216000, 5120, 20480, 20000, 20000, -2048, 2047, 4, 16}, /* level 3.2 */
|
||||
{LEVEL_3_0, 40500, 1620, 8100, 10000, 10000, -1024, 1023, 2, 32 }, /* level 3 */
|
||||
{LEVEL_3_1, 108000, 3600, 18000, 14000, 14000, -2048, 2047, 4, 16}, /* level 3.1 */
|
||||
{LEVEL_3_2, 216000, 5120, 20480, 20000, 20000, -2048, 2047, 4, 16}, /* level 3.2 */
|
||||
|
||||
{40, 245760, 8192, 32768, 20000, 25000, -2048, 2047, 4, 16}, /* level 4 */
|
||||
{41, 245760, 8192, 32768, 50000, 62500, -2048, 2047, 2, 16}, /* level 4.1 */
|
||||
{42, 522240, 8704, 34816, 50000, 62500, -2048, 2047, 2, 16}, /* level 4.2 */
|
||||
{LEVEL_4_0, 245760, 8192, 32768, 20000, 25000, -2048, 2047, 4, 16}, /* level 4 */
|
||||
{LEVEL_4_1, 245760, 8192, 32768, 50000, 62500, -2048, 2047, 2, 16}, /* level 4.1 */
|
||||
{LEVEL_4_2, 522240, 8704, 34816, 50000, 62500, -2048, 2047, 2, 16}, /* level 4.2 */
|
||||
|
||||
{50, 589824, 22080, 110400, 135000, 135000, -2048, 2047, 2, 16}, /* level 5 */
|
||||
{51, 983040, 36864, 184320, 240000, 240000, -2048, 2047, 2, 16}, /* level 5.1 */
|
||||
{52, 2073600, 36864, 184320, 240000, 240000, -2048, 2047, 2, 16} /* level 5.2 */
|
||||
{LEVEL_5_0, 589824, 22080, 110400, 135000, 135000, -2048, 2047, 2, 16}, /* level 5 */
|
||||
{LEVEL_5_1, 983040, 36864, 184320, 240000, 240000, -2048, 2047, 2, 16}, /* level 5.1 */
|
||||
{LEVEL_5_2, 2073600, 36864, 184320, 240000, 240000, -2048, 2047, 2, 16} /* level 5.2 */
|
||||
};
|
||||
const uint32_t g_kuiLevelMaps[LEVEL_NUMBER] = {
|
||||
10, 9, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 52
|
||||
};
|
||||
//for cabac
|
||||
/* this table is from Table9-12 to Table 9-24 */
|
||||
|
||||
const int8_t g_kiCabacGlobalContextIdx[WELS_CONTEXT_COUNT][4][2] = {
|
||||
//0-10 Table 9-12
|
||||
{{20, -15}, {20, -15}, {20, -15}, {20, -15}},
|
||||
{{2, 54}, {2, 54}, {2, 54}, {2, 54}},
|
||||
{{3, 74}, {3, 74}, {3, 74}, {3, 74}},
|
||||
{{20, -15}, {20, -15}, {20, -15}, {20, -15}},
|
||||
{{2, 54}, {2, 54}, {2, 54}, {2, 54}},
|
||||
{{3, 74}, {3, 74}, {3, 74}, {3, 74}},
|
||||
{{ -28, 127}, { -28, 127}, { -28, 127}, { -28, 127}},
|
||||
{{ -23, 104}, { -23, 104}, { -23, 104}, { -23, 104}},
|
||||
{{ -6, 53}, { -6, 53}, { -6, 53}, { -6, 53}},
|
||||
{{ -1, 54}, { -1, 54}, { -1, 54}, { -1, 54}},
|
||||
{{7, 51}, {7, 51}, {7, 51}, {7, 51}},
|
||||
//11-23 Table 9-13
|
||||
{{CTX_NA, CTX_NA}, {23, 33}, {22, 25}, {29, 16}},
|
||||
{{CTX_NA, CTX_NA}, {23, 2}, {34, 0}, {25, 0}},
|
||||
{{CTX_NA, CTX_NA}, {21, 0}, {16, 0}, {14, 0}},
|
||||
{{CTX_NA, CTX_NA}, {1, 9}, { -2, 9}, { -10, 51}},
|
||||
{{CTX_NA, CTX_NA}, {0, 49}, {4, 41}, { -3, 62}},
|
||||
{{CTX_NA, CTX_NA}, { -37, 118}, { -29, 118}, { -27, 99}},
|
||||
{{CTX_NA, CTX_NA}, {5, 57}, {2, 65}, {26, 16}},
|
||||
{{CTX_NA, CTX_NA}, { -13, 78}, { -6, 71}, { -4, 85}},
|
||||
{{CTX_NA, CTX_NA}, { -11, 65}, { -13, 79}, { -24, 102}},
|
||||
{{CTX_NA, CTX_NA}, {1, 62}, {5, 52}, {5, 57}},
|
||||
{{CTX_NA, CTX_NA}, {12, 49}, {9, 50}, {6, 57}},
|
||||
{{CTX_NA, CTX_NA}, { -4, 73}, { -3, 70}, { -17, 73}},
|
||||
{{CTX_NA, CTX_NA}, {17, 50}, {10, 54}, {14, 57}},
|
||||
//24-39 Table9-14
|
||||
{{CTX_NA, CTX_NA}, {18, 64}, {26, 34}, {20, 40}},
|
||||
{{CTX_NA, CTX_NA}, {9, 43}, {19, 22}, {20, 10}},
|
||||
{{CTX_NA, CTX_NA}, {29, 0}, {40, 0}, {29, 0}},
|
||||
{{CTX_NA, CTX_NA}, {26, 67}, {57, 2}, {54, 0}},
|
||||
{{CTX_NA, CTX_NA}, {16, 90}, {41, 36}, {37, 42}},
|
||||
{{CTX_NA, CTX_NA}, {9, 104}, {26, 69}, {12, 97}},
|
||||
{{CTX_NA, CTX_NA}, { -46, 127}, { -45, 127}, { -32, 127}},
|
||||
{{CTX_NA, CTX_NA}, { -20, 104}, { -15, 101}, { -22, 117}},
|
||||
{{CTX_NA, CTX_NA}, {1, 67}, { -4, 76}, { -2, 74}},
|
||||
{{CTX_NA, CTX_NA}, { -13, 78}, { -6, 71}, { -4, 85}},
|
||||
{{CTX_NA, CTX_NA}, { -11, 65}, { -13, 79}, { -24, 102}},
|
||||
{{CTX_NA, CTX_NA}, {1, 62}, {5, 52}, {5, 57}},
|
||||
{{CTX_NA, CTX_NA}, { -6, 86}, {6, 69}, { -6, 93}},
|
||||
{{CTX_NA, CTX_NA}, { -17, 95}, { -13, 90}, { -14, 88}},
|
||||
{{CTX_NA, CTX_NA}, { -6, 61}, {0, 52}, { -6, 44}},
|
||||
{{CTX_NA, CTX_NA}, {9, 45}, {8, 43}, {4, 55}},
|
||||
//40-53 Table 9-15
|
||||
{{CTX_NA, CTX_NA}, { -3, 69}, { -2, 69}, { -11, 89}},
|
||||
{{CTX_NA, CTX_NA}, { -6, 81}, { -5, 82}, { -15, 103}},
|
||||
{{CTX_NA, CTX_NA}, { -11, 96}, { -10, 96}, { -21, 116}},
|
||||
{{CTX_NA, CTX_NA}, {6, 55}, {2, 59}, {19, 57}},
|
||||
{{CTX_NA, CTX_NA}, {7, 67}, {2, 75}, {20, 58}},
|
||||
{{CTX_NA, CTX_NA}, { -5, 86}, { -3, 87}, {4, 84}},
|
||||
{{CTX_NA, CTX_NA}, {2, 88}, { -3, 100}, {6, 96}},
|
||||
{{CTX_NA, CTX_NA}, {0, 58}, {1, 56}, {1, 63}},
|
||||
{{CTX_NA, CTX_NA}, { -3, 76}, { -3, 74}, { -5, 85}},
|
||||
{{CTX_NA, CTX_NA}, { -10, 94}, { -6, 85}, { -13, 106}},
|
||||
{{CTX_NA, CTX_NA}, {5, 54}, {0, 59}, {5, 63}},
|
||||
{{CTX_NA, CTX_NA}, {4, 69}, { -3, 81}, {6, 75}},
|
||||
{{CTX_NA, CTX_NA}, { -3, 81}, { -7, 86}, { -3, 90}},
|
||||
{{CTX_NA, CTX_NA}, {0, 88}, { -5, 95}, { -1, 101}},
|
||||
//54-59 Table 9-16
|
||||
{{CTX_NA, CTX_NA}, { -7, 67}, { -1, 66}, {3, 55}},
|
||||
{{CTX_NA, CTX_NA}, { -5, 74}, { -1, 77}, { -4, 79}},
|
||||
{{CTX_NA, CTX_NA}, { -4, 74}, {1, 70}, { -2, 75}},
|
||||
{{CTX_NA, CTX_NA}, { -5, 80}, { -2, 86}, { -12, 97}},
|
||||
{{CTX_NA, CTX_NA}, { -7, 72}, { -5, 72}, { -7, 50}},
|
||||
{{CTX_NA, CTX_NA}, {1, 58}, {0, 61}, {1, 60}},
|
||||
//60-69 Table 9-17
|
||||
{{0, 41}, {0, 41}, {0, 41}, {0, 41}},
|
||||
{{0, 63}, {0, 63}, {0, 63}, {0, 63}},
|
||||
{{0, 63}, {0, 63}, {0, 63}, {0, 63}},
|
||||
{{0, 63}, {0, 63}, {0, 63}, {0, 63}},
|
||||
{{ -9, 83}, { -9, 83}, { -9, 83}, { -9, 83}},
|
||||
{{4, 86}, {4, 86}, {4, 86}, {4, 86}},
|
||||
{{0, 97}, {0, 97}, {0, 97}, {0, 97}},
|
||||
{{ -7, 72}, { -7, 72}, { -7, 72}, { -7, 72}},
|
||||
{{13, 41}, {13, 41}, {13, 41}, {13, 41}},
|
||||
{{3, 62}, {3, 62}, {3, 62}, {3, 62}},
|
||||
//70-104 Table 9-18
|
||||
{{0, 11}, {0, 45}, {13, 15}, {7, 34}},
|
||||
{{1, 55}, { -4, 78}, {7, 51}, { -9, 88}},
|
||||
{{0, 69}, { -3, 96}, {2, 80}, { -20, 127}},
|
||||
{{ -17, 127}, { -27, 126}, { -39, 127}, { -36, 127}},
|
||||
{{ -13, 102}, { -28, 98}, { -18, 91}, { -17, 91}},
|
||||
{{0, 82}, { -25, 101}, { -17, 96}, { -14, 95}},
|
||||
{{ -7, 74}, { -23, 67}, { -26, 81}, { -25, 84}},
|
||||
{{ -21, 107}, { -28, 82}, { -35, 98}, { -25, 86}},
|
||||
{{ -27, 127}, { -20, 94}, { -24, 102}, { -12, 89}},
|
||||
{{ -31, 127}, { -16, 83}, { -23, 97}, { -17, 91}},
|
||||
{{ -24, 127}, { -22, 110}, { -27, 119}, { -31, 127}},
|
||||
{{ -18, 95}, { -21, 91}, { -24, 99}, { -14, 76}},
|
||||
{{ -27, 127}, { -18, 102}, { -21, 110}, { -18, 103}},
|
||||
{{ -21, 114}, { -13, 93}, { -18, 102}, { -13, 90}},
|
||||
{{ -30, 127}, { -29, 127}, { -36, 127}, { -37, 127}},
|
||||
{{ -17, 123}, { -7, 92}, {0, 80}, {11, 80}},
|
||||
{{ -12, 115}, { -5, 89}, { -5, 89}, {5, 76}},
|
||||
{{ -16, 122}, { -7, 96}, { -7, 94}, {2, 84}},
|
||||
{{ -11, 115}, { -13, 108}, { -4, 92}, {5, 78}},
|
||||
{{ -12, 63}, { -3, 46}, {0, 39}, { -6, 55}},
|
||||
{{ -2, 68}, { -1, 65}, {0, 65}, {4, 61}},
|
||||
{{ -15, 84}, { -1, 57}, { -15, 84}, { -14, 83}},
|
||||
{{ -13, 104}, { -9, 93}, { -35, 127}, { -37, 127}},
|
||||
{{ -3, 70}, { -3, 74}, { -2, 73}, { -5, 79}},
|
||||
{{ -8, 93}, { -9, 92}, { -12, 104}, { -11, 104}},
|
||||
{{ -10, 90}, { -8, 87}, { -9, 91}, { -11, 91}},
|
||||
{{ -30, 127}, { -23, 126}, { -31, 127}, { -30, 127}},
|
||||
{{ -1, 74}, {5, 54}, {3, 55}, {0, 65}},
|
||||
{{ -6, 97}, {6, 60}, {7, 56}, { -2, 79}},
|
||||
{{ -7, 91}, {6, 59}, {7, 55}, {0, 72}},
|
||||
{{ -20, 127}, {6, 69}, {8, 61}, { -4, 92}},
|
||||
{{ -4, 56}, { -1, 48}, { -3, 53}, { -6, 56}},
|
||||
{{ -5, 82}, {0, 68}, {0, 68}, {3, 68}},
|
||||
{{ -7, 76}, { -4, 69}, { -7, 74}, { -8, 71}},
|
||||
{{ -22, 125}, { -8, 88}, { -9, 88}, { -13, 98}},
|
||||
//105-165 Table 9-19
|
||||
{{ -7, 93}, { -2, 85}, { -13, 103}, { -4, 86}},
|
||||
{{ -11, 87}, { -6, 78}, { -13, 91}, { -12, 88}},
|
||||
{{ -3, 77}, { -1, 75}, { -9, 89}, { -5, 82}},
|
||||
{{ -5, 71}, { -7, 77}, { -14, 92}, { -3, 72}},
|
||||
{{ -4, 63}, {2, 54}, { -8, 76}, { -4, 67}},
|
||||
{{ -4, 68}, {5, 50}, { -12, 87}, { -8, 72}},
|
||||
{{ -12, 84}, { -3, 68}, { -23, 110}, { -16, 89}},
|
||||
{{ -7, 62}, {1, 50}, { -24, 105}, { -9, 69}},
|
||||
{{ -7, 65}, {6, 42}, { -10, 78}, { -1, 59}},
|
||||
{{8, 61}, { -4, 81}, { -20, 112}, {5, 66}},
|
||||
{{5, 56}, {1, 63}, { -17, 99}, {4, 57}},
|
||||
{{ -2, 66}, { -4, 70}, { -78, 127}, { -4, 71}},
|
||||
{{1, 64}, {0, 67}, { -70, 127}, { -2, 71}},
|
||||
{{0, 61}, {2, 57}, { -50, 127}, {2, 58}},
|
||||
{{ -2, 78}, { -2, 76}, { -46, 127}, { -1, 74}},
|
||||
{{1, 50}, {11, 35}, { -4, 66}, { -4, 44}},
|
||||
{{7, 52}, {4, 64}, { -5, 78}, { -1, 69}},
|
||||
{{10, 35}, {1, 61}, { -4, 71}, {0, 62}},
|
||||
{{0, 44}, {11, 35}, { -8, 72}, { -7, 51}},
|
||||
{{11, 38}, {18, 25}, {2, 59}, { -4, 47}},
|
||||
{{1, 45}, {12, 24}, { -1, 55}, { -6, 42}},
|
||||
{{0, 46}, {13, 29}, { -7, 70}, { -3, 41}},
|
||||
{{5, 44}, {13, 36}, { -6, 75}, { -6, 53}},
|
||||
{{31, 17}, { -10, 93}, { -8, 89}, {8, 76}},
|
||||
{{1, 51}, { -7, 73}, { -34, 119}, { -9, 78}},
|
||||
{{7, 50}, { -2, 73}, { -3, 75}, { -11, 83}},
|
||||
{{28, 19}, {13, 46}, {32, 20}, {9, 52}},
|
||||
{{16, 33}, {9, 49}, {30, 22}, {0, 67}},
|
||||
{{14, 62}, { -7, 100}, { -44, 127}, { -5, 90}},
|
||||
{{ -13, 108}, {9, 53}, {0, 54}, {1, 67}},
|
||||
{{ -15, 100}, {2, 53}, { -5, 61}, { -15, 72}},
|
||||
{{ -13, 101}, {5, 53}, {0, 58}, { -5, 75}},
|
||||
{{ -13, 91}, { -2, 61}, { -1, 60}, { -8, 80}},
|
||||
{{ -12, 94}, {0, 56}, { -3, 61}, { -21, 83}},
|
||||
{{ -10, 88}, {0, 56}, { -8, 67}, { -21, 64}},
|
||||
{{ -16, 84}, { -13, 63}, { -25, 84}, { -13, 31}},
|
||||
{{ -10, 86}, { -5, 60}, { -14, 74}, { -25, 64}},
|
||||
{{ -7, 83}, { -1, 62}, { -5, 65}, { -29, 94}},
|
||||
{{ -13, 87}, {4, 57}, {5, 52}, {9, 75}},
|
||||
{{ -19, 94}, { -6, 69}, {2, 57}, {17, 63}},
|
||||
{{1, 70}, {4, 57}, {0, 61}, { -8, 74}},
|
||||
{{0, 72}, {14, 39}, { -9, 69}, { -5, 35}},
|
||||
{{ -5, 74}, {4, 51}, { -11, 70}, { -2, 27}},
|
||||
{{18, 59}, {13, 68}, {18, 55}, {13, 91}},
|
||||
{{ -8, 102}, {3, 64}, { -4, 71}, {3, 65}},
|
||||
{{ -15, 100}, {1, 61}, {0, 58}, { -7, 69}},
|
||||
{{0, 95}, {9, 63}, {7, 61}, {8, 77}},
|
||||
{{ -4, 75}, {7, 50}, {9, 41}, { -10, 66}},
|
||||
{{2, 72}, {16, 39}, {18, 25}, {3, 62}},
|
||||
{{ -11, 75}, {5, 44}, {9, 32}, { -3, 68}},
|
||||
{{ -3, 71}, {4, 52}, {5, 43}, { -20, 81}},
|
||||
{{15, 46}, {11, 48}, {9, 47}, {0, 30}},
|
||||
{{ -13, 69}, { -5, 60}, {0, 44}, {1, 7}},
|
||||
{{0, 62}, { -1, 59}, {0, 51}, { -3, 23}},
|
||||
{{0, 65}, {0, 59}, {2, 46}, { -21, 74}},
|
||||
{{21, 37}, {22, 33}, {19, 38}, {16, 66}},
|
||||
{{ -15, 72}, {5, 44}, { -4, 66}, { -23, 124}},
|
||||
{{9, 57}, {14, 43}, {15, 38}, {17, 37}},
|
||||
{{16, 54}, { -1, 78}, {12, 42}, {44, -18}},
|
||||
{{0, 62}, {0, 60}, {9, 34}, {50, -34}},
|
||||
{{12, 72}, {9, 69}, {0, 89}, { -22, 127}},
|
||||
//166-226 Table 9-20
|
||||
{{24, 0}, {11, 28}, {4, 45}, {4, 39}},
|
||||
{{15, 9}, {2, 40}, {10, 28}, {0, 42}},
|
||||
{{8, 25}, {3, 44}, {10, 31}, {7, 34}},
|
||||
{{13, 18}, {0, 49}, {33, -11}, {11, 29}},
|
||||
{{15, 9}, {0, 46}, {52, -43}, {8, 31}},
|
||||
{{13, 19}, {2, 44}, {18, 15}, {6, 37}},
|
||||
{{10, 37}, {2, 51}, {28, 0}, {7, 42}},
|
||||
{{12, 18}, {0, 47}, {35, -22}, {3, 40}},
|
||||
{{6, 29}, {4, 39}, {38, -25}, {8, 33}},
|
||||
{{20, 33}, {2, 62}, {34, 0}, {13, 43}},
|
||||
{{15, 30}, {6, 46}, {39, -18}, {13, 36}},
|
||||
{{4, 45}, {0, 54}, {32, -12}, {4, 47}},
|
||||
{{1, 58}, {3, 54}, {102, -94}, {3, 55}},
|
||||
{{0, 62}, {2, 58}, {0, 0}, {2, 58}},
|
||||
{{7, 61}, {4, 63}, {56, -15}, {6, 60}},
|
||||
{{12, 38}, {6, 51}, {33, -4}, {8, 44}},
|
||||
{{11, 45}, {6, 57}, {29, 10}, {11, 44}},
|
||||
{{15, 39}, {7, 53}, {37, -5}, {14, 42}},
|
||||
{{11, 42}, {6, 52}, {51, -29}, {7, 48}},
|
||||
{{13, 44}, {6, 55}, {39, -9}, {4, 56}},
|
||||
{{16, 45}, {11, 45}, {52, -34}, {4, 52}},
|
||||
{{12, 41}, {14, 36}, {69, -58}, {13, 37}},
|
||||
{{10, 49}, {8, 53}, {67, -63}, {9, 49}},
|
||||
{{30, 34}, { -1, 82}, {44, -5}, {19, 58}},
|
||||
{{18, 42}, {7, 55}, {32, 7}, {10, 48}},
|
||||
{{10, 55}, { -3, 78}, {55, -29}, {12, 45}},
|
||||
{{17, 51}, {15, 46}, {32, 1}, {0, 69}},
|
||||
{{17, 46}, {22, 31}, {0, 0}, {20, 33}},
|
||||
{{0, 89}, { -1, 84}, {27, 36}, {8, 63}},
|
||||
{{26, -19}, {25, 7}, {33, -25}, {35, -18}},
|
||||
{{22, -17}, {30, -7}, {34, -30}, {33, -25}},
|
||||
{{26, -17}, {28, 3}, {36, -28}, {28, -3}},
|
||||
{{30, -25}, {28, 4}, {38, -28}, {24, 10}},
|
||||
{{28, -20}, {32, 0}, {38, -27}, {27, 0}},
|
||||
{{33, -23}, {34, -1}, {34, -18}, {34, -14}},
|
||||
{{37, -27}, {30, 6}, {35, -16}, {52, -44}},
|
||||
{{33, -23}, {30, 6}, {34, -14}, {39, -24}},
|
||||
{{40, -28}, {32, 9}, {32, -8}, {19, 17}},
|
||||
{{38, -17}, {31, 19}, {37, -6}, {31, 25}},
|
||||
{{33, -11}, {26, 27}, {35, 0}, {36, 29}},
|
||||
{{40, -15}, {26, 30}, {30, 10}, {24, 33}},
|
||||
{{41, -6}, {37, 20}, {28, 18}, {34, 15}},
|
||||
{{38, 1}, {28, 34}, {26, 25}, {30, 20}},
|
||||
{{41, 17}, {17, 70}, {29, 41}, {22, 73}},
|
||||
{{30, -6}, {1, 67}, {0, 75}, {20, 34}},
|
||||
{{27, 3}, {5, 59}, {2, 72}, {19, 31}},
|
||||
{{26, 22}, {9, 67}, {8, 77}, {27, 44}},
|
||||
{{37, -16}, {16, 30}, {14, 35}, {19, 16}},
|
||||
{{35, -4}, {18, 32}, {18, 31}, {15, 36}},
|
||||
{{38, -8}, {18, 35}, {17, 35}, {15, 36}},
|
||||
{{38, -3}, {22, 29}, {21, 30}, {21, 28}},
|
||||
{{37, 3}, {24, 31}, {17, 45}, {25, 21}},
|
||||
{{38, 5}, {23, 38}, {20, 42}, {30, 20}},
|
||||
{{42, 0}, {18, 43}, {18, 45}, {31, 12}},
|
||||
{{35, 16}, {20, 41}, {27, 26}, {27, 16}},
|
||||
{{39, 22}, {11, 63}, {16, 54}, {24, 42}},
|
||||
{{14, 48}, {9, 59}, {7, 66}, {0, 93}},
|
||||
{{27, 37}, {9, 64}, {16, 56}, {14, 56}},
|
||||
{{21, 60}, { -1, 94}, {11, 73}, {15, 57}},
|
||||
{{12, 68}, { -2, 89}, {10, 67}, {26, 38}},
|
||||
{{2, 97}, { -9, 108}, { -10, 116}, { -24, 127}},
|
||||
//227-275 Table 9-21
|
||||
{{ -3, 71}, { -6, 76}, { -23, 112}, { -24, 115}},
|
||||
{{ -6, 42}, { -2, 44}, { -15, 71}, { -22, 82}},
|
||||
{{ -5, 50}, {0, 45}, { -7, 61}, { -9, 62}},
|
||||
{{ -3, 54}, {0, 52}, {0, 53}, {0, 53}},
|
||||
{{ -2, 62}, { -3, 64}, { -5, 66}, {0, 59}},
|
||||
{{0, 58}, { -2, 59}, { -11, 77}, { -14, 85}},
|
||||
{{1, 63}, { -4, 70}, { -9, 80}, { -13, 89}},
|
||||
{{ -2, 72}, { -4, 75}, { -9, 84}, { -13, 94}},
|
||||
{{ -1, 74}, { -8, 82}, { -10, 87}, { -11, 92}},
|
||||
{{ -9, 91}, { -17, 102}, { -34, 127}, { -29, 127}},
|
||||
{{ -5, 67}, { -9, 77}, { -21, 101}, { -21, 100}},
|
||||
{{ -5, 27}, {3, 24}, { -3, 39}, { -14, 57}},
|
||||
{{ -3, 39}, {0, 42}, { -5, 53}, { -12, 67}},
|
||||
{{ -2, 44}, {0, 48}, { -7, 61}, { -11, 71}},
|
||||
{{0, 46}, {0, 55}, { -11, 75}, { -10, 77}},
|
||||
{{ -16, 64}, { -6, 59}, { -15, 77}, { -21, 85}},
|
||||
{{ -8, 68}, { -7, 71}, { -17, 91}, { -16, 88}},
|
||||
{{ -10, 78}, { -12, 83}, { -25, 107}, { -23, 104}},
|
||||
{{ -6, 77}, { -11, 87}, { -25, 111}, { -15, 98}},
|
||||
{{ -10, 86}, { -30, 119}, { -28, 122}, { -37, 127}},
|
||||
{{ -12, 92}, {1, 58}, { -11, 76}, { -10, 82}},
|
||||
{{ -15, 55}, { -3, 29}, { -10, 44}, { -8, 48}},
|
||||
{{ -10, 60}, { -1, 36}, { -10, 52}, { -8, 61}},
|
||||
{{ -6, 62}, {1, 38}, { -10, 57}, { -8, 66}},
|
||||
{{ -4, 65}, {2, 43}, { -9, 58}, { -7, 70}},
|
||||
{{ -12, 73}, { -6, 55}, { -16, 72}, { -14, 75}},
|
||||
{{ -8, 76}, {0, 58}, { -7, 69}, { -10, 79}},
|
||||
{{ -7, 80}, {0, 64}, { -4, 69}, { -9, 83}},
|
||||
{{ -9, 88}, { -3, 74}, { -5, 74}, { -12, 92}},
|
||||
{{ -17, 110}, { -10, 90}, { -9, 86}, { -18, 108}},
|
||||
{{ -11, 97}, {0, 70}, {2, 66}, { -4, 79}},
|
||||
{{ -20, 84}, { -4, 29}, { -9, 34}, { -22, 69}},
|
||||
{{ -11, 79}, {5, 31}, {1, 32}, { -16, 75}},
|
||||
{{ -6, 73}, {7, 42}, {11, 31}, { -2, 58}},
|
||||
{{ -4, 74}, {1, 59}, {5, 52}, {1, 58}},
|
||||
{{ -13, 86}, { -2, 58}, { -2, 55}, { -13, 78}},
|
||||
{{ -13, 96}, { -3, 72}, { -2, 67}, { -9, 83}},
|
||||
{{ -11, 97}, { -3, 81}, {0, 73}, { -4, 81}},
|
||||
{{ -19, 117}, { -11, 97}, { -8, 89}, { -13, 99}},
|
||||
{{ -8, 78}, {0, 58}, {3, 52}, { -13, 81}},
|
||||
{{ -5, 33}, {8, 5}, {7, 4}, { -6, 38}},
|
||||
{{ -4, 48}, {10, 14}, {10, 8}, { -13, 62}},
|
||||
{{ -2, 53}, {14, 18}, {17, 8}, { -6, 58}},
|
||||
{{ -3, 62}, {13, 27}, {16, 19}, { -2, 59}},
|
||||
{{ -13, 71}, {2, 40}, {3, 37}, { -16, 73}},
|
||||
{{ -10, 79}, {0, 58}, { -1, 61}, { -10, 76}},
|
||||
{{ -12, 86}, { -3, 70}, { -5, 73}, { -13, 86}},
|
||||
{{ -13, 90}, { -6, 79}, { -1, 70}, { -9, 83}},
|
||||
{{ -14, 97}, { -8, 85}, { -4, 78}, { -10, 87}},
|
||||
//276 no use
|
||||
{{CTX_NA, CTX_NA}, {CTX_NA, CTX_NA}, {CTX_NA, CTX_NA}, {CTX_NA, CTX_NA}},
|
||||
//277-337 Table 9-22
|
||||
{{ -6, 93}, { -13, 106}, { -21, 126}, { -22, 127}},
|
||||
{{ -6, 84}, { -16, 106}, { -23, 124}, { -25, 127}},
|
||||
{{ -8, 79}, { -10, 87}, { -20, 110}, { -25, 120}},
|
||||
{{0, 66}, { -21, 114}, { -26, 126}, { -27, 127}},
|
||||
{{ -1, 71}, { -18, 110}, { -25, 124}, { -19, 114}},
|
||||
{{0, 62}, { -14, 98}, { -17, 105}, { -23, 117}},
|
||||
{{ -2, 60}, { -22, 110}, { -27, 121}, { -25, 118}},
|
||||
{{ -2, 59}, { -21, 106}, { -27, 117}, { -26, 117}},
|
||||
{{ -5, 75}, { -18, 103}, { -17, 102}, { -24, 113}},
|
||||
{{ -3, 62}, { -21, 107}, { -26, 117}, { -28, 118}},
|
||||
{{ -4, 58}, { -23, 108}, { -27, 116}, { -31, 120}},
|
||||
{{ -9, 66}, { -26, 112}, { -33, 122}, { -37, 124}},
|
||||
{{ -1, 79}, { -10, 96}, { -10, 95}, { -10, 94}},
|
||||
{{0, 71}, { -12, 95}, { -14, 100}, { -15, 102}},
|
||||
{{3, 68}, { -5, 91}, { -8, 95}, { -10, 99}},
|
||||
{{10, 44}, { -9, 93}, { -17, 111}, { -13, 106}},
|
||||
{{ -7, 62}, { -22, 94}, { -28, 114}, { -50, 127}},
|
||||
{{15, 36}, { -5, 86}, { -6, 89}, { -5, 92}},
|
||||
{{14, 40}, {9, 67}, { -2, 80}, {17, 57}},
|
||||
{{16, 27}, { -4, 80}, { -4, 82}, { -5, 86}},
|
||||
{{12, 29}, { -10, 85}, { -9, 85}, { -13, 94}},
|
||||
{{1, 44}, { -1, 70}, { -8, 81}, { -12, 91}},
|
||||
{{20, 36}, {7, 60}, { -1, 72}, { -2, 77}},
|
||||
{{18, 32}, {9, 58}, {5, 64}, {0, 71}},
|
||||
{{5, 42}, {5, 61}, {1, 67}, { -1, 73}},
|
||||
{{1, 48}, {12, 50}, {9, 56}, {4, 64}},
|
||||
{{10, 62}, {15, 50}, {0, 69}, { -7, 81}},
|
||||
{{17, 46}, {18, 49}, {1, 69}, {5, 64}},
|
||||
{{9, 64}, {17, 54}, {7, 69}, {15, 57}},
|
||||
{{ -12, 104}, {10, 41}, { -7, 69}, {1, 67}},
|
||||
{{ -11, 97}, {7, 46}, { -6, 67}, {0, 68}},
|
||||
{{ -16, 96}, { -1, 51}, { -16, 77}, { -10, 67}},
|
||||
{{ -7, 88}, {7, 49}, { -2, 64}, {1, 68}},
|
||||
{{ -8, 85}, {8, 52}, {2, 61}, {0, 77}},
|
||||
{{ -7, 85}, {9, 41}, { -6, 67}, {2, 64}},
|
||||
{{ -9, 85}, {6, 47}, { -3, 64}, {0, 68}},
|
||||
{{ -13, 88}, {2, 55}, {2, 57}, { -5, 78}},
|
||||
{{4, 66}, {13, 41}, { -3, 65}, {7, 55}},
|
||||
{{ -3, 77}, {10, 44}, { -3, 66}, {5, 59}},
|
||||
{{ -3, 76}, {6, 50}, {0, 62}, {2, 65}},
|
||||
{{ -6, 76}, {5, 53}, {9, 51}, {14, 54}},
|
||||
{{10, 58}, {13, 49}, { -1, 66}, {15, 44}},
|
||||
{{ -1, 76}, {4, 63}, { -2, 71}, {5, 60}},
|
||||
{{ -1, 83}, {6, 64}, { -2, 75}, {2, 70}},
|
||||
{{ -7, 99}, { -2, 69}, { -1, 70}, { -2, 76}},
|
||||
{{ -14, 95}, { -2, 59}, { -9, 72}, { -18, 86}},
|
||||
{{2, 95}, {6, 70}, {14, 60}, {12, 70}},
|
||||
{{0, 76}, {10, 44}, {16, 37}, {5, 64}},
|
||||
{{ -5, 74}, {9, 31}, {0, 47}, { -12, 70}},
|
||||
{{0, 70}, {12, 43}, {18, 35}, {11, 55}},
|
||||
{{ -11, 75}, {3, 53}, {11, 37}, {5, 56}},
|
||||
{{1, 68}, {14, 34}, {12, 41}, {0, 69}},
|
||||
{{0, 65}, {10, 38}, {10, 41}, {2, 65}},
|
||||
{{ -14, 73}, { -3, 52}, {2, 48}, { -6, 74}},
|
||||
{{3, 62}, {13, 40}, {12, 41}, {5, 54}},
|
||||
{{4, 62}, {17, 32}, {13, 41}, {7, 54}},
|
||||
{{ -1, 68}, {7, 44}, {0, 59}, { -6, 76}},
|
||||
{{ -13, 75}, {7, 38}, {3, 50}, { -11, 82}},
|
||||
{{11, 55}, {13, 50}, {19, 40}, { -2, 77}},
|
||||
{{5, 64}, {10, 57}, {3, 66}, { -2, 77}},
|
||||
{{12, 70}, {26, 43}, {18, 50}, {25, 42}},
|
||||
//338-398 Table9-23
|
||||
{{15, 6}, {14, 11}, {19, -6}, {17, -13}},
|
||||
{{6, 19}, {11, 14}, {18, -6}, {16, -9}},
|
||||
{{7, 16}, {9, 11}, {14, 0}, {17, -12}},
|
||||
{{12, 14}, {18, 11}, {26, -12}, {27, -21}},
|
||||
{{18, 13}, {21, 9}, {31, -16}, {37, -30}},
|
||||
{{13, 11}, {23, -2}, {33, -25}, {41, -40}},
|
||||
{{13, 15}, {32, -15}, {33, -22}, {42, -41}},
|
||||
{{15, 16}, {32, -15}, {37, -28}, {48, -47}},
|
||||
{{12, 23}, {34, -21}, {39, -30}, {39, -32}},
|
||||
{{13, 23}, {39, -23}, {42, -30}, {46, -40}},
|
||||
{{15, 20}, {42, -33}, {47, -42}, {52, -51}},
|
||||
{{14, 26}, {41, -31}, {45, -36}, {46, -41}},
|
||||
{{14, 44}, {46, -28}, {49, -34}, {52, -39}},
|
||||
{{17, 40}, {38, -12}, {41, -17}, {43, -19}},
|
||||
{{17, 47}, {21, 29}, {32, 9}, {32, 11}},
|
||||
{{24, 17}, {45, -24}, {69, -71}, {61, -55}},
|
||||
{{21, 21}, {53, -45}, {63, -63}, {56, -46}},
|
||||
{{25, 22}, {48, -26}, {66, -64}, {62, -50}},
|
||||
{{31, 27}, {65, -43}, {77, -74}, {81, -67}},
|
||||
{{22, 29}, {43, -19}, {54, -39}, {45, -20}},
|
||||
{{19, 35}, {39, -10}, {52, -35}, {35, -2}},
|
||||
{{14, 50}, {30, 9}, {41, -10}, {28, 15}},
|
||||
{{10, 57}, {18, 26}, {36, 0}, {34, 1}},
|
||||
{{7, 63}, {20, 27}, {40, -1}, {39, 1}},
|
||||
{{ -2, 77}, {0, 57}, {30, 14}, {30, 17}},
|
||||
{{ -4, 82}, { -14, 82}, {28, 26}, {20, 38}},
|
||||
{{ -3, 94}, { -5, 75}, {23, 37}, {18, 45}},
|
||||
{{9, 69}, { -19, 97}, {12, 55}, {15, 54}},
|
||||
{{ -12, 109}, { -35, 125}, {11, 65}, {0, 79}},
|
||||
{{36, -35}, {27, 0}, {37, -33}, {36, -16}},
|
||||
{{36, -34}, {28, 0}, {39, -36}, {37, -14}},
|
||||
{{32, -26}, {31, -4}, {40, -37}, {37, -17}},
|
||||
{{37, -30}, {27, 6}, {38, -30}, {32, 1}},
|
||||
{{44, -32}, {34, 8}, {46, -33}, {34, 15}},
|
||||
{{34, -18}, {30, 10}, {42, -30}, {29, 15}},
|
||||
{{34, -15}, {24, 22}, {40, -24}, {24, 25}},
|
||||
{{40, -15}, {33, 19}, {49, -29}, {34, 22}},
|
||||
{{33, -7}, {22, 32}, {38, -12}, {31, 16}},
|
||||
{{35, -5}, {26, 31}, {40, -10}, {35, 18}},
|
||||
{{33, 0}, {21, 41}, {38, -3}, {31, 28}},
|
||||
{{38, 2}, {26, 44}, {46, -5}, {33, 41}},
|
||||
{{33, 13}, {23, 47}, {31, 20}, {36, 28}},
|
||||
{{23, 35}, {16, 65}, {29, 30}, {27, 47}},
|
||||
{{13, 58}, {14, 71}, {25, 44}, {21, 62}},
|
||||
{{29, -3}, {8, 60}, {12, 48}, {18, 31}},
|
||||
{{26, 0}, {6, 63}, {11, 49}, {19, 26}},
|
||||
{{22, 30}, {17, 65}, {26, 45}, {36, 24}},
|
||||
{{31, -7}, {21, 24}, {22, 22}, {24, 23}},
|
||||
{{35, -15}, {23, 20}, {23, 22}, {27, 16}},
|
||||
{{34, -3}, {26, 23}, {27, 21}, {24, 30}},
|
||||
{{34, 3}, {27, 32}, {33, 20}, {31, 29}},
|
||||
{{36, -1}, {28, 23}, {26, 28}, {22, 41}},
|
||||
{{34, 5}, {28, 24}, {30, 24}, {22, 42}},
|
||||
{{32, 11}, {23, 40}, {27, 34}, {16, 60}},
|
||||
{{35, 5}, {24, 32}, {18, 42}, {15, 52}},
|
||||
{{34, 12}, {28, 29}, {25, 39}, {14, 60}},
|
||||
{{39, 11}, {23, 42}, {18, 50}, {3, 78}},
|
||||
{{30, 29}, {19, 57}, {12, 70}, { -16, 123}},
|
||||
{{34, 26}, {22, 53}, {21, 54}, {21, 53}},
|
||||
{{29, 39}, {22, 61}, {14, 71}, {22, 56}},
|
||||
{{19, 66}, {11, 86}, {11, 83}, {25, 61}},
|
||||
{{31, 21}, {12, 40}, {25, 32}, {21, 33}},
|
||||
{{31, 31}, {11, 51}, {21, 49}, {19, 50}},
|
||||
{{25, 50}, {14, 59}, {21, 54}, {17, 61}},
|
||||
//402-459 Table 9-24
|
||||
{{ -17, 120}, { -4, 79}, { -5, 85}, { -3, 78}},
|
||||
{{ -20, 112}, { -7, 71}, { -6, 81}, { -8, 74}},
|
||||
{{ -18, 114}, { -5, 69}, { -10, 77}, { -9, 72}},
|
||||
{{ -11, 85}, { -9, 70}, { -7, 81}, { -10, 72}},
|
||||
{{ -15, 92}, { -8, 66}, { -17, 80}, { -18, 75}},
|
||||
{{ -14, 89}, { -10, 68}, { -18, 73}, { -12, 71}},
|
||||
{{ -26, 71}, { -19, 73}, { -4, 74}, { -11, 63}},
|
||||
{{ -15, 81}, { -12, 69}, { -10, 83}, { -5, 70}},
|
||||
{{ -14, 80}, { -16, 70}, { -9, 71}, { -17, 75}},
|
||||
{{0, 68}, { -15, 67}, { -9, 67}, { -14, 72}},
|
||||
{{ -14, 70}, { -20, 62}, { -1, 61}, { -16, 67}},
|
||||
{{ -24, 56}, { -19, 70}, { -8, 66}, { -8, 53}},
|
||||
{{ -23, 68}, { -16, 66}, { -14, 66}, { -14, 59}},
|
||||
{{ -24, 50}, { -22, 65}, {0, 59}, { -9, 52}},
|
||||
{{ -11, 74}, { -20, 63}, {2, 59}, { -11, 68}},
|
||||
{{23, -13}, {9, -2}, {17, -10}, {9, -2}},
|
||||
{{26, -13}, {26, -9}, {32, -13}, {30, -10}},
|
||||
{{40, -15}, {33, -9}, {42, -9}, {31, -4}},
|
||||
{{49, -14}, {39, -7}, {49, -5}, {33, -1}},
|
||||
{{44, 3}, {41, -2}, {53, 0}, {33, 7}},
|
||||
{{45, 6}, {45, 3}, {64, 3}, {31, 12}},
|
||||
{{44, 34}, {49, 9}, {68, 10}, {37, 23}},
|
||||
{{33, 54}, {45, 27}, {66, 27}, {31, 38}},
|
||||
{{19, 82}, {36, 59}, {47, 57}, {20, 64}},
|
||||
{{ -3, 75}, { -6, 66}, { -5, 71}, { -9, 71}},
|
||||
{{ -1, 23}, { -7, 35}, {0, 24}, { -7, 37}},
|
||||
{{1, 34}, { -7, 42}, { -1, 36}, { -8, 44}},
|
||||
{{1, 43}, { -8, 45}, { -2, 42}, { -11, 49}},
|
||||
{{0, 54}, { -5, 48}, { -2, 52}, { -10, 56}},
|
||||
{{ -2, 55}, { -12, 56}, { -9, 57}, { -12, 59}},
|
||||
{{0, 61}, { -6, 60}, { -6, 63}, { -8, 63}},
|
||||
{{1, 64}, { -5, 62}, { -4, 65}, { -9, 67}},
|
||||
{{0, 68}, { -8, 66}, { -4, 67}, { -6, 68}},
|
||||
{{ -9, 92}, { -8, 76}, { -7, 82}, { -10, 79}},
|
||||
{{ -14, 106}, { -5, 85}, { -3, 81}, { -3, 78}},
|
||||
{{ -13, 97}, { -6, 81}, { -3, 76}, { -8, 74}},
|
||||
{{ -15, 90}, { -10, 77}, { -7, 72}, { -9, 72}},
|
||||
{{ -12, 90}, { -7, 81}, { -6, 78}, { -10, 72}},
|
||||
{{ -18, 88}, { -17, 80}, { -12, 72}, { -18, 75}},
|
||||
{{ -10, 73}, { -18, 73}, { -14, 68}, { -12, 71}},
|
||||
{{ -9, 79}, { -4, 74}, { -3, 70}, { -11, 63}},
|
||||
{{ -14, 86}, { -10, 83}, { -6, 76}, { -5, 70}},
|
||||
{{ -10, 73}, { -9, 71}, { -5, 66}, { -17, 75}},
|
||||
{{ -10, 70}, { -9, 67}, { -5, 62}, { -14, 72}},
|
||||
{{ -10, 69}, { -1, 61}, {0, 57}, { -16, 67}},
|
||||
{{ -5, 66}, { -8, 66}, { -4, 61}, { -8, 53}},
|
||||
{{ -9, 64}, { -14, 66}, { -9, 60}, { -14, 59}},
|
||||
{{ -5, 58}, {0, 59}, {1, 54}, { -9, 52}},
|
||||
{{2, 59}, {2, 59}, {2, 58}, { -11, 68}},
|
||||
{{21, -10}, {21, -13}, {17, -10}, {9, -2}},
|
||||
{{24, -11}, {33, -14}, {32, -13}, {30, -10}},
|
||||
{{28, -8}, {39, -7}, {42, -9}, {31, -4}},
|
||||
{{28, -1}, {46, -2}, {49, -5}, {33, -1}},
|
||||
{{29, 3}, {51, 2}, {53, 0}, {33, 7}},
|
||||
{{29, 9}, {60, 6}, {64, 3}, {31, 12}},
|
||||
{{35, 20}, {61, 17}, {68, 10}, {37, 23}},
|
||||
{{29, 36}, {55, 34}, {66, 27}, {31, 38}},
|
||||
{{14, 67}, {42, 62}, {47, 57}, {20, 64}},
|
||||
};
|
||||
|
||||
/*Table 9-44 – Specification of rangeTabLPS depending on pStateIdx and qCodIRangeIdx */
|
||||
|
||||
const uint8_t g_kuiCabacRangeLps[64][4] = {
|
||||
{ 128, 176, 208, 240}, { 128, 167, 197, 227}, { 128, 158, 187, 216}, { 123, 150, 178, 205}, { 116, 142, 169, 195}, { 111, 135, 160, 185}, { 105, 128, 152, 175}, { 100, 122, 144, 166},
|
||||
{ 95, 116, 137, 158}, { 90, 110, 130, 150}, { 85, 104, 123, 142}, { 81, 99, 117, 135}, { 77, 94, 111, 128}, { 73, 89, 105, 122}, { 69, 85, 100, 116}, { 66, 80, 95, 110},
|
||||
{ 62, 76, 90, 104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89}, { 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72},
|
||||
{ 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59}, { 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48},
|
||||
{ 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39}, { 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31},
|
||||
{ 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25}, { 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21},
|
||||
{ 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17}, { 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14},
|
||||
{ 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11}, { 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2}
|
||||
};
|
||||
|
||||
/*Table 9-45 – State transition table*/
|
||||
|
||||
const uint8_t g_kuiStateTransTable[64][2] = {
|
||||
|
||||
{0, 1}, {0, 2}, {1, 3}, {2, 4}, {2, 5}, {4, 6}, {4, 7}, {5, 8}, {6, 9}, {7, 10},
|
||||
|
||||
{8, 11}, {9, 12}, {9, 13}, {11, 14}, {11, 15}, {12, 16}, {13, 17}, {13, 18}, {15, 19}, {15, 20},
|
||||
|
||||
{16, 21}, {16, 22}, {18, 23}, {18, 24}, {19, 25}, {19, 26}, {21, 27}, {21, 28}, {22, 29}, {22, 30},
|
||||
|
||||
{23, 31}, {24, 32}, {24, 33}, {25, 34}, {26, 35}, {26, 36}, {27, 37}, {27, 38}, {28, 39}, {29, 40},
|
||||
|
||||
{29, 41}, {30, 42}, {30, 43}, {30, 44}, {31, 45}, {32, 46}, {32, 47}, {33, 48}, {33, 49}, {33, 50},
|
||||
|
||||
{34, 51}, {34, 52}, {35, 53}, {35, 54}, {35, 55}, {36, 56}, {36, 57}, {36, 58}, {37, 59}, {37, 60},
|
||||
|
||||
{37, 61}, {38, 62}, {38, 62}, {63, 63}
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
@@ -53,19 +53,19 @@ void WelsLog (SLogContext* logCtx, int32_t iLevel, const char* kpFmt, ...) {
|
||||
char pTraceTag[MAX_LOG_SIZE];
|
||||
switch (iLevel) {
|
||||
case WELS_LOG_ERROR:
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] Error:");
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] this = 0x%p, Error:", logCtx->pCodecInstance);
|
||||
break;
|
||||
case WELS_LOG_WARNING:
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] Warning:");
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] this = 0x%p, Warning:", logCtx->pCodecInstance);
|
||||
break;
|
||||
case WELS_LOG_INFO:
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] Info:");
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] this = 0x%p, Info:", logCtx->pCodecInstance);
|
||||
break;
|
||||
case WELS_LOG_DEBUG:
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] Debug:");
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] this = 0x%p, Debug:", logCtx->pCodecInstance);
|
||||
break;
|
||||
default:
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] Detail:");
|
||||
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] this = 0x%p, Detail:", logCtx->pCodecInstance);
|
||||
break;
|
||||
}
|
||||
WelsStrcat (pTraceTag, MAX_LOG_SIZE, kpFmt);
|
||||
|
||||
@@ -83,6 +83,10 @@ void welsCodecTrace::CodecTrace (const int32_t iLevel, const char* Str_Format, v
|
||||
}
|
||||
}
|
||||
|
||||
void welsCodecTrace::SetCodecInstance (void* pCodecInstance) {
|
||||
m_sLogCtx.pCodecInstance = pCodecInstance;
|
||||
}
|
||||
|
||||
void welsCodecTrace::SetTraceLevel (const int32_t iLevel) {
|
||||
if (iLevel >= 0)
|
||||
m_iTraceLevel = iLevel;
|
||||
|
||||
@@ -336,6 +336,7 @@ HRESULT CD3D9ExUtils::Render (void* pDst[3], SBufferInfo* pInfo) {
|
||||
|| m_nHeight != pInfo->UsrData.sSystemBuffer.iHeight) {
|
||||
m_nWidth = pInfo->UsrData.sSystemBuffer.iWidth;
|
||||
m_nHeight = pInfo->UsrData.sSystemBuffer.iHeight;
|
||||
MoveWindow(m_hWnd,0,0,pInfo->UsrData.sSystemBuffer.iWidth,pInfo->UsrData.sSystemBuffer.iHeight,true);
|
||||
SAFE_RELEASE (m_lpD3D9RawSurfaceShare);
|
||||
SAFE_RELEASE (m_lpD3D9Device);
|
||||
}
|
||||
|
||||
@@ -63,12 +63,18 @@ using namespace std;
|
||||
//using namespace WelsDec;
|
||||
|
||||
//#define STICK_STREAM_SIZE // For Demo interfaces test with track file of integrated frames
|
||||
//#define NO_DELAY_DECODING // For Demo interfaces test with no delay decoding
|
||||
|
||||
void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, const char* kpOuputFileName,
|
||||
int32_t& iWidth, int32_t& iHeight, const char* pOptionFileName) {
|
||||
FILE* pH264File = NULL;
|
||||
FILE* pYuvFile = NULL;
|
||||
FILE* pOptionFile = NULL;
|
||||
#if defined ( STICK_STREAM_SIZE )
|
||||
FILE* fpTrack = fopen ("3.len", "rb");
|
||||
unsigned long pInfo[4];
|
||||
#endif// STICK_STREAM_SIZE
|
||||
unsigned long long uiTimeStamp = 0;
|
||||
int64_t iStart = 0, iEnd = 0, iTotal = 0;
|
||||
int32_t iSliceSize;
|
||||
int32_t iSliceIndex = 0;
|
||||
@@ -153,12 +159,6 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
||||
goto label_exit;
|
||||
}
|
||||
|
||||
#if defined ( STICK_STREAM_SIZE )
|
||||
FILE* fpTrack = fopen ("3.len", "rb");
|
||||
|
||||
#endif// STICK_STREAM_SIZE
|
||||
|
||||
|
||||
while (true) {
|
||||
|
||||
if (iBufPos >= iFileSize) {
|
||||
@@ -169,8 +169,10 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
||||
}
|
||||
|
||||
#if defined ( STICK_STREAM_SIZE )
|
||||
if (fpTrack)
|
||||
fread (&iSliceSize, 1, sizeof (int32_t), fpTrack);
|
||||
if (fpTrack) {
|
||||
fread (pInfo, 4, sizeof (unsigned long), fpTrack);
|
||||
iSliceSize = static_cast<int32_t>(pInfo[2]);
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < iFileSize; i++) {
|
||||
if ((pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 0 && pBuf[iBufPos + i + 3] == 1
|
||||
@@ -198,7 +200,7 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
||||
pDecoder->GetOption (DECODER_OPTION_VCL_NAL, &iFeedbackVclNalInAu);
|
||||
int32_t iFeedbackTidInAu;
|
||||
pDecoder->GetOption (DECODER_OPTION_TEMPORAL_ID, &iFeedbackTidInAu);
|
||||
int32_t iErrorConMethod = (int32_t) ERROR_CON_SLICE_COPY;
|
||||
int32_t iErrorConMethod = (int32_t) ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
|
||||
pDecoder->SetOption (DECODER_OPTION_ERROR_CON_IDC, &iErrorConMethod);
|
||||
//~end for
|
||||
|
||||
@@ -206,8 +208,9 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
||||
pData[0] = NULL;
|
||||
pData[1] = NULL;
|
||||
pData[2] = NULL;
|
||||
uiTimeStamp ++;
|
||||
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
|
||||
|
||||
sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
|
||||
pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);
|
||||
|
||||
if (sDstBufInfo.iBufferStatus == 1) {
|
||||
@@ -234,6 +237,38 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
||||
++ iFrameCount;
|
||||
}
|
||||
|
||||
#ifdef NO_DELAY_DECODING
|
||||
iStart = WelsTime();
|
||||
pData[0] = NULL;
|
||||
pData[1] = NULL;
|
||||
pData[2] = NULL;
|
||||
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
|
||||
sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
|
||||
pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);
|
||||
if (sDstBufInfo.iBufferStatus == 1) {
|
||||
pDst[0] = pData[0];
|
||||
pDst[1] = pData[1];
|
||||
pDst[2] = pData[2];
|
||||
}
|
||||
iEnd = WelsTime();
|
||||
iTotal += iEnd - iStart;
|
||||
if (sDstBufInfo.iBufferStatus == 1) {
|
||||
cOutputModule.Process ((void**)pDst, &sDstBufInfo, pYuvFile);
|
||||
iWidth = sDstBufInfo.UsrData.sSystemBuffer.iWidth;
|
||||
iHeight = sDstBufInfo.UsrData.sSystemBuffer.iHeight;
|
||||
|
||||
if (pOptionFile != NULL) {
|
||||
if (iWidth != iLastWidth && iHeight != iLastHeight) {
|
||||
fwrite (&iFrameCount, sizeof (iFrameCount), 1, pOptionFile);
|
||||
fwrite (&iWidth , sizeof (iWidth) , 1, pOptionFile);
|
||||
fwrite (&iHeight, sizeof (iHeight), 1, pOptionFile);
|
||||
iLastWidth = iWidth;
|
||||
iLastHeight = iHeight;
|
||||
}
|
||||
}
|
||||
++ iFrameCount;
|
||||
}
|
||||
#endif
|
||||
iBufPos += iSliceSize;
|
||||
++ iSliceIndex;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ static int g_iCtrlC = 0;
|
||||
static void SigIntHandler (int a) {
|
||||
g_iCtrlC = 1;
|
||||
}
|
||||
static int g_LevelSetting = -1;
|
||||
static int g_LevelSetting = WELS_LOG_ERROR;
|
||||
|
||||
int ParseLayerConfig (CReadConfig& cRdLayerCfg, const int iLayer, SEncParamExt& pSvcParam, SFilesSet& sFileSet) {
|
||||
if (!cRdLayerCfg.ExistFile()) {
|
||||
@@ -238,6 +238,8 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
|
||||
pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false;
|
||||
} else if (strTag[0].compare ("EnableFrameCropping") == 0) {
|
||||
pSvcParam.bEnableFrameCroppingFlag = (atoi (strTag[1].c_str()) != 0);
|
||||
} else if (strTag[0].compare ("EntropyCodingModeFlag") == 0) {
|
||||
pSvcParam.iEntropyCodingModeFlag = (atoi (strTag[1].c_str()) != 0);
|
||||
} else if (strTag[0].compare ("LoopFilterDisableIDC") == 0) {
|
||||
pSvcParam.iLoopFilterDisableIdc = (int8_t)atoi (strTag[1].c_str());
|
||||
if (pSvcParam.iLoopFilterDisableIdc > 6 || pSvcParam.iLoopFilterDisableIdc < 0) {
|
||||
@@ -354,6 +356,7 @@ void PrintHelp() {
|
||||
printf (" -iper Intra period (default: -1) : must be a power of 2 of GOP size (or -1)\n");
|
||||
printf (" -nalsize the Maximum NAL size. which should be larger than the each layer slicesize when slice mode equals to SM_DYN_SLICE\n");
|
||||
printf (" -spsid Enable id adding in SPS/PPS per IDR \n");
|
||||
printf (" -cabac Entropy coding mode(0:cavlc 1:cabac \n");
|
||||
printf (" -denois Control denoising (default: 0)\n");
|
||||
printf (" -scene Control scene change detection (default: 0)\n");
|
||||
printf (" -bgd Control background detection (default: 0)\n");
|
||||
@@ -420,6 +423,9 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE
|
||||
else if (!strcmp (pCommand, "-spsid") && (n < argc))
|
||||
pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false;
|
||||
|
||||
else if (!strcmp (pCommand, "-cabac") && (n < argc))
|
||||
pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]);
|
||||
|
||||
else if (!strcmp (pCommand, "-denois") && (n < argc))
|
||||
pSvcParam.bEnableDenoise = atoi (argv[n++]) ? true : false;
|
||||
|
||||
@@ -574,7 +580,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
|
||||
sParam.iPicWidth = 1280; // width of picture in samples
|
||||
sParam.iPicHeight = 720; // height of picture in samples
|
||||
sParam.iTargetBitrate = 2500000; // target bitrate desired
|
||||
sParam.iMaxBitrate = MAX_BIT_RATE;
|
||||
sParam.iMaxBitrate = UNSPECIFIED_BIT_RATE;
|
||||
sParam.iRCMode = RC_QUALITY_MODE; // rc mode control
|
||||
sParam.iTemporalLayerNum = 3; // layer number at temporal level
|
||||
sParam.iSpatialLayerNum = 4; // layer number at spatial level
|
||||
@@ -594,7 +600,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
|
||||
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 90;
|
||||
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 7.5f;
|
||||
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 64000;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
|
||||
++ iIndexLayer;
|
||||
@@ -603,7 +609,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
|
||||
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 180;
|
||||
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 15.0f;
|
||||
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 160000;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
|
||||
++ iIndexLayer;
|
||||
@@ -612,7 +618,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
|
||||
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 360;
|
||||
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f;
|
||||
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 512000;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
|
||||
|
||||
@@ -622,7 +628,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
|
||||
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 720;
|
||||
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f;
|
||||
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 1500000;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
|
||||
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
|
||||
|
||||
@@ -704,9 +710,7 @@ int ProcessEncoding (ISVCEncoder* pPtrEnc, int argc, char** argv, bool bConfigFi
|
||||
iRet = 1;
|
||||
goto INSIDE_MEM_FREE;
|
||||
}
|
||||
if (g_LevelSetting >= 0) {
|
||||
pPtrEnc->SetOption (ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting);
|
||||
}
|
||||
pPtrEnc->SetOption (ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting);
|
||||
//finish reading the configurations
|
||||
iSourceWidth = pSrcPic->iPicWidth;
|
||||
iSourceHeight = pSrcPic->iPicHeight;
|
||||
|
||||
@@ -156,4 +156,22 @@ WELS_ASM_FUNC_BEGIN IdctResAddPred_neon
|
||||
vst1.32 {d22[0]},[r2],r1
|
||||
vst1.32 {d22[1]},[r2]
|
||||
WELS_ASM_FUNC_END
|
||||
|
||||
|
||||
WELS_ASM_FUNC_BEGIN WelsBlockZero16x16_neon
|
||||
veor q0, q0
|
||||
veor q1, q1
|
||||
lsl r1, r1, 1
|
||||
.rept 16
|
||||
vst1.64 {q0, q1}, [r0], r1
|
||||
.endr
|
||||
WELS_ASM_FUNC_END
|
||||
|
||||
WELS_ASM_FUNC_BEGIN WelsBlockZero8x8_neon
|
||||
veor q0, q0
|
||||
lsl r1, r1, 1
|
||||
.rept 8
|
||||
vst1.64 {q0}, [r0], r1
|
||||
.endr
|
||||
WELS_ASM_FUNC_END
|
||||
#endif
|
||||
|
||||
@@ -158,4 +158,21 @@ WELS_ASM_AARCH64_FUNC_BEGIN IdctResAddPred_AArch64_neon
|
||||
st1 {v1.s}[0],[x2],x1
|
||||
st1 {v1.s}[1],[x2]
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
|
||||
WELS_ASM_AARCH64_FUNC_BEGIN WelsBlockZero16x16_AArch64_neon
|
||||
eor v0.16b, v0.16b, v0.16b
|
||||
eor v1.16b, v1.16b, v1.16b
|
||||
lsl x1, x1, 1
|
||||
.rept 16
|
||||
st1 {v0.16b, v1.16b}, [x0], x1
|
||||
.endr
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
|
||||
WELS_ASM_AARCH64_FUNC_BEGIN WelsBlockZero8x8_AArch64_neon
|
||||
eor v0.16b, v0.16b, v0.16b
|
||||
lsl x1, x1, 1
|
||||
.rept 8
|
||||
st1 {v0.16b}, [x0], x1
|
||||
.endr
|
||||
WELS_ASM_AARCH64_FUNC_END
|
||||
#endif
|
||||
|
||||
@@ -86,7 +86,7 @@ uint8_t* DetectStartCodePrefix (const uint8_t* kpBuf, int32_t* pOffset, int32_t
|
||||
uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeader, uint8_t* pSrcRbsp,
|
||||
int32_t iSrcRbspLen, uint8_t* pSrcNal, int32_t iSrcNalLen, int32_t* pConsumedBytes);
|
||||
|
||||
int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t kiSrcLen);
|
||||
int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t kiSrcLen, uint8_t* pSrcNal, const int32_t kSrcNalLen);
|
||||
|
||||
int32_t ParseRefBasePicMarking (PBitStringAux pBs, PRefBasePicMarking pRefBasePicMarking);
|
||||
|
||||
@@ -113,7 +113,7 @@ bool CheckNextAuNewSeq (PWelsDecoderContext pCtx, const PNalUnit kpCurNal, const
|
||||
* \note Call it in case eNalUnitType is SPS.
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight);
|
||||
int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight, uint8_t* pSrcNal, const int32_t kSrcNalLen);
|
||||
|
||||
/*!
|
||||
*************************************************************************************
|
||||
@@ -129,7 +129,7 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
* \note Call it in case eNalUnitType is PPS.
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux);
|
||||
int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux, uint8_t* pSrcNal, const int32_t kSrcNalLen);
|
||||
|
||||
/*!
|
||||
*************************************************************************************
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#define WELS_BIT_STREAM_H__
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
namespace WelsDec {
|
||||
|
||||
/*
|
||||
@@ -64,9 +63,17 @@ typedef struct TagBitStringAux {
|
||||
*/
|
||||
int32_t InitBits (PBitStringAux pBitString, const uint8_t* kpBuf, const int32_t kiSize);
|
||||
|
||||
void InitReadBits (PBitStringAux pBitString);
|
||||
|
||||
int32_t InitReadBits (PBitStringAux pBitString, intX_t iEndOffset);
|
||||
|
||||
//The following for writing bs in decoder for Parse Only purpose
|
||||
void DecInitBitsForEncoding (PBitStringAux pBitString, uint8_t* kpBuf, const int32_t kiSize);
|
||||
int32_t DecBsWriteBits (PBitStringAux pBitString, int32_t iLen, const uint32_t kuiValue);
|
||||
int32_t DecBsWriteOneBit (PBitStringAux pBitString, const uint32_t kuiValue);
|
||||
int32_t DecBsFlush (PBitStringAux pBitString);
|
||||
int32_t DecBsWriteUe (PBitStringAux pBitString, const uint32_t kuiValue);
|
||||
int32_t DecBsWriteSe (PBitStringAux pBitString, const int32_t kiValue);
|
||||
int32_t DecBsRbspTrailingBits (PBitStringAux pBitString);
|
||||
void RBSP2EBSP (uint8_t* pDstBuf, uint8_t* pSrcBuf, const int32_t kiSize);
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
|
||||
111
codec/decoder/core/inc/cabac_decoder.h
Normal file
111
codec/decoder/core/inc/cabac_decoder.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*!
|
||||
* \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 cabac_decoder.h
|
||||
*
|
||||
* \brief Interfaces introduced for cabac decoder
|
||||
*
|
||||
* \date 10/10/2014 Created
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
#ifndef WELS_CABAC_DECODER_H__
|
||||
#define WELS_CABAC_DECODER_H__
|
||||
|
||||
#include "decoder_context.h"
|
||||
#include "error_code.h"
|
||||
#include "wels_common_defs.h"
|
||||
namespace WelsDec {
|
||||
static const uint8_t g_kRenormTable256[256] = {
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
|
||||
//1. CABAC context initialization
|
||||
void WelsCabacGlobalInit(PWelsDecoderContext pCabacCtx);
|
||||
void WelsCabacContextInit (PWelsDecoderContext pCtx, uint8_t eSliceType, int32_t iCabacInitIdc, int32_t iQp);
|
||||
|
||||
//2. decoding Engine initialization
|
||||
int32_t InitCabacDecEngineFromBS (PWelsCabacDecEngine pDecEngine, SBitStringAux* pBsAux);
|
||||
void RestoreCabacDecEngineToBS (PWelsCabacDecEngine pDecEngine, SBitStringAux* pBsAux);
|
||||
//3. actual decoding
|
||||
int32_t Read32BitsCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiValue, int32_t& iNumBitsRead);
|
||||
int32_t DecodeBinCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t& uiBit);
|
||||
int32_t DecodeBypassCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiBinVal);
|
||||
int32_t DecodeTerminateCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiBinVal);
|
||||
|
||||
//4. unary parsing
|
||||
int32_t DecodeUnaryBinCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, int32_t iCtxOffset,
|
||||
uint32_t& uiSymVal);
|
||||
|
||||
//5. EXGk parsing
|
||||
int32_t DecodeExpBypassCabac (PWelsCabacDecEngine pDecEngine, int32_t iCount, uint32_t& uiSymVal);
|
||||
uint32_t DecodeUEGLevelCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t& uiBinVal);
|
||||
int32_t DecodeUEGMvCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t iMaxC, uint32_t& uiCode);
|
||||
|
||||
#define WELS_CABAC_HALF 0x01FE
|
||||
#define WELS_CABAC_QUARTER 0x0100
|
||||
#define WELS_CABAC_FALSE_RETURN(iErrorInfo) \
|
||||
if(iErrorInfo) { \
|
||||
return iErrorInfo; \
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -66,15 +66,18 @@ struct TagDqLayer {
|
||||
int8_t* pMbType;
|
||||
int32_t* pSliceIdc; // using int32_t for slice_idc
|
||||
int16_t (*pMv[LIST_A])[MB_BLOCK4x4_NUM][MV_A];
|
||||
int16_t (*pMvd[LIST_A])[MB_BLOCK4x4_NUM][MV_A];
|
||||
int8_t (*pRefIndex[LIST_A])[MB_BLOCK4x4_NUM];
|
||||
int8_t* pLumaQp;
|
||||
int8_t* pChromaQp;
|
||||
int8_t* pCbp;
|
||||
uint8_t *pCbfDc;
|
||||
int8_t (*pNzc)[24];
|
||||
int8_t (*pNzcRs)[24];
|
||||
int8_t* pResidualPredFlag;
|
||||
int8_t* pInterPredictionDoneFlag;
|
||||
bool* pMbCorrectlyDecodedFlag;
|
||||
bool* pMbRefConcealedFlag;
|
||||
int16_t (*pScaledTCoeff)[MB_COEFF_LIST_SIZE];
|
||||
int8_t (*pIntraPredMode)[8]; //0~3 top4x4 ; 4~6 left 4x4; 7 intra16x16
|
||||
int8_t (*pIntra4x4FinalMode)[MB_BLOCK4x4_NUM];
|
||||
|
||||
@@ -219,7 +219,7 @@ static inline int32_t BsGetTe0 (PBitStringAux pBs, int32_t iRange, uint32_t* pCo
|
||||
static inline int32_t BsGetTrailingBits (uint8_t* pBuf) {
|
||||
// TODO
|
||||
uint32_t uiValue = *pBuf;
|
||||
int32_t iRetNum = 1;
|
||||
int32_t iRetNum = 0;
|
||||
|
||||
do {
|
||||
if (uiValue & 1)
|
||||
|
||||
@@ -38,17 +38,21 @@
|
||||
namespace WelsDec {
|
||||
|
||||
int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx);
|
||||
int32_t WelsDecodeMbCavlcISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur);
|
||||
int32_t WelsDecodeMbCavlcISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag);
|
||||
|
||||
int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx);
|
||||
int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur);
|
||||
typedef int32_t (*PWelsDecMbCavlcFunc) (PWelsDecoderContext pCtx, PNalUnit pNalCur);
|
||||
int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag);
|
||||
typedef int32_t (*PWelsDecMbFunc) (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag);
|
||||
|
||||
int32_t WelsDecodeMbCabacISlice(PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag);
|
||||
int32_t WelsDecodeMbCabacPSlice(PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag);
|
||||
int32_t WelsDecodeMbCabacISliceBaseMode0(PWelsDecoderContext pCtx, uint32_t& uiEosFlag);
|
||||
int32_t WelsDecodeMbCabacPSliceBaseMode0(PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiEosFlag);
|
||||
|
||||
int32_t WelsTargetSliceConstruction (PWelsDecoderContext pCtx); //construction based on slice
|
||||
|
||||
int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNalUnit pNalCur);
|
||||
|
||||
|
||||
int32_t WelsTargetMbConstruction (PWelsDecoderContext pCtx);
|
||||
|
||||
int32_t WelsMbIntraPredictionConstruction (PWelsDecoderContext pCtx, PDqLayer pCurLayer, bool bOutput);
|
||||
@@ -63,12 +67,21 @@ void WelsChromaDcIdct (int16_t* pBlock);
|
||||
extern "C" {
|
||||
#endif//__cplusplus
|
||||
|
||||
#if defined(X86_ASM)
|
||||
void WelsBlockZero16x16_sse2(int16_t * block, int32_t stride);
|
||||
void WelsBlockZero8x8_sse2(int16_t * block, int32_t stride);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_NEON)
|
||||
void SetNonZeroCount_neon (int8_t* pNonZeroCount);
|
||||
void WelsBlockZero16x16_neon(int16_t * block, int32_t stride);
|
||||
void WelsBlockZero8x8_neon(int16_t * block, int32_t stride);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_NEON_AARCH64)
|
||||
void SetNonZeroCount_AArch64_neon (int8_t* pNonZeroCount);
|
||||
void WelsBlockZero16x16_AArch64_neon(int16_t * block, int32_t stride);
|
||||
void WelsBlockZero8x8_AArch64_neon(int16_t * block, int32_t stride);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -77,6 +90,8 @@ void SetNonZeroCount_AArch64_neon (int8_t* pNonZeroCount);
|
||||
void SetNonZeroCount_c (int8_t* pNonZeroCount);
|
||||
|
||||
void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu);
|
||||
void WelsBlockZero16x16_c(int16_t * block, int32_t stride);
|
||||
void WelsBlockZero8x8_c(int16_t * block, int32_t stride);
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ int32_t DecoderConfigParam (PWelsDecoderContext pCtx, const SDecodingParam* kpPa
|
||||
* \note N/A
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t WelsInitDecoder (PWelsDecoderContext pCtx, SLogContext* pLogCtx);
|
||||
int32_t WelsInitDecoder (PWelsDecoderContext pCtx, const bool bParseOnly, SLogContext* pLogCtx);
|
||||
|
||||
/*!
|
||||
*************************************************************************************
|
||||
@@ -101,7 +101,7 @@ void WelsEndDecoder (PWelsDecoderContext pCtx);
|
||||
*/
|
||||
|
||||
int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const int32_t kiBsLen,
|
||||
uint8_t** ppDst, SBufferInfo* pDstBufInfo);
|
||||
uint8_t** ppDst, SBufferInfo* pDstBufInfo, SParserBsInfo* pDstBsInfo);
|
||||
|
||||
/*
|
||||
* request memory blocks for decoder avc part
|
||||
@@ -132,11 +132,19 @@ int32_t SyncPictureResolutionExt (PWelsDecoderContext pCtx, const int32_t kiMbWi
|
||||
|
||||
void AssignFuncPointerForRec (PWelsDecoderContext pCtx);
|
||||
|
||||
void ResetParameterSetsState (PWelsDecoderContext pCtx);
|
||||
|
||||
void GetVclNalTemporalId (PWelsDecoderContext pCtx); //get the info that whether or not have VCL NAL in current AU,
|
||||
//and if YES, get the temporal ID
|
||||
|
||||
//reset decoder number related statistics info
|
||||
void ResetDecStatNums (SDecoderStatistics* pDecStat);
|
||||
//update information when freezing occurs, including IDR/non-IDR number
|
||||
void UpdateDecStatFreezingInfo (const bool kbIdrFlag, SDecoderStatistics* pDecStat);
|
||||
//update information when no freezing occurs, including QP, correct IDR number, ECed IDR number
|
||||
void UpdateDecStatNoFreezingInfo (PWelsDecoderContext pCtx);
|
||||
//update decoder statistics information
|
||||
void UpdateDecStat (PWelsDecoderContext pCtx, const bool kbOutput);
|
||||
//Destroy picutre buffer
|
||||
void DestroyPicBuff (PPicBuff* ppPicBuf);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif//__cplusplus
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "utils.h"
|
||||
#include "wels_const.h"
|
||||
#include "wels_common_basis.h"
|
||||
#include "wels_common_defs.h"
|
||||
#include "codec_app_def.h"
|
||||
#include "parameter_sets.h"
|
||||
#include "nalu.h"
|
||||
@@ -56,6 +57,42 @@
|
||||
#include "expand_pic.h"
|
||||
|
||||
namespace WelsDec {
|
||||
#define MAX_PRED_MODE_ID_I16x16 3
|
||||
#define MAX_PRED_MODE_ID_CHROMA 3
|
||||
#define MAX_PRED_MODE_ID_I4x4 8
|
||||
#define WELS_QP_MAX 51
|
||||
|
||||
typedef struct SWels_Cabac_Element {
|
||||
uint8_t uiState;
|
||||
uint8_t uiMPS;
|
||||
}SWelsCabacCtx, *PWelsCabacCtx;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t uiRange;
|
||||
uint64_t uiOffset;
|
||||
int32_t iBitsLeft;
|
||||
uint8_t *pBuffStart;
|
||||
uint8_t *pBuffCurr;
|
||||
uint8_t *pBuffEnd;
|
||||
} SWelsCabacDecEngine, *PWelsCabacDecEngine;
|
||||
|
||||
#define NEW_CTX_OFFSET_MB_TYPE_I 3
|
||||
#define NEW_CTX_OFFSET_SKIP 11
|
||||
#define NEW_CTX_OFFSET_SUBMB_TYPE 21
|
||||
#define NEW_CTX_OFFSET_MVD 40
|
||||
#define NEW_CTX_OFFSET_REF_NO 54
|
||||
#define NEW_CTX_OFFSET_DELTA_QP 60
|
||||
#define NEW_CTX_OFFSET_IPR 68
|
||||
#define NEW_CTX_OFFSET_CIPR 64
|
||||
#define NEW_CTX_OFFSET_CBP 73
|
||||
#define NEW_CTX_OFFSET_CBF 85
|
||||
#define NEW_CTX_OFFSET_MAP 105
|
||||
#define NEW_CTX_OFFSET_LAST 166
|
||||
#define NEW_CTX_OFFSET_ONE 227
|
||||
#define NEW_CTX_OFFSET_ABS 232
|
||||
#define CTX_NUM_MVD 7
|
||||
#define CTX_NUM_CBP 4
|
||||
|
||||
typedef struct TagDataBuffer {
|
||||
uint8_t* pHead;
|
||||
@@ -65,6 +102,19 @@ uint8_t* pStartPos;
|
||||
uint8_t* pCurPos;
|
||||
} SDataBuffer;
|
||||
|
||||
//limit size for SPS PPS total permitted size for parse_only
|
||||
#define SPS_PPS_BS_SIZE 128
|
||||
typedef struct TagSpsBsInfo {
|
||||
uint8_t pSpsBsBuf [SPS_PPS_BS_SIZE];
|
||||
int32_t iSpsId;
|
||||
uint16_t uiSpsBsLen;
|
||||
} SSpsBsInfo;
|
||||
|
||||
typedef struct TagPpsBsInfo {
|
||||
uint8_t pPpsBsBuf [SPS_PPS_BS_SIZE];
|
||||
int32_t iPpsId;
|
||||
uint16_t uiPpsBsLen;
|
||||
} SPpsBsInfo;
|
||||
//#ifdef __cplusplus
|
||||
//extern "C" {
|
||||
//#endif//__cplusplus
|
||||
@@ -141,16 +191,20 @@ PChromaDeblockingEQ4Func pfChromaDeblockingEQ4Hor;
|
||||
} SDeblockingFunc, *PDeblockingFunc;
|
||||
|
||||
typedef void (*PWelsNonZeroCountFunc) (int8_t* pNonZeroCount);
|
||||
|
||||
typedef void (*PWelsBlockZeroFunc) (int16_t* block,int32_t stride);
|
||||
typedef struct TagBlockFunc {
|
||||
PWelsNonZeroCountFunc pWelsSetNonZeroCountFunc;
|
||||
PWelsBlockZeroFunc pWelsBlockZero16x16Func;
|
||||
PWelsBlockZeroFunc pWelsBlockZero8x8Func;
|
||||
} SBlockFunc;
|
||||
|
||||
typedef void (*PWelsFillNeighborMbInfoIntra4x4Func) (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
typedef void (*PWelsFillNeighborMbInfoIntra4x4Func) (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int8_t* pIntraPredMode, PDqLayer pCurLayer);
|
||||
typedef int32_t (*PWelsParseIntra4x4ModeFunc) (PNeighAvail pNeighAvail, int8_t* pIntraPredMode, PBitStringAux pBs,
|
||||
typedef void (*PWelsMapNeighToSample) (PWelsNeighAvail pNeighAvail, int32_t* pSampleAvail);
|
||||
typedef void (*PWelsMap16NeighToSample) (PWelsNeighAvail pNeighAvail, uint8_t* pSampleAvail);
|
||||
typedef int32_t (*PWelsParseIntra4x4ModeFunc) (PWelsNeighAvail pNeighAvail, int8_t* pIntraPredMode, PBitStringAux pBs,
|
||||
PDqLayer pCurDqLayer);
|
||||
typedef int32_t (*PWelsParseIntra16x16ModeFunc) (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer);
|
||||
typedef int32_t (*PWelsParseIntra16x16ModeFunc) (PWelsNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer);
|
||||
|
||||
enum {
|
||||
OVERWRITE_NONE = 0,
|
||||
@@ -169,6 +223,7 @@ SLogContext sLogCtx;
|
||||
void* pArgDec; // structured arguments for decoder, reserved here for extension in the future
|
||||
|
||||
SDataBuffer sRawData;
|
||||
SDataBuffer sSavedData; //for parse only purpose
|
||||
|
||||
// Configuration
|
||||
SDecodingParam* pParam;
|
||||
@@ -180,6 +235,10 @@ bool bHaveGotMemory; // global memory for decoder context related ever reques
|
||||
|
||||
int32_t iImgWidthInPixel; // width of image in pixel reconstruction picture to be output
|
||||
int32_t iImgHeightInPixel;// height of image in pixel reconstruction picture to be output
|
||||
int32_t iLastImgWidthInPixel; // width of image in last successful pixel reconstruction picture to be output
|
||||
int32_t iLastImgHeightInPixel;// height of image in last successful pixel reconstruction picture to be output
|
||||
bool bFreezeOutput; // indicating current frame freezing. Default: true
|
||||
|
||||
|
||||
// Derived common elements
|
||||
SNalUnitHeader sCurNalHead;
|
||||
@@ -202,6 +261,8 @@ struct {
|
||||
int8_t (*pRefIndex[LAYER_NUM_EXCHANGEABLE][LIST_A])[MB_BLOCK4x4_NUM];
|
||||
int8_t* pLumaQp[LAYER_NUM_EXCHANGEABLE]; /*mb luma_qp*/
|
||||
int8_t* pChromaQp[LAYER_NUM_EXCHANGEABLE]; /*mb chroma_qp*/
|
||||
int16_t (*pMvd[LAYER_NUM_EXCHANGEABLE][LIST_A])[MB_BLOCK4x4_NUM][MV_A]; //[LAYER_NUM_EXCHANGEABLE MB_BLOCK4x4_NUM*]
|
||||
uint8_t *pCbfDc[LAYER_NUM_EXCHANGEABLE];
|
||||
int8_t (*pNzc[LAYER_NUM_EXCHANGEABLE])[24];
|
||||
int8_t (*pNzcRs[LAYER_NUM_EXCHANGEABLE])[24];
|
||||
int16_t (*pScaledTCoeff[LAYER_NUM_EXCHANGEABLE])[MB_COEFF_LIST_SIZE]; /*need be aligned*/
|
||||
@@ -215,6 +276,7 @@ struct {
|
||||
int8_t* pResidualPredFlag[LAYER_NUM_EXCHANGEABLE];
|
||||
int8_t* pInterPredictionDoneFlag[LAYER_NUM_EXCHANGEABLE];
|
||||
bool* pMbCorrectlyDecodedFlag[LAYER_NUM_EXCHANGEABLE];
|
||||
bool* pMbRefConcealedFlag[LAYER_NUM_EXCHANGEABLE];
|
||||
uint32_t iMbWidth;
|
||||
uint32_t iMbHeight;
|
||||
} sMb;
|
||||
@@ -287,6 +349,14 @@ bool bNewSeqBegin;
|
||||
bool bNextNewSeqBegin;
|
||||
int iOverwriteFlags;
|
||||
ERROR_CON_IDC eErrorConMethod; //
|
||||
|
||||
//for Parse only
|
||||
bool bParseOnly;
|
||||
SSpsBsInfo sSpsBsInfo [MAX_SPS_COUNT];
|
||||
SSpsBsInfo sSubsetSpsBsInfo [MAX_PPS_COUNT];
|
||||
SPpsBsInfo sPpsBsInfo [MAX_PPS_COUNT];
|
||||
SParserBsInfo* pParserBsInfo;
|
||||
|
||||
PPicture pPreviousDecodedPictureInDpb; //pointer to previously decoded picture in DPB for error concealment
|
||||
PGetIntraPredFunc pGetI16x16LumaPredFunc[7]; //h264_predict_copy_16x16;
|
||||
PGetIntraPredFunc pGetI4x4LumaPredFunc[14]; // h264_predict_4x4_t
|
||||
@@ -308,8 +378,8 @@ int32_t iCurSeqIntervalMaxPicWidth;
|
||||
int32_t iCurSeqIntervalMaxPicHeight;
|
||||
|
||||
PWelsFillNeighborMbInfoIntra4x4Func pFillInfoCacheIntra4x4Func;
|
||||
PWelsParseIntra4x4ModeFunc pParseIntra4x4ModeFunc;
|
||||
PWelsParseIntra16x16ModeFunc pParseIntra16x16ModeFunc;
|
||||
PWelsMapNeighToSample pMap4x4NeighToSampleFunc;
|
||||
PWelsMap16NeighToSample pMap16x16NeighToSampleFunc;
|
||||
|
||||
//feedback whether or not have VCL in current AU, and the temporal ID
|
||||
int32_t iFeedbackVclNalInAu;
|
||||
@@ -325,7 +395,20 @@ void* pTraceHandle;
|
||||
//Save the last nal header info
|
||||
SNalUnitHeaderExt sLastNalHdrExt;
|
||||
SSliceHeader sLastSliceHeader;
|
||||
|
||||
SWelsCabacCtx sWelsCabacContexts[4][WELS_QP_MAX + 1][WELS_CONTEXT_COUNT];
|
||||
bool bCabacInited;
|
||||
SWelsCabacCtx pCabacCtx[WELS_CONTEXT_COUNT];
|
||||
PWelsCabacDecEngine pCabacDecEngine;
|
||||
double dDecTime;
|
||||
SDecoderStatistics sDecoderStatistics;// For real time debugging
|
||||
int32_t iMbEcedNum;
|
||||
int32_t iMbEcedPropNum;
|
||||
int32_t iMbNum;
|
||||
bool bMbRefConcealed;
|
||||
bool bRPLRError;
|
||||
int32_t iECMVs[16][2];
|
||||
PPicture pECRefPic[16];
|
||||
unsigned long long uiTimeStamp;
|
||||
} SWelsDecoderContext, *PWelsDecoderContext;
|
||||
|
||||
static inline void ResetActiveSPSForEachLayer (PWelsDecoderContext pCtx) {
|
||||
@@ -337,6 +420,7 @@ for (int i = 0; i < MAX_LAYER_NUM; i++) {
|
||||
//}
|
||||
//#endif//__cplusplus
|
||||
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
#endif//WELS_DECODER_FRAMEWORK_H__
|
||||
|
||||
@@ -157,7 +157,9 @@ void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
|
||||
void ForceResetCurrentAccessUnit (PAccessUnit pAu);
|
||||
void ForceClearCurrentNal (PAccessUnit pAu);
|
||||
|
||||
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx); // Check whether all ref pictures are complete
|
||||
bool CheckRefPicturesComplete (PWelsDecoderContext pCtx); // Check whether all ref pictures are complete
|
||||
|
||||
void ForceResetParaSetStatusAndAUList(PWelsDecoderContext pCtx);
|
||||
} // namespace WelsDec
|
||||
|
||||
#endif//WELS_DECODER_CORE_H__
|
||||
|
||||
@@ -117,6 +117,7 @@ ERR_INFO_INVALID_SLICE_ALPHA_C0_OFFSET_DIV2,
|
||||
ERR_INFO_INVALID_SLICE_BETA_OFFSET_DIV2,
|
||||
ERR_INFO_FMO_INIT_FAIL,
|
||||
ERR_INFO_SLICE_TYPE_OVERFLOW,
|
||||
ERR_INFO_INVALID_CABAC_INIT_IDC,
|
||||
ERR_INFO_INVALID_QP,
|
||||
ERR_INFO_INVALID_PIC_INIT_QS,
|
||||
ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET,
|
||||
@@ -154,6 +155,7 @@ ERR_INFO_UNSUPPORTED_SPSI,
|
||||
ERR_INFO_UNSUPPORTED_MGS,
|
||||
ERR_INFO_UNSUPPORTED_BIPRED,
|
||||
ERR_INFO_UNSUPPORTED_WP,
|
||||
ERR_INFO_UNSUPPORTED_SLICESKIP,
|
||||
|
||||
ERR_INFO_FRAMES_LOST,
|
||||
ERR_INFO_DEPENDENCY_SPATIAL_LAYER_LOST,
|
||||
@@ -180,7 +182,9 @@ 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,
|
||||
//for CABAC
|
||||
ERR_CABAC_NO_BS_TO_READ,
|
||||
};
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#ifndef WELS_ERROR_CONCEALMENT_H__
|
||||
#define WELS_ERROR_CONCEALMENT_H__
|
||||
#include "typedefs.h"
|
||||
#include "rec_mb.h"
|
||||
#include "decoder_context.h"
|
||||
|
||||
namespace WelsDec {
|
||||
@@ -48,6 +49,10 @@ void InitErrorCon (PWelsDecoderContext pCtx);
|
||||
void DoErrorConFrameCopy (PWelsDecoderContext pCtx);
|
||||
//Do error concealment using slice copy method
|
||||
void DoErrorConSliceCopy (PWelsDecoderContext pCtx);
|
||||
//Do error concealment using slice MV copy method
|
||||
void DoMbECMvCopy (PWelsDecoderContext pCtx, PPicture pDec, PPicture pRef, int32_t iMbXy, int32_t iMbX, int32_t iMbY, sMCRefMember* pMCRefMem, int32_t iCurrPoc);
|
||||
void GetAvilInfoFromCorrectMb (PWelsDecoderContext pCtx);
|
||||
void DoErrorConSliceMVCopy (PWelsDecoderContext pCtx);
|
||||
//Mark erroneous frame as Ref Pic into DPB
|
||||
int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx);
|
||||
//Judge if EC is needed to current frame
|
||||
|
||||
@@ -69,7 +69,11 @@ int32_t iLeftType;
|
||||
int32_t iTopType;
|
||||
int32_t iLeftTopType;
|
||||
int32_t iRightTopType;
|
||||
} SNeighAvail, *PNeighAvail;
|
||||
|
||||
int8_t iTopCbp;
|
||||
int8_t iLeftCbp;
|
||||
int8_t iDummy[2]; //for align
|
||||
} SWelsNeighAvail, *PWelsNeighAvail;
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ union {
|
||||
} sVclNal;
|
||||
SPrefixNalUnit sPrefixNal;
|
||||
} sNalData;
|
||||
|
||||
unsigned long long uiTimeStamp;
|
||||
} SNalUnit, *PNalUnit;
|
||||
|
||||
///////////////////////////////////ACCESS Unit level///////////////////////////////////
|
||||
|
||||
72
codec/decoder/core/inc/parse_mb_syn_cabac.h
Normal file
72
codec/decoder/core/inc/parse_mb_syn_cabac.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*!
|
||||
* \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 parse_mb_syn_cabac.h
|
||||
*
|
||||
* \brief cabac parse for syntax elements
|
||||
*
|
||||
* \date 10/10/2014 Created
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
#ifndef WELS_PARSE_MB_SYN_CABAC_H__
|
||||
#define WELS_PARSE_MB_SYN_CABAC_H__
|
||||
|
||||
#include "decoder_context.h"
|
||||
#include "cabac_decoder.h"
|
||||
namespace WelsDec {
|
||||
int32_t ParseEndOfSliceCabac (PWelsDecoderContext pCtx, uint32_t& uiBinVal);
|
||||
int32_t ParseSkipFlagCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiSkip);
|
||||
int32_t ParseMBTypeISliceCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiBinVal);
|
||||
int32_t ParseMBTypePSliceCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiBinVal);
|
||||
int32_t ParseSubMBTypeCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiSubMbType);
|
||||
int32_t ParseIntraPredModeLumaCabac (PWelsDecoderContext pCtx, int32_t& iBinVal);
|
||||
int32_t ParseIntraPredModeChromaCabac (PWelsDecoderContext pCtx, uint8_t uiNeighAvail, int32_t& iBinVal);
|
||||
int32_t ParseInterMotionInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int16_t pMotionVector[LIST_A][30][MV_A], int16_t pMvdCache[LIST_A][30][MV_A], int8_t pRefIndex[LIST_A][30]);
|
||||
int32_t ParseRefIdxCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* nzc,
|
||||
int8_t ref_idx[LIST_A][30],
|
||||
int32_t iListIdx, int32_t index, int32_t iActiveRefNum, int32_t b8mode, int8_t& iRefIdxVal);
|
||||
int32_t ParseMvdInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, int8_t pRefIndex[LIST_A][30],
|
||||
int16_t pMvdCache[LIST_A][30][2], int32_t index, int8_t iListIdx, int8_t iMvComp, int16_t& iMvdVal);
|
||||
int32_t ParseCbpInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiBinVal);
|
||||
int32_t ParseDeltaQpCabac (PWelsDecoderContext pCtx, int32_t& iQpDelta);
|
||||
int32_t ParseCbfInfoCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNzcCache, int32_t index, int32_t iResProperty,
|
||||
PWelsDecoderContext pCtx, uint32_t& uiCbpBit);
|
||||
int32_t ParseSignificantMapCabac (int32_t* pSignificantMap, int32_t iResProperty, PWelsDecoderContext pCtx,
|
||||
uint32_t& uiBinVal);
|
||||
int32_t ParseSignificantCoeffCabac (int32_t* significant, int32_t iResProperty, PWelsDecoderContext pCtx);
|
||||
int32_t ParseResidualBlockCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCountCache, SBitStringAux* pBsAux,
|
||||
int32_t index, int32_t iMaxNumCoeff, const uint8_t* pScanTable, int32_t iResProperty, int16_t* sTCoeff, uint8_t uiQp,
|
||||
PWelsDecoderContext pCtx);
|
||||
int32_t ParseIPCMInfoCabac (PWelsDecoderContext pCtx);
|
||||
}
|
||||
//#pragma pack()
|
||||
#endif
|
||||
@@ -49,101 +49,19 @@
|
||||
|
||||
namespace WelsDec {
|
||||
|
||||
#define I16_LUMA_DC 1
|
||||
#define I16_LUMA_AC 2
|
||||
#define LUMA_DC_AC 3
|
||||
#define CHROMA_DC 4
|
||||
#define CHROMA_AC 5
|
||||
|
||||
typedef struct TagReadBitsCache {
|
||||
uint32_t uiCache32Bit;
|
||||
uint8_t uiRemainBits;
|
||||
uint8_t* pBuf;
|
||||
} SReadBitsCache;
|
||||
|
||||
#define SHIFT_BUFFER(pBitsCache) { pBitsCache->pBuf+=2; pBitsCache->uiRemainBits += 16; pBitsCache->uiCache32Bit |= (((pBitsCache->pBuf[2] << 8) | pBitsCache->pBuf[3]) << (32 - pBitsCache->uiRemainBits)); }
|
||||
#define POP_BUFFER(pBitsCache, iCount) { pBitsCache->uiCache32Bit <<= iCount; pBitsCache->uiRemainBits -= iCount; }
|
||||
|
||||
static const uint8_t g_kuiZigzagScan[16] = { //4*4block residual zig-zag scan order
|
||||
0, 1, 4, 8,
|
||||
5, 2, 3, 6,
|
||||
9, 12, 13, 10,
|
||||
7, 11, 14, 15,
|
||||
};
|
||||
|
||||
|
||||
typedef struct TagI16PredInfo {
|
||||
int8_t iPredMode;
|
||||
int8_t iLeftAvail;
|
||||
int8_t iTopAvail;
|
||||
int8_t iLeftTopAvail;
|
||||
} SI16PredInfo;
|
||||
static const SI16PredInfo g_ksI16PredInfo[4] = {
|
||||
{I16_PRED_V, 0, 1, 0},
|
||||
{I16_PRED_H, 1, 0, 0},
|
||||
{ 0, 0, 0, 0},
|
||||
{I16_PRED_P, 1, 1, 1},
|
||||
};
|
||||
|
||||
static const SI16PredInfo g_ksChromaPredInfo[4] = {
|
||||
{ 0, 0, 0, 0},
|
||||
{C_PRED_H, 1, 0, 0},
|
||||
{C_PRED_V, 0, 1, 0},
|
||||
{C_PRED_P, 1, 1, 1},
|
||||
};
|
||||
|
||||
|
||||
typedef struct TagI4PredInfo {
|
||||
int8_t iPredMode;
|
||||
int8_t iLeftAvail;
|
||||
int8_t iTopAvail;
|
||||
int8_t iLeftTopAvail;
|
||||
// int8_t right_top_avail; //when right_top unavailable but top avail, we can pad the right-top with the rightmost pixel of top
|
||||
} SI4PredInfo;
|
||||
static const SI4PredInfo g_ksI4PredInfo[9] = {
|
||||
{ I4_PRED_V, 0, 1, 0},
|
||||
{ I4_PRED_H, 1, 0, 0},
|
||||
{ 0, 0, 0, 0},
|
||||
{I4_PRED_DDL, 0, 1, 0},
|
||||
{I4_PRED_DDR, 1, 1, 1},
|
||||
{ I4_PRED_VR, 1, 1, 1},
|
||||
{ I4_PRED_HD, 1, 1, 1},
|
||||
{ I4_PRED_VL, 0, 1, 0},
|
||||
{ I4_PRED_HU, 1, 0, 0},
|
||||
};
|
||||
|
||||
static const uint8_t g_kuiI16CbpTable[6] = {0, 16, 32, 15, 31, 47}; //reference to JM
|
||||
|
||||
|
||||
typedef struct TagPartMbInfo {
|
||||
MbType iType;
|
||||
int8_t iPartCount; //P_16*16, P_16*8, P_8*16, P_8*8 based on 8*8 block; P_8*4, P_4*8, P_4*4 based on 4*4 block
|
||||
int8_t iPartWidth; //based on 4*4 block
|
||||
} SPartMbInfo;
|
||||
static const SPartMbInfo g_ksInterMbTypeInfo[5] = {
|
||||
{MB_TYPE_16x16, 1, 4},
|
||||
{MB_TYPE_16x8, 2, 4},
|
||||
{MB_TYPE_8x16, 2, 2},
|
||||
{MB_TYPE_8x8, 4, 4},
|
||||
{MB_TYPE_8x8_REF0, 4, 4}, //ref0--ref_idx not present in bit-stream and default as 0
|
||||
};
|
||||
static const SPartMbInfo g_ksInterSubMbTypeInfo[4] = {
|
||||
{SUB_MB_TYPE_8x8, 1, 2},
|
||||
{SUB_MB_TYPE_8x4, 2, 2},
|
||||
{SUB_MB_TYPE_4x8, 2, 1},
|
||||
{SUB_MB_TYPE_4x4, 4, 1},
|
||||
};
|
||||
|
||||
void GetNeighborAvailMbType (PNeighAvail pNeighAvail, PDqLayer pCurLayer);
|
||||
void WelsFillCacheNonZeroCount (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount, PDqLayer pCurLayer);
|
||||
void WelsFillCacheConstrain0Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
void GetNeighborAvailMbType (PWelsNeighAvail pNeighAvail, PDqLayer pCurLayer);
|
||||
void WelsFillCacheNonZeroCount (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, PDqLayer pCurLayer);
|
||||
void WelsFillCacheConstrain0Intra4x4 (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
PDqLayer pCurLayer);
|
||||
void WelsFillCacheConstrain1Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
void WelsFillCacheConstrain1Intra4x4 (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
PDqLayer pCurLayer);
|
||||
void WelsFillCacheInter (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
void WelsFillCacheInterCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int16_t iMvArray[LIST_A][30][MV_A], int16_t iMvdCache[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurLayer);
|
||||
void WelsFillCacheInter (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int16_t iMvArray[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurLayer);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief check iPredMode for intra16x16 eligible or not
|
||||
* \param input : current iPredMode
|
||||
@@ -190,19 +108,7 @@ int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable,
|
||||
PWelsDecoderContext pCtx);
|
||||
|
||||
/*!
|
||||
* \brief parsing intra mode
|
||||
* \param input : current mb, bit-stream
|
||||
* \param output: 0 indicating decoding correctly; -1 means error
|
||||
*/
|
||||
int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPredMode, PBitStringAux pBs,
|
||||
PDqLayer pCurDqLayer);
|
||||
int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPredMode, PBitStringAux pBs,
|
||||
PDqLayer pCurDqLayer);
|
||||
int32_t ParseIntra16x16ModeConstrain0 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer);
|
||||
int32_t ParseIntra16x16ModeConstrain1 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer);
|
||||
|
||||
/*!
|
||||
* \brief parsing inter info (including ref_index and mvd)
|
||||
* \brief parsing inter info (including ref_index and pMvd)
|
||||
* \param input : decoding context, current mb, bit-stream
|
||||
* \param output: 0 indicating decoding correctly; -1 means error
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,9 @@ int32_t iLinesize[4];// linesize of picture planes respectively used currently
|
||||
int32_t iPlanes; // How many planes are introduced due to color space format?
|
||||
// picture information
|
||||
|
||||
/*******************************from EC mv copy****************************/
|
||||
bool bIdrFlag;
|
||||
|
||||
/*******************************from other standard syntax****************************/
|
||||
/*from sps*/
|
||||
int32_t iWidthInPixel; // picture width in pixel
|
||||
@@ -74,6 +77,11 @@ int32_t iLongTermFrameIdx; //id for long term ref pic
|
||||
|
||||
int32_t iSpsId; //against mosaic caused by cross-IDR interval reference.
|
||||
int32_t iPpsId;
|
||||
unsigned long long uiTimeStamp;
|
||||
bool bNewSeqBegin;
|
||||
int32_t iMbEcedNum;
|
||||
int32_t iMbEcedPropNum;
|
||||
int32_t iMbNum;
|
||||
} SPicture, *PPicture; // "Picture" declaration is comflict with Mac system
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
@@ -48,6 +48,27 @@
|
||||
#include "decoder_context.h"
|
||||
|
||||
namespace WelsDec {
|
||||
typedef struct TagMCRefMember {
|
||||
uint8_t* pDstY;
|
||||
uint8_t* pDstU;
|
||||
uint8_t* pDstV;
|
||||
|
||||
uint8_t* pSrcY;
|
||||
uint8_t* pSrcU;
|
||||
uint8_t* pSrcV;
|
||||
|
||||
int32_t iSrcLineLuma;
|
||||
int32_t iSrcLineChroma;
|
||||
|
||||
int32_t iDstLineLuma;
|
||||
int32_t iDstLineChroma;
|
||||
|
||||
int32_t iPicWidth;
|
||||
int32_t iPicHeight;
|
||||
} sMCRefMember;
|
||||
|
||||
void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
|
||||
int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]);
|
||||
|
||||
void WelsFillRecNeededMbInfo (PWelsDecoderContext pCtx, bool bOutput, PDqLayer pCurLayer);
|
||||
|
||||
@@ -63,9 +84,6 @@ int32_t RecChroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLeve
|
||||
|
||||
void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx);
|
||||
|
||||
void FillBufForMc (uint8_t* pBuf, int32_t iBufStride, uint8_t* pSrc, int32_t iSrcStride, int32_t iSrcOffset,
|
||||
int32_t iBlockWidth, int32_t iBlockHeight, int32_t iSrcX, int32_t iSrcY, int32_t iPicWidth, int32_t iPicHeight);
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
#endif //WELS_REC_MB_H__
|
||||
|
||||
@@ -120,6 +120,7 @@ PSps pSps;
|
||||
PPps pPps;
|
||||
int32_t iSpsId;
|
||||
int32_t iPpsId;
|
||||
bool bIdrFlag;
|
||||
|
||||
/*********************got from other layer for efficency if possible*********************/
|
||||
SRefPicListReorderSyn pRefPicListReordering; // Reference picture list reordering syntaxs
|
||||
@@ -145,7 +146,6 @@ typedef struct TagSliceHeaderExt {
|
||||
SSliceHeader sSliceHeader;
|
||||
PSubsetSps pSubsetSps;
|
||||
|
||||
uint32_t uiNumMbsInSlice;
|
||||
uint32_t uiDisableInterLayerDeblockingFilterIdc;
|
||||
int32_t iInterLayerSliceAlphaC0Offset;
|
||||
int32_t iInterLayerSliceBetaOffset;
|
||||
@@ -197,6 +197,7 @@ bool bSliceHeaderExtFlag; // Indicate which slice header is used, avc or ext?
|
||||
/*from lower layer: slice header*/
|
||||
uint8_t eSliceType;
|
||||
uint8_t uiPadding[2];
|
||||
int32_t iLastDeltaQp;
|
||||
} SSlice, *PSlice;
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace WelsDec {
|
||||
extern const uint8_t g_kuiScan8[24];
|
||||
extern const uint8_t g_kuiLumaDcZigzagScan[16];
|
||||
extern const uint8_t g_kuiChromaDcScan[4];
|
||||
extern const uint8_t g_kMbNonZeroCountIdx[24];
|
||||
extern const uint8_t g_kCacheNzcScanIdx[4*4+4+4+3];
|
||||
extern const uint8_t g_kCache26ScanIdx[16];
|
||||
extern const uint8_t g_kCache30ScanIdx[16];
|
||||
extern const uint8_t g_kNonZeroScanIdxC[4];
|
||||
/* Profile IDC */
|
||||
typedef uint8_t ProfileIdc;
|
||||
enum {
|
||||
@@ -118,7 +123,94 @@ typedef int32_t SubMbType;
|
||||
#define IS_I_BL(type) ( (type) == MB_TYPE_INTRA_BL )
|
||||
#define IS_SUB8x8(type) (MB_TYPE_8x8 == (type) || MB_TYPE_8x8_REF0 == (type))
|
||||
|
||||
#define I16_LUMA_DC 1
|
||||
#define I16_LUMA_AC 2
|
||||
#define LUMA_DC_AC 3
|
||||
#define CHROMA_DC 4
|
||||
#define CHROMA_AC 5
|
||||
#define CHROMA_DC_U 6
|
||||
#define CHROMA_DC_V 7
|
||||
#define CHROMA_AC_U 8
|
||||
#define CHROMA_AC_V 9
|
||||
|
||||
typedef struct TagReadBitsCache {
|
||||
uint32_t uiCache32Bit;
|
||||
uint8_t uiRemainBits;
|
||||
uint8_t* pBuf;
|
||||
} SReadBitsCache;
|
||||
|
||||
#define SHIFT_BUFFER(pBitsCache) { pBitsCache->pBuf+=2; pBitsCache->uiRemainBits += 16; pBitsCache->uiCache32Bit |= (((pBitsCache->pBuf[2] << 8) | pBitsCache->pBuf[3]) << (32 - pBitsCache->uiRemainBits)); }
|
||||
#define POP_BUFFER(pBitsCache, iCount) { pBitsCache->uiCache32Bit <<= iCount; pBitsCache->uiRemainBits -= iCount; }
|
||||
|
||||
static const uint8_t g_kuiZigzagScan[16] = { //4*4block residual zig-zag scan order
|
||||
0, 1, 4, 8,
|
||||
5, 2, 3, 6,
|
||||
9, 12, 13, 10,
|
||||
7, 11, 14, 15,
|
||||
};
|
||||
|
||||
|
||||
typedef struct TagI16PredInfo {
|
||||
int8_t iPredMode;
|
||||
int8_t iLeftAvail;
|
||||
int8_t iTopAvail;
|
||||
int8_t iLeftTopAvail;
|
||||
} SI16PredInfo;
|
||||
static const SI16PredInfo g_ksI16PredInfo[4] = {
|
||||
{I16_PRED_V, 0, 1, 0},
|
||||
{I16_PRED_H, 1, 0, 0},
|
||||
{ 0, 0, 0, 0},
|
||||
{I16_PRED_P, 1, 1, 1},
|
||||
};
|
||||
|
||||
static const SI16PredInfo g_ksChromaPredInfo[4] = {
|
||||
{ 0, 0, 0, 0},
|
||||
{C_PRED_H, 1, 0, 0},
|
||||
{C_PRED_V, 0, 1, 0},
|
||||
{C_PRED_P, 1, 1, 1},
|
||||
};
|
||||
|
||||
|
||||
typedef struct TagI4PredInfo {
|
||||
int8_t iPredMode;
|
||||
int8_t iLeftAvail;
|
||||
int8_t iTopAvail;
|
||||
int8_t iLeftTopAvail;
|
||||
// int8_t right_top_avail; //when right_top unavailable but top avail, we can pad the right-top with the rightmost pixel of top
|
||||
} SI4PredInfo;
|
||||
static const SI4PredInfo g_ksI4PredInfo[9] = {
|
||||
{ I4_PRED_V, 0, 1, 0},
|
||||
{ I4_PRED_H, 1, 0, 0},
|
||||
{ 0, 0, 0, 0},
|
||||
{I4_PRED_DDL, 0, 1, 0},
|
||||
{I4_PRED_DDR, 1, 1, 1},
|
||||
{ I4_PRED_VR, 1, 1, 1},
|
||||
{ I4_PRED_HD, 1, 1, 1},
|
||||
{ I4_PRED_VL, 0, 1, 0},
|
||||
{ I4_PRED_HU, 1, 0, 0},
|
||||
};
|
||||
|
||||
static const uint8_t g_kuiI16CbpTable[6] = {0, 16, 32, 15, 31, 47};
|
||||
|
||||
|
||||
typedef struct TagPartMbInfo {
|
||||
MbType iType;
|
||||
int8_t iPartCount; //P_16*16, P_16*8, P_8*16, P_8*8 based on 8*8 block; P_8*4, P_4*8, P_4*4 based on 4*4 block
|
||||
int8_t iPartWidth; //based on 4*4 block
|
||||
} SPartMbInfo;
|
||||
static const SPartMbInfo g_ksInterMbTypeInfo[5] = {
|
||||
{MB_TYPE_16x16, 1, 4},
|
||||
{MB_TYPE_16x8, 2, 4},
|
||||
{MB_TYPE_8x16, 2, 2},
|
||||
{MB_TYPE_8x8, 4, 4},
|
||||
{MB_TYPE_8x8_REF0, 4, 4}, //ref0--ref_idx not present in bit-stream and default as 0
|
||||
};
|
||||
static const SPartMbInfo g_ksInterSubMbTypeInfo[4] = {
|
||||
{SUB_MB_TYPE_8x8, 1, 2},
|
||||
{SUB_MB_TYPE_8x4, 2, 2},
|
||||
{SUB_MB_TYPE_4x8, 2, 1},
|
||||
{SUB_MB_TYPE_4x4, 4, 1},
|
||||
};
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
|
||||
@@ -96,4 +96,10 @@
|
||||
#define MAX_ACCESS_UNIT_CAPACITY 7077888 //Maximum AU size in bytes for level 5.2 for single frame
|
||||
#define MAX_MACROBLOCK_CAPACITY 5000 //Maximal legal MB capacity, 15000 bits is enough
|
||||
|
||||
enum {
|
||||
BASE_MB = 0,
|
||||
NON_AVC_REWRITE_ENHANCE_MB =1,
|
||||
AVC_REWRITE_ENHANCE_MB = 2
|
||||
};
|
||||
|
||||
#endif//WELS_CONSTANCE_H__
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
#include "error_code.h"
|
||||
#include "memmgr_nal_unit.h"
|
||||
#include "decoder_core.h"
|
||||
#include "decoder_core.h"
|
||||
#include "bit_stream.h"
|
||||
#include "mem_align.h"
|
||||
|
||||
namespace WelsDec {
|
||||
/*!
|
||||
@@ -111,6 +112,7 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
bool bExtensionFlag = false;
|
||||
int32_t iErr = ERR_NONE;
|
||||
int32_t iBitSize = 0;
|
||||
SDataBuffer* pSavedData = &pCtx->sSavedData;
|
||||
SLogContext* pLogCtx = & (pCtx->sLogCtx);
|
||||
pNalUnitHeader->eNalUnitType = NAL_UNIT_UNSPEC_0;//SHOULD init it. because pCtx->sCurNalHead is common variable.
|
||||
|
||||
@@ -185,6 +187,7 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
|
||||
case NAL_UNIT_PREFIX:
|
||||
pCurNal = &pCtx->sPrefixNal;
|
||||
pCurNal->uiTimeStamp = pCtx->uiTimeStamp;
|
||||
|
||||
if (iNalSize < NAL_UNIT_HEADER_EXT_SIZE) {
|
||||
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
||||
@@ -227,14 +230,18 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
pCurNal->sNalHeaderExt.sNalUnitHeader.uiForbiddenZeroBit = pNalUnitHeader->uiForbiddenZeroBit;
|
||||
pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc = pNalUnitHeader->uiNalRefIdc;
|
||||
pCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType = pNalUnitHeader->eNalUnitType;
|
||||
if (pNalUnitHeader->uiNalRefIdc != 0) {
|
||||
pBs = &pCtx->sBs;
|
||||
iBitSize = (iNalSize << 3) - BsGetTrailingBits (pNal + iNalSize - 1); // convert into bit
|
||||
|
||||
pBs = &pCtx->sBs;
|
||||
|
||||
iBitSize = (iNalSize << 3) - BsGetTrailingBits (pNal + iNalSize - 1); // convert into bit
|
||||
|
||||
InitBits (pBs, pNal, iBitSize);
|
||||
|
||||
ParsePrefixNalUnit (pCtx, pBs);
|
||||
iErr = InitBits (pBs, pNal, iBitSize);
|
||||
if (iErr) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "NAL_UNIT_PREFIX: InitBits() fail due invalid access.");
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return NULL;
|
||||
}
|
||||
ParsePrefixNalUnit (pCtx, pBs);
|
||||
}
|
||||
pCurNal->sNalData.sPrefixNal.bPrefixNalCorrectFlag = true;
|
||||
|
||||
break;
|
||||
@@ -250,7 +257,7 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
pCtx->iErrorCode |= dsOutOfMemory;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pCurNal->uiTimeStamp = pCtx->uiTimeStamp;
|
||||
pCurNal->sNalHeaderExt.sNalUnitHeader.uiForbiddenZeroBit = pNalUnitHeader->uiForbiddenZeroBit;
|
||||
pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc = pNalUnitHeader->uiNalRefIdc;
|
||||
pCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType = pNalUnitHeader->eNalUnitType;
|
||||
@@ -264,7 +271,9 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
|
||||
if (uiAvailNalNum > 1) {
|
||||
pCurAu->uiEndPos = uiAvailNalNum - 2;
|
||||
pCtx->bAuReadyFlag = true;
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
pCtx->bAuReadyFlag = true;
|
||||
}
|
||||
}
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return NULL;
|
||||
@@ -284,7 +293,9 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
|
||||
if (uiAvailNalNum > 1) {
|
||||
pCurAu->uiEndPos = uiAvailNalNum - 2;
|
||||
pCtx->bAuReadyFlag = true;
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
pCtx->bAuReadyFlag = true;
|
||||
}
|
||||
}
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return NULL;
|
||||
@@ -293,9 +304,28 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
iNalSize -= NAL_UNIT_HEADER_EXT_SIZE;
|
||||
*pConsumedBytes += NAL_UNIT_HEADER_EXT_SIZE;
|
||||
|
||||
if (pCtx->bParseOnly) {
|
||||
pCurNal->sNalData.sVclNal.pNalPos = pSavedData->pCurPos;
|
||||
pCurNal->sNalData.sVclNal.iNalLength = iSrcNalLen - NAL_UNIT_HEADER_EXT_SIZE;
|
||||
if (pCurNal->sNalHeaderExt.bIdrFlag) {
|
||||
* (pSrcNal + 3) &= 0xE0;
|
||||
* (pSrcNal + 3) |= 0x05;
|
||||
} else {
|
||||
* (pSrcNal + 3) &= 0xE0;
|
||||
* (pSrcNal + 3) |= 0x01;
|
||||
}
|
||||
memcpy (pSavedData->pCurPos, pSrcNal, 4);
|
||||
pSavedData->pCurPos += 4;
|
||||
memcpy (pSavedData->pCurPos, pSrcNal + 7, iSrcNalLen - 7);
|
||||
pSavedData->pCurPos += iSrcNalLen - 7;
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
if (pCtx->bParseOnly) {
|
||||
pCurNal->sNalData.sVclNal.pNalPos = pSavedData->pCurPos;
|
||||
pCurNal->sNalData.sVclNal.iNalLength = iSrcNalLen;
|
||||
memcpy (pSavedData->pCurPos, pSrcNal, iSrcNalLen);
|
||||
pSavedData->pCurPos += iSrcNalLen;
|
||||
}
|
||||
if (NAL_UNIT_PREFIX == pCtx->sPrefixNal.sNalHeaderExt.sNalUnitHeader.eNalUnitType) {
|
||||
if (pCtx->sPrefixNal.sNalData.sPrefixNal.bPrefixNalCorrectFlag) {
|
||||
PrefetchNalHeaderExtSyntax (pCtx, pCurNal, &pCtx->sPrefixNal);
|
||||
@@ -309,7 +339,19 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
|
||||
pBs = &pCurAu->pNalUnitsList[uiAvailNalNum - 1]->sNalData.sVclNal.sSliceBitsRead;
|
||||
iBitSize = (iNalSize << 3) - BsGetTrailingBits (pNal + iNalSize - 1); // convert into bit
|
||||
InitBits (pBs, pNal, iBitSize);
|
||||
iErr = InitBits (pBs, pNal, iBitSize);
|
||||
if (iErr) {
|
||||
ForceClearCurrentNal (pCurAu);
|
||||
if (uiAvailNalNum > 1) {
|
||||
pCurAu->uiEndPos = uiAvailNalNum - 2;
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
pCtx->bAuReadyFlag = true;
|
||||
}
|
||||
}
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "NAL_UNIT_CODED_SLICE: InitBits() fail due invalid access.");
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return NULL;
|
||||
}
|
||||
iErr = ParseSliceHeaderSyntaxs (pCtx, pBs, bExtensionFlag);
|
||||
if (iErr != ERR_NONE) {
|
||||
if ((uiAvailNalNum == 1) && (pCurNal->sNalHeaderExt.bIdrFlag)) { //IDR parse error
|
||||
@@ -321,7 +363,9 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
|
||||
if (uiAvailNalNum > 1) {
|
||||
pCurAu->uiEndPos = uiAvailNalNum - 2;
|
||||
pCtx->bAuReadyFlag = true;
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
pCtx->bAuReadyFlag = true;
|
||||
}
|
||||
}
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return NULL;
|
||||
@@ -379,6 +423,8 @@ bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeade
|
||||
return true;
|
||||
if (pLastSliceHeader->iPpsId != pCurSliceHeader->iPpsId)
|
||||
return true;
|
||||
if (pLastSliceHeader->pSps->iSpsId != pCurSliceHeader->pSps->iSpsId)
|
||||
return true;
|
||||
if (pLastSliceHeader->bFieldPicFlag != pCurSliceHeader->bFieldPicFlag)
|
||||
return true;
|
||||
if (pLastSliceHeader->bBottomFiledFlag != pCurSliceHeader->bBottomFiledFlag)
|
||||
@@ -403,7 +449,10 @@ bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeade
|
||||
if (pLastSliceHeader->iDeltaPicOrderCnt[1] != pCurSliceHeader->iDeltaPicOrderCnt[1])
|
||||
return true;
|
||||
}
|
||||
|
||||
if(memcmp(pLastSliceHeader->pPps, pCurSliceHeader->pPps, sizeof(SPps)) != 0
|
||||
|| memcmp(pLastSliceHeader->pSps, pCurSliceHeader->pSps, sizeof(SSps)) != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -488,7 +537,8 @@ bool CheckNextAuNewSeq (PWelsDecoderContext pCtx, const PNalUnit kpCurNal, const
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t kiSrcLen) {
|
||||
int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t kiSrcLen, uint8_t* pSrcNal,
|
||||
const int32_t kSrcNalLen) {
|
||||
PBitStringAux pBs = NULL;
|
||||
EWelsNalUnitType eNalType = NAL_UNIT_UNSPEC_0; // make initial value as unspecified
|
||||
int32_t iPicWidth = 0;
|
||||
@@ -505,9 +555,17 @@ int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t
|
||||
switch (eNalType) {
|
||||
case NAL_UNIT_SPS:
|
||||
case NAL_UNIT_SUBSET_SPS:
|
||||
if (iBitSize > 0)
|
||||
InitBits (pBs, pRbsp, iBitSize);
|
||||
iErr = ParseSps (pCtx, pBs, &iPicWidth, &iPicHeight);
|
||||
if (iBitSize > 0) {
|
||||
iErr = InitBits (pBs, pRbsp, iBitSize);
|
||||
if (ERR_NONE != iErr) {
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE)
|
||||
pCtx->iErrorCode |= dsNoParamSets;
|
||||
else
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return iErr;
|
||||
}
|
||||
}
|
||||
iErr = ParseSps (pCtx, pBs, &iPicWidth, &iPicHeight, pSrcNal, kSrcNalLen);
|
||||
if (ERR_NONE != iErr) { // modified for pSps/pSubsetSps invalid, 12/1/2009
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE)
|
||||
pCtx->iErrorCode |= dsNoParamSets;
|
||||
@@ -519,9 +577,17 @@ int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t
|
||||
break;
|
||||
|
||||
case NAL_UNIT_PPS:
|
||||
if (iBitSize > 0)
|
||||
InitBits (pBs, pRbsp, iBitSize);
|
||||
iErr = ParsePps (pCtx, &pCtx->sPpsBuffer[0], pBs);
|
||||
if (iBitSize > 0) {
|
||||
iErr = InitBits (pBs, pRbsp, iBitSize);
|
||||
if (ERR_NONE != iErr) {
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE)
|
||||
pCtx->iErrorCode |= dsNoParamSets;
|
||||
else
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return iErr;
|
||||
}
|
||||
}
|
||||
iErr = ParsePps (pCtx, &pCtx->sPpsBuffer[0], pBs, pSrcNal, kSrcNalLen);
|
||||
if (ERR_NONE != iErr) { // modified for pps invalid, 12/1/2009
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE)
|
||||
pCtx->iErrorCode |= dsNoParamSets;
|
||||
@@ -690,6 +756,8 @@ int32_t DecodeSpsSvcExt (PWelsDecoderContext pCtx, PSubsetSps pSpsExt, PBitStrin
|
||||
|
||||
const SLevelLimits* GetLevelLimits (int32_t iLevelIdx, bool bConstraint3) {
|
||||
switch (iLevelIdx) {
|
||||
case 9:
|
||||
return &g_ksLevelLimits[1];
|
||||
case 10:
|
||||
return &g_ksLevelLimits[0];
|
||||
case 11:
|
||||
@@ -731,11 +799,29 @@ const SLevelLimits* GetLevelLimits (int32_t iLevelIdx, bool bConstraint3) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CheckSpsActive (PWelsDecoderContext pCtx, PSps pSps) {
|
||||
bool CheckSpsActive (PWelsDecoderContext pCtx, PSps pSps, bool bUseSubsetFlag) {
|
||||
for (int i = 0; i < MAX_LAYER_NUM; i++) {
|
||||
if (pCtx->pActiveLayerSps[i] == pSps)
|
||||
return true;
|
||||
}
|
||||
// Pre-active, will be used soon
|
||||
if (bUseSubsetFlag) {
|
||||
if (pSps->iMbWidth > 0 && pSps->iMbHeight > 0 && pCtx->bSubspsAvailFlags[pSps->iSpsId]
|
||||
&& pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
|
||||
PSps pNextUsedSps =
|
||||
pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
|
||||
if (pNextUsedSps->iSpsId == pSps->iSpsId)
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (pSps->iMbWidth > 0 && pSps->iMbHeight > 0 && pCtx->bSpsAvailFlags[pSps->iSpsId]
|
||||
&& pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
|
||||
PSps pNextUsedSps =
|
||||
pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
|
||||
if (pNextUsedSps->iSpsId == pSps->iSpsId)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -764,7 +850,8 @@ bool CheckSpsActive (PWelsDecoderContext pCtx, PSps pSps) {
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight) {
|
||||
int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicWidth, int32_t* pPicHeight,
|
||||
uint8_t* pSrcNal, const int32_t kSrcNalLen) {
|
||||
PBitStringAux pBs = pBsAux;
|
||||
SSubsetSps sTempSubsetSps;
|
||||
PSps pSps = NULL;
|
||||
@@ -964,6 +1051,79 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //vui_parameters_present_flag
|
||||
pSps->bVuiParamPresentFlag = !!uiCode;
|
||||
|
||||
if (pCtx->bParseOnly) {
|
||||
if (kSrcNalLen >= SPS_PPS_BS_SIZE - 4) { //sps bs exceeds!
|
||||
pCtx->iErrorCode |= dsOutOfMemory;
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_OUT_OF_MEMORY);
|
||||
}
|
||||
if (!kbUseSubsetFlag) { //SPS
|
||||
SSpsBsInfo* pSpsBs = &pCtx->sSpsBsInfo [iSpsId];
|
||||
pSpsBs->iSpsId = iSpsId;
|
||||
memcpy (pSpsBs->pSpsBsBuf, pSrcNal, kSrcNalLen);
|
||||
pSpsBs->uiSpsBsLen = (uint32_t) kSrcNalLen;
|
||||
} else { //subset SPS
|
||||
SSpsBsInfo* pSpsBs = &pCtx->sSubsetSpsBsInfo [iSpsId];
|
||||
pSpsBs->iSpsId = iSpsId;
|
||||
pSpsBs->pSpsBsBuf [0] = pSpsBs->pSpsBsBuf [1] = pSpsBs->pSpsBsBuf [2] = 0x00;
|
||||
pSpsBs->pSpsBsBuf [3] = 0x01;
|
||||
pSpsBs->pSpsBsBuf [4] = 0x67;
|
||||
|
||||
//re-write subset SPS to SPS
|
||||
SBitStringAux sSubsetSpsBs;
|
||||
uint8_t* pBsBuf = static_cast<uint8_t*> (WelsMalloc (SPS_PPS_BS_SIZE + 4,
|
||||
"Temp buffer for parse only usage.")); //to reserve 4 bytes for UVLC writing buffer
|
||||
if (NULL == pBsBuf) {
|
||||
pCtx->iErrorCode |= dsOutOfMemory;
|
||||
return pCtx->iErrorCode;
|
||||
}
|
||||
DecInitBitsForEncoding (&sSubsetSpsBs, pBsBuf, (int32_t) (pBs->pEndBuf - pBs->pStartBuf));
|
||||
DecBsWriteBits (&sSubsetSpsBs, 8, 77); //profile_idc, forced to Main profile
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bConstraintSet0Flag); // constraint_set0_flag
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bConstraintSet1Flag); // constraint_set1_flag
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bConstraintSet2Flag); // constraint_set2_flag
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bConstraintSet3Flag); // constraint_set3_flag
|
||||
DecBsWriteBits (&sSubsetSpsBs, 4, 0); //constraint_set4_flag, constraint_set5_flag, reserved_zero_2bits
|
||||
DecBsWriteBits (&sSubsetSpsBs, 8, pSps->uiLevelIdc); //level_idc
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->iSpsId); //sps_id
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->uiLog2MaxFrameNum - 4); //log2_max_frame_num_minus4
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->uiPocType); //pic_order_cnt_type
|
||||
if (pSps->uiPocType == 0) {
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->iLog2MaxPocLsb - 4); //log2_max_pic_order_cnt_lsb_minus4
|
||||
} else if (pSps->uiPocType == 1) {
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bDeltaPicOrderAlwaysZeroFlag); //delta_pic_order_always_zero_flag
|
||||
DecBsWriteSe (&sSubsetSpsBs, pSps->iOffsetForNonRefPic); //offset_for_no_ref_pic
|
||||
DecBsWriteSe (&sSubsetSpsBs, pSps->iOffsetForTopToBottomField); //offset_for_top_to_bottom_field
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->iNumRefFramesInPocCycle); //num_ref_frames_in_pic_order_cnt_cycle
|
||||
for (int32_t i = 0; i < pSps->iNumRefFramesInPocCycle; ++i) {
|
||||
DecBsWriteSe (&sSubsetSpsBs, pSps->iOffsetForRefFrame[i]); //offset_for_ref_frame[i]
|
||||
}
|
||||
}
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->iNumRefFrames); //max_num_ref_frames
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bGapsInFrameNumValueAllowedFlag); //gaps_in_frame_num_value_allowed_flag
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->iMbWidth - 1); //pic_width_in_mbs_minus1
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->iMbHeight - 1); //pic_height_in_map_units_minus1
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bFrameMbsOnlyFlag); //frame_mbs_only_flag
|
||||
if (!pSps->bFrameMbsOnlyFlag) {
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bMbaffFlag); //mb_adaptive_frame_field_flag
|
||||
}
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bDirect8x8InferenceFlag); //direct_8x8_inference_flag
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, pSps->bFrameCroppingFlag); //frame_cropping_flag
|
||||
if (pSps->bFrameCroppingFlag) {
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->sFrameCrop.iLeftOffset); //frame_crop_left_offset
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->sFrameCrop.iRightOffset); //frame_crop_right_offset
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->sFrameCrop.iTopOffset); //frame_crop_top_offset
|
||||
DecBsWriteUe (&sSubsetSpsBs, pSps->sFrameCrop.iBottomOffset); //frame_crop_bottom_offset
|
||||
}
|
||||
DecBsWriteOneBit (&sSubsetSpsBs, 0); //vui_parameters_present_flag
|
||||
DecBsRbspTrailingBits (&sSubsetSpsBs); //finished, rbsp trailing bit
|
||||
int32_t iRbspSize = (int32_t) (sSubsetSpsBs.pCurBuf - sSubsetSpsBs.pStartBuf);
|
||||
RBSP2EBSP (pSpsBs->pSpsBsBuf + 5, sSubsetSpsBs.pStartBuf, iRbspSize);
|
||||
pSpsBs->uiSpsBsLen = (uint16_t) (sSubsetSpsBs.pCurBuf - sSubsetSpsBs.pStartBuf + 5);
|
||||
if (pBsBuf) {
|
||||
WelsFree (pBsBuf, "pBsBuf for parse only usage");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if SPS SVC extension applicated
|
||||
if (kbUseSubsetFlag && (PRO_SCALABLE_BASELINE == uiProfileIdc || PRO_SCALABLE_HIGH == uiProfileIdc)) {
|
||||
if (DecodeSpsSvcExt (pCtx, pSubsetSps, pBs) != ERR_NONE) {
|
||||
@@ -990,7 +1150,7 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
} else {
|
||||
pTmpSps = &pCtx->sSpsBuffer[iSpsId];
|
||||
}
|
||||
if (CheckSpsActive (pCtx, pTmpSps)) {
|
||||
if (CheckSpsActive (pCtx, pTmpSps, kbUseSubsetFlag)) {
|
||||
// we are overwriting the active sps, copy a temp buffer
|
||||
if (kbUseSubsetFlag) {
|
||||
if (memcmp (&pCtx->sSubsetSpsBuffer[iSpsId], pSubsetSps, sizeof (SSubsetSps)) != 0) {
|
||||
@@ -1049,7 +1209,8 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
* \note Call it in case eNalUnitType is PPS.
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux) {
|
||||
int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux, uint8_t* pSrcNal,
|
||||
const int32_t kSrcNalLen) {
|
||||
|
||||
PPps pPps = NULL;
|
||||
SPps sTempPps;
|
||||
@@ -1163,6 +1324,16 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
|
||||
memcpy (&pCtx->sPpsBuffer[uiPpsId], pPps, sizeof (SPps));
|
||||
pCtx->bPpsAvailFlags[uiPpsId] = true;
|
||||
}
|
||||
if (pCtx->bParseOnly) {
|
||||
if (kSrcNalLen >= SPS_PPS_BS_SIZE - 4) { //pps bs exceeds
|
||||
pCtx->iErrorCode |= dsOutOfMemory;
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_OUT_OF_MEMORY);
|
||||
}
|
||||
SPpsBsInfo* pPpsBs = &pCtx->sPpsBsInfo [uiPpsId];
|
||||
pPpsBs->iPpsId = (int32_t) uiPpsId;
|
||||
memcpy (pPpsBs->pPpsBsBuf, pSrcNal, kSrcNalLen);
|
||||
pPpsBs->uiPpsBsLen = kSrcNalLen;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
*************************************************************************************
|
||||
*/
|
||||
#include "bit_stream.h"
|
||||
#include "error_code.h"
|
||||
|
||||
namespace WelsDec {
|
||||
|
||||
@@ -47,10 +48,14 @@ inline uint32_t GetValue4Bytes (uint8_t* pDstNal) {
|
||||
return uiValue;
|
||||
}
|
||||
|
||||
void InitReadBits (PBitStringAux pBitString) {
|
||||
int32_t InitReadBits (PBitStringAux pBitString, intX_t iEndOffset) {
|
||||
if (pBitString->pCurBuf >= (pBitString->pEndBuf - iEndOffset)) {
|
||||
return ERR_INFO_INVALID_ACCESS;
|
||||
}
|
||||
pBitString->uiCurBits = GetValue4Bytes (pBitString->pCurBuf);
|
||||
pBitString->pCurBuf += 4;
|
||||
pBitString->iLeftBits = -16;
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -60,23 +65,154 @@ void InitReadBits (PBitStringAux pBitString) {
|
||||
* \param kpBuf bit-stream buffer
|
||||
* \param kiSize size in bits for decoder; size in bytes for encoder
|
||||
*
|
||||
* \return size of buffer data in byte; failed in -1 return
|
||||
* \return 0: success, other: fail
|
||||
*/
|
||||
int32_t InitBits (PBitStringAux pBitString, const uint8_t* kpBuf, const int32_t kiSize) {
|
||||
const int32_t kiSizeBuf = (kiSize + 7) >> 3;
|
||||
uint8_t* pTmp = (uint8_t*)kpBuf;
|
||||
|
||||
if (NULL == pTmp)
|
||||
return -1;
|
||||
return ERR_INFO_INVALID_ACCESS;
|
||||
|
||||
pBitString->pStartBuf = pTmp; // buffer to start position
|
||||
pBitString->pEndBuf = pTmp + kiSizeBuf; // buffer + length
|
||||
pBitString->iBits = kiSize; // count bits of overall bitstreaming inputindex;
|
||||
|
||||
pBitString->pCurBuf = pBitString->pStartBuf;
|
||||
InitReadBits (pBitString);
|
||||
int32_t iErr = InitReadBits (pBitString, 0);
|
||||
if (iErr) {
|
||||
return iErr;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
return kiSizeBuf;
|
||||
//Following for write bs in decoder
|
||||
void DecInitBitsForEncoding (PBitStringAux pBitString, uint8_t* pBuf, const int32_t kiSize) {
|
||||
uint8_t* pPtr = pBuf;
|
||||
pBitString->pStartBuf = pPtr;
|
||||
pBitString->pCurBuf = pPtr;
|
||||
pBitString->pEndBuf = pPtr + kiSize;
|
||||
pBitString->iLeftBits = 32;
|
||||
pBitString->uiCurBits = 0;
|
||||
}
|
||||
|
||||
#define WRITE_BE_32(ptr, val) do { \
|
||||
(ptr)[0] = (val) >> 24; \
|
||||
(ptr)[1] = (val) >> 16; \
|
||||
(ptr)[2] = (val) >> 8; \
|
||||
(ptr)[3] = (val) >> 0; \
|
||||
} while (0);
|
||||
|
||||
int32_t DecBsWriteBits (PBitStringAux pBitString, int32_t iLen, const uint32_t kuiValue) {
|
||||
if (iLen < pBitString->iLeftBits) {
|
||||
pBitString->uiCurBits = (pBitString->uiCurBits << iLen) | kuiValue;
|
||||
pBitString->iLeftBits -= iLen;
|
||||
} else {
|
||||
iLen -= pBitString->iLeftBits;
|
||||
pBitString->uiCurBits = (pBitString->uiCurBits << pBitString->iLeftBits) | (kuiValue >> iLen);
|
||||
WRITE_BE_32 (pBitString->pCurBuf, pBitString->uiCurBits);
|
||||
pBitString->pCurBuf += 4;
|
||||
pBitString->uiCurBits = kuiValue & ((1 << iLen) - 1);
|
||||
pBitString->iLeftBits = 32 - iLen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t DecBsWriteOneBit (PBitStringAux pBitString, const uint32_t kuiValue) {
|
||||
DecBsWriteBits (pBitString, 1, kuiValue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t DecBsFlush (PBitStringAux pBitString) {
|
||||
WRITE_BE_32 (pBitString->pCurBuf, pBitString->uiCurBits << pBitString->iLeftBits);
|
||||
pBitString->pCurBuf += 4 - pBitString->iLeftBits / 8;
|
||||
pBitString->iLeftBits = 32;
|
||||
pBitString->uiCurBits = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint32_t g_kuiDecGolombUELength[256] = {
|
||||
1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, //14
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, //30
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,//46
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,//62
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,//
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
17
|
||||
};
|
||||
|
||||
int32_t DecBsWriteUe (PBitStringAux pBitString, const uint32_t kuiValue) {
|
||||
uint32_t iTmpValue = kuiValue + 1;
|
||||
if (256 > kuiValue) {
|
||||
DecBsWriteBits (pBitString, g_kuiDecGolombUELength[kuiValue], kuiValue + 1);
|
||||
} else {
|
||||
uint32_t n = 0;
|
||||
if (iTmpValue & 0xffff0000) {
|
||||
iTmpValue >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if (iTmpValue & 0xff) {
|
||||
iTmpValue >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
|
||||
//n += (g_kuiDecGolombUELength[iTmpValue] >> 1);
|
||||
|
||||
n += (g_kuiDecGolombUELength[iTmpValue - 1] >> 1);
|
||||
DecBsWriteBits (pBitString, (n << 1) + 1, kuiValue + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t DecBsWriteSe (PBitStringAux pBitString, const int32_t kiValue) {
|
||||
uint32_t iTmpValue;
|
||||
if (0 == kiValue) {
|
||||
DecBsWriteOneBit (pBitString, 1);
|
||||
} else if (0 < kiValue) {
|
||||
iTmpValue = (kiValue << 1) - 1;
|
||||
DecBsWriteUe (pBitString, iTmpValue);
|
||||
} else {
|
||||
iTmpValue = ((-kiValue) << 1);
|
||||
DecBsWriteUe (pBitString, iTmpValue);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t DecBsRbspTrailingBits (PBitStringAux pBitString) {
|
||||
DecBsWriteOneBit (pBitString, 1);
|
||||
DecBsFlush (pBitString);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RBSP2EBSP (uint8_t* pDstBuf, uint8_t* pSrcBuf, const int32_t kiSize) {
|
||||
uint8_t* pSrcPointer = pSrcBuf;
|
||||
uint8_t* pDstPointer = pDstBuf;
|
||||
uint8_t* pSrcEnd = pSrcBuf + kiSize;
|
||||
int32_t iZeroCount = 0;
|
||||
|
||||
while (pSrcPointer < pSrcEnd) {
|
||||
if (iZeroCount == 2 && *pSrcPointer <= 3) {
|
||||
//add the code 0x03
|
||||
*pDstPointer++ = 3;
|
||||
iZeroCount = 0;
|
||||
}
|
||||
if (*pSrcPointer == 0) {
|
||||
++ iZeroCount;
|
||||
} else {
|
||||
iZeroCount = 0;
|
||||
}
|
||||
*pDstPointer++ = *pSrcPointer++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
330
codec/decoder/core/src/cabac_decoder.cpp
Normal file
330
codec/decoder/core/src/cabac_decoder.cpp
Normal file
@@ -0,0 +1,330 @@
|
||||
/*!
|
||||
* \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.
|
||||
*
|
||||
* cabac_decoder.cpp: deals with cabac state transition and related functions
|
||||
*/
|
||||
#include "cabac_decoder.h"
|
||||
namespace WelsDec {
|
||||
static const int16_t g_kMvdBinPos2Ctx [8] = {0, 1, 2, 3, 3, 3, 3, 3};
|
||||
|
||||
void WelsCabacGlobalInit (PWelsDecoderContext pCtx) {
|
||||
for (int32_t iModel = 0; iModel < 4; iModel++) {
|
||||
for (int32_t iQp = 0; iQp <= WELS_QP_MAX; iQp++)
|
||||
for (int32_t iIdx = 0; iIdx < WELS_CONTEXT_COUNT; iIdx++) {
|
||||
int32_t m = g_kiCabacGlobalContextIdx[iIdx][iModel][0];
|
||||
int32_t n = g_kiCabacGlobalContextIdx[iIdx][iModel][1];
|
||||
int32_t iPreCtxState = WELS_CLIP3 ((((m * iQp) >> 4) + n), 1, 126);
|
||||
uint8_t uiValMps = 0;
|
||||
uint8_t uiStateIdx = 0;
|
||||
if (iPreCtxState <= 63) {
|
||||
uiStateIdx = 63 - iPreCtxState;
|
||||
uiValMps = 0;
|
||||
} else {
|
||||
uiStateIdx = iPreCtxState - 64;
|
||||
uiValMps = 1;
|
||||
}
|
||||
pCtx->sWelsCabacContexts[iModel][iQp][iIdx].uiState = uiStateIdx;
|
||||
pCtx->sWelsCabacContexts[iModel][iQp][iIdx].uiMPS = uiValMps;
|
||||
}
|
||||
}
|
||||
pCtx->bCabacInited = true;
|
||||
}
|
||||
|
||||
// ------------------- 1. context initialization
|
||||
void WelsCabacContextInit (PWelsDecoderContext pCtx, uint8_t eSliceType, int32_t iCabacInitIdc, int32_t iQp) {
|
||||
int32_t iIdx = pCtx->eSliceType == WelsCommon::I_SLICE ? 0 : iCabacInitIdc + 1;
|
||||
if (!pCtx->bCabacInited) {
|
||||
WelsCabacGlobalInit (pCtx);
|
||||
}
|
||||
memcpy (pCtx->pCabacCtx, pCtx->sWelsCabacContexts[iIdx][iQp],
|
||||
WELS_CONTEXT_COUNT * sizeof (SWelsCabacCtx));
|
||||
}
|
||||
|
||||
// ------------------- 2. decoding Engine initialization
|
||||
int32_t InitCabacDecEngineFromBS (PWelsCabacDecEngine pDecEngine, PBitStringAux pBsAux) {
|
||||
int32_t iRemainingBits = - pBsAux->iLeftBits; //pBsAux->iLeftBits < 0
|
||||
int32_t iRemainingBytes = (iRemainingBits >> 3) + 2; //+2: indicating the pre-read 2 bytes
|
||||
uint8_t* pCurr;
|
||||
|
||||
pCurr = pBsAux->pCurBuf - iRemainingBytes;
|
||||
if(pCurr >= (pBsAux->pEndBuf - 1)) {
|
||||
return ERR_INFO_INVALID_ACCESS;
|
||||
}
|
||||
pDecEngine->uiOffset = ((pCurr[0] << 16) | (pCurr[1] << 8) | pCurr[2]);
|
||||
pDecEngine->uiOffset <<= 16;
|
||||
pDecEngine->uiOffset |= (pCurr[3] << 8) | pCurr[4];
|
||||
pDecEngine->iBitsLeft = 31;
|
||||
pDecEngine->pBuffCurr = pCurr + 5;
|
||||
|
||||
pDecEngine->uiRange = WELS_CABAC_HALF;
|
||||
pDecEngine->pBuffStart = pBsAux->pStartBuf;
|
||||
pDecEngine->pBuffEnd = pBsAux->pEndBuf;
|
||||
pBsAux->iLeftBits = 0;
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
void RestoreCabacDecEngineToBS (PWelsCabacDecEngine pDecEngine, PBitStringAux pBsAux) {
|
||||
//CABAC decoding finished, changing to SBitStringAux
|
||||
pDecEngine->pBuffCurr -= (pDecEngine->iBitsLeft >> 3);
|
||||
pDecEngine->iBitsLeft = 0; //pcm_alignment_zero_bit in CABAC
|
||||
pBsAux->iLeftBits = 0;
|
||||
pBsAux->pStartBuf = pDecEngine->pBuffStart;
|
||||
pBsAux->pCurBuf = pDecEngine->pBuffCurr;
|
||||
pBsAux->uiCurBits = 0;
|
||||
pBsAux->iIndex = 0;
|
||||
}
|
||||
|
||||
// ------------------- 3. actual decoding
|
||||
int32_t Read32BitsCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiValue, int32_t& iNumBitsRead) {
|
||||
intX_t iLeftBytes = pDecEngine->pBuffEnd - pDecEngine->pBuffCurr;
|
||||
iNumBitsRead = 0;
|
||||
uiValue = 0;
|
||||
if (iLeftBytes <= 0) {
|
||||
return ERR_CABAC_NO_BS_TO_READ;
|
||||
}
|
||||
switch (iLeftBytes) {
|
||||
case 3:
|
||||
uiValue = ((pDecEngine->pBuffCurr[0]) << 16 | (pDecEngine->pBuffCurr[1]) << 8 | (pDecEngine->pBuffCurr[2]));
|
||||
pDecEngine->pBuffCurr += 3;
|
||||
iNumBitsRead = 24;
|
||||
break;
|
||||
case 2:
|
||||
uiValue = ((pDecEngine->pBuffCurr[0]) << 8 | (pDecEngine->pBuffCurr[1]));
|
||||
pDecEngine->pBuffCurr += 2;
|
||||
iNumBitsRead = 16;
|
||||
break;
|
||||
case 1:
|
||||
uiValue = pDecEngine->pBuffCurr[0];
|
||||
pDecEngine->pBuffCurr += 1;
|
||||
iNumBitsRead = 8;
|
||||
break;
|
||||
default:
|
||||
uiValue = ((pDecEngine->pBuffCurr[0] << 24) | (pDecEngine->pBuffCurr[1]) << 16 | (pDecEngine->pBuffCurr[2]) << 8 |
|
||||
(pDecEngine->pBuffCurr[3]));
|
||||
pDecEngine->pBuffCurr += 4;
|
||||
iNumBitsRead = 32;
|
||||
break;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t DecodeBinCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t& uiBinVal) {
|
||||
int32_t iErrorInfo = ERR_NONE;
|
||||
uint32_t uiState = pBinCtx->uiState;
|
||||
uiBinVal = pBinCtx->uiMPS;
|
||||
uint64_t uiOffset = pDecEngine->uiOffset;
|
||||
uint64_t uiRange = pDecEngine->uiRange;
|
||||
|
||||
int32_t iRenorm = 1;
|
||||
uint32_t uiRangeLPS = g_kuiCabacRangeLps[uiState][ (uiRange >> 6) & 0x03];
|
||||
uiRange -= uiRangeLPS;
|
||||
if (uiOffset >= (uiRange << pDecEngine->iBitsLeft)) { //LPS
|
||||
uiOffset -= (uiRange << pDecEngine->iBitsLeft);
|
||||
uiBinVal ^= 0x0001;
|
||||
if (!uiState)
|
||||
pBinCtx->uiMPS ^= 0x01;
|
||||
pBinCtx->uiState = g_kuiStateTransTable[uiState][0];
|
||||
iRenorm = g_kRenormTable256[uiRangeLPS];
|
||||
uiRange = (uiRangeLPS << iRenorm);
|
||||
} else { //MPS
|
||||
pBinCtx->uiState = g_kuiStateTransTable[uiState][1];
|
||||
if (uiRange >= WELS_CABAC_QUARTER) {
|
||||
pDecEngine->uiRange = uiRange;
|
||||
return ERR_NONE;
|
||||
} else {
|
||||
uiRange <<= 1;
|
||||
}
|
||||
}
|
||||
//Renorm
|
||||
pDecEngine->uiRange = uiRange;
|
||||
pDecEngine->iBitsLeft -= iRenorm;
|
||||
if (pDecEngine->iBitsLeft > 0) {
|
||||
pDecEngine->uiOffset = uiOffset;
|
||||
return ERR_NONE;
|
||||
}
|
||||
uint32_t uiVal = 0;
|
||||
int32_t iNumBitsRead = 0;
|
||||
iErrorInfo = Read32BitsCabac (pDecEngine, uiVal, iNumBitsRead);
|
||||
pDecEngine->uiOffset = (uiOffset << iNumBitsRead) | uiVal;
|
||||
pDecEngine->iBitsLeft += iNumBitsRead;
|
||||
if (iErrorInfo && pDecEngine->iBitsLeft < 0) {
|
||||
return iErrorInfo;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t DecodeBypassCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiBinVal) {
|
||||
int32_t iErrorInfo = ERR_NONE;
|
||||
int32_t iBitsLeft = pDecEngine->iBitsLeft;
|
||||
uint64_t uiOffset = pDecEngine->uiOffset;
|
||||
uint64_t uiRangeValue;
|
||||
|
||||
|
||||
if (iBitsLeft <= 0) {
|
||||
uint32_t uiVal = 0;
|
||||
int32_t iNumBitsRead = 0;
|
||||
iErrorInfo = Read32BitsCabac (pDecEngine, uiVal, iNumBitsRead);
|
||||
uiOffset = (uiOffset << iNumBitsRead) | uiVal;
|
||||
iBitsLeft = iNumBitsRead;
|
||||
if (iErrorInfo && iBitsLeft == 0) {
|
||||
return iErrorInfo;
|
||||
}
|
||||
}
|
||||
iBitsLeft--;
|
||||
uiRangeValue = (pDecEngine->uiRange << iBitsLeft);
|
||||
if (uiOffset >= uiRangeValue) {
|
||||
pDecEngine->iBitsLeft = iBitsLeft;
|
||||
pDecEngine->uiOffset = uiOffset - uiRangeValue;
|
||||
uiBinVal = 1;
|
||||
return ERR_NONE;
|
||||
}
|
||||
pDecEngine->iBitsLeft = iBitsLeft;
|
||||
pDecEngine->uiOffset = uiOffset;
|
||||
uiBinVal = 0;
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t DecodeTerminateCabac (PWelsCabacDecEngine pDecEngine, uint32_t& uiBinVal) {
|
||||
int32_t iErrorInfo = ERR_NONE;
|
||||
uint64_t uiRange = pDecEngine->uiRange - 2;
|
||||
uint64_t uiOffset = pDecEngine->uiOffset;
|
||||
|
||||
if (uiOffset >= (uiRange << pDecEngine->iBitsLeft)) {
|
||||
uiBinVal = 1;
|
||||
} else {
|
||||
uiBinVal = 0;
|
||||
// Renorm
|
||||
if (uiRange < WELS_CABAC_QUARTER) {
|
||||
int32_t iRenorm = g_kRenormTable256[uiRange];
|
||||
pDecEngine->uiRange = (uiRange << iRenorm);
|
||||
pDecEngine->iBitsLeft -= iRenorm;
|
||||
if (pDecEngine->iBitsLeft < 0) {
|
||||
uint32_t uiVal = 0;
|
||||
int32_t iNumBitsRead = 0;
|
||||
iErrorInfo = Read32BitsCabac (pDecEngine, uiVal, iNumBitsRead);
|
||||
pDecEngine->uiOffset = (pDecEngine->uiOffset << iNumBitsRead) | uiVal;
|
||||
pDecEngine->iBitsLeft += iNumBitsRead;
|
||||
}
|
||||
if (iErrorInfo && pDecEngine->iBitsLeft < 0) {
|
||||
return iErrorInfo;
|
||||
}
|
||||
return ERR_NONE;
|
||||
} else {
|
||||
pDecEngine->uiRange = uiRange;
|
||||
return ERR_NONE;
|
||||
}
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t DecodeUnaryBinCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, int32_t iCtxOffset,
|
||||
uint32_t& uiSymVal) {
|
||||
uiSymVal = 0;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiSymVal));
|
||||
if (uiSymVal == 0) {
|
||||
return ERR_NONE;
|
||||
} else {
|
||||
uint32_t uiCode;
|
||||
pBinCtx += iCtxOffset;
|
||||
uiSymVal = 0;
|
||||
do {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiCode));
|
||||
++uiSymVal;
|
||||
} while (uiCode != 0);
|
||||
return ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t DecodeExpBypassCabac (PWelsCabacDecEngine pDecEngine, int32_t iCount, uint32_t& uiSymVal) {
|
||||
uint32_t uiCode;
|
||||
int32_t iSymTmp = 0;
|
||||
int32_t iSymTmp2 = 0;
|
||||
uiSymVal = 0;
|
||||
do {
|
||||
WELS_READ_VERIFY (DecodeBypassCabac (pDecEngine, uiCode));
|
||||
if (uiCode == 1) {
|
||||
iSymTmp += (1 << iCount);
|
||||
++iCount;
|
||||
}
|
||||
} while (uiCode != 0);
|
||||
|
||||
while (iCount--) {
|
||||
WELS_READ_VERIFY (DecodeBypassCabac (pDecEngine, uiCode));
|
||||
if (uiCode == 1) {
|
||||
iSymTmp2 |= (1 << iCount);
|
||||
}
|
||||
}
|
||||
uiSymVal = (uint32_t) (iSymTmp + iSymTmp2);
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
uint32_t DecodeUEGLevelCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t& uiCode) {
|
||||
uiCode = 0;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiCode));
|
||||
if (uiCode == 0)
|
||||
return ERR_NONE;
|
||||
else {
|
||||
uint32_t uiTmp, uiCount = 1;
|
||||
uiCode = 0;
|
||||
do {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx, uiTmp));
|
||||
++uiCode;
|
||||
++uiCount;
|
||||
} while (uiTmp != 0 && uiCount != 13);
|
||||
|
||||
if (uiTmp != 0) {
|
||||
WELS_READ_VERIFY (DecodeExpBypassCabac (pDecEngine, 0, uiTmp));
|
||||
uiCode += uiTmp + 1;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t DecodeUEGMvCabac (PWelsCabacDecEngine pDecEngine, PWelsCabacCtx pBinCtx, uint32_t iMaxBin, uint32_t& uiCode) {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx + g_kMvdBinPos2Ctx[0], uiCode));
|
||||
if (uiCode == 0)
|
||||
return ERR_NONE;
|
||||
else {
|
||||
uint32_t uiTmp, uiCount = 1;
|
||||
uiCode = 0;
|
||||
do {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pDecEngine, pBinCtx + g_kMvdBinPos2Ctx[uiCount++], uiTmp));
|
||||
uiCode++;
|
||||
} while (uiTmp != 0 && uiCount != 8);
|
||||
|
||||
if (uiTmp != 0) {
|
||||
WELS_READ_VERIFY (DecodeExpBypassCabac (pDecEngine, 3, uiTmp));
|
||||
uiCode += (uiTmp + 1);
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -76,25 +76,168 @@ static int32_t CreatePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, cons
|
||||
pPicBuf->ppPic = (PPicture*)WelsMalloc (kiSize * sizeof (PPicture), "PPicture*");
|
||||
|
||||
if (NULL == pPicBuf->ppPic) {
|
||||
pPicBuf->iCapacity = 0;
|
||||
DestroyPicBuff (&pPicBuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (iPicIdx = 0; iPicIdx < kiSize; ++ iPicIdx) {
|
||||
PPicture pPic = AllocPicture (pCtx, kiPicWidth, kiPicHeight);
|
||||
if (NULL == pPic) {
|
||||
// init capacity first for free memory
|
||||
pPicBuf->iCapacity = iPicIdx;
|
||||
DestroyPicBuff (&pPicBuf);
|
||||
return 1;
|
||||
}
|
||||
pPicBuf->ppPic[iPicIdx] = pPic;
|
||||
}
|
||||
|
||||
// initialize context in queue
|
||||
// initialize context in queue
|
||||
pPicBuf->iCapacity = kiSize;
|
||||
pPicBuf->iCurrentIdx = 0;
|
||||
*ppPicBuf = pPicBuf;
|
||||
* ppPicBuf = pPicBuf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DestroyPicBuff (PPicBuff* ppPicBuf) {
|
||||
static int32_t IncreasePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, const int32_t kiOldSize,
|
||||
const int32_t kiPicWidth, const int32_t kiPicHeight, const int32_t kiNewSize) {
|
||||
PPicBuff pPicOldBuf = *ppPicBuf;
|
||||
PPicBuff pPicNewBuf = NULL;
|
||||
int32_t iPicIdx = 0;
|
||||
if (kiOldSize <= 0 || kiNewSize <= 0 || kiPicWidth <= 0 || kiPicHeight <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pPicNewBuf = (PPicBuff)WelsMalloc (sizeof (SPicBuff), "PPicBuff");
|
||||
|
||||
if (NULL == pPicNewBuf) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pPicNewBuf->ppPic = (PPicture*)WelsMalloc (kiNewSize * sizeof (PPicture), "PPicture*");
|
||||
|
||||
if (NULL == pPicNewBuf->ppPic) {
|
||||
pPicNewBuf->iCapacity = 0;
|
||||
DestroyPicBuff (&pPicNewBuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// increase new PicBuf
|
||||
for (iPicIdx = kiOldSize; iPicIdx < kiNewSize; ++ iPicIdx) {
|
||||
PPicture pPic = AllocPicture (pCtx, kiPicWidth, kiPicHeight);
|
||||
if (NULL == pPic) {
|
||||
// Set maximum capacity as the new malloc memory at the tail
|
||||
pPicNewBuf->iCapacity = iPicIdx;
|
||||
DestroyPicBuff (&pPicNewBuf);
|
||||
return 1;
|
||||
}
|
||||
pPicNewBuf->ppPic[iPicIdx] = pPic;
|
||||
}
|
||||
|
||||
// copy old PicBuf to new PicBuf
|
||||
memcpy (pPicNewBuf->ppPic, pPicOldBuf->ppPic, kiOldSize * sizeof (PPicture));
|
||||
|
||||
// initialize context in queue
|
||||
pPicNewBuf->iCapacity = kiNewSize;
|
||||
pPicNewBuf->iCurrentIdx = pPicOldBuf->iCurrentIdx;
|
||||
* ppPicBuf = pPicNewBuf;
|
||||
|
||||
for (int32_t i = 0; i < pPicNewBuf->iCapacity; i++) {
|
||||
pPicNewBuf->ppPic[i]->bUsedAsRef = false;
|
||||
pPicNewBuf->ppPic[i]->bIsLongRef = false;
|
||||
pPicNewBuf->ppPic[i]->uiRefCount = 0;
|
||||
pPicNewBuf->ppPic[i]->bAvailableFlag = true;
|
||||
pPicNewBuf->ppPic[i]->bIsComplete = false;
|
||||
}
|
||||
// remove old PicBuf
|
||||
if (pPicOldBuf->ppPic != NULL) {
|
||||
WelsFree (pPicOldBuf->ppPic, "pPicOldBuf->queue");
|
||||
pPicOldBuf->ppPic = NULL;
|
||||
}
|
||||
pPicOldBuf->iCapacity = 0;
|
||||
pPicOldBuf->iCurrentIdx = 0;
|
||||
WelsFree (pPicOldBuf, "pPicOldBuf");
|
||||
pPicOldBuf = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t DecreasePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, const int32_t kiOldSize,
|
||||
const int32_t kiPicWidth, const int32_t kiPicHeight, const int32_t kiNewSize) {
|
||||
PPicBuff pPicOldBuf = *ppPicBuf;
|
||||
PPicBuff pPicNewBuf = NULL;
|
||||
int32_t iPicIdx = 0;
|
||||
if (kiOldSize <= 0 || kiNewSize <= 0 || kiPicWidth <= 0 || kiPicHeight <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pPicNewBuf = (PPicBuff)WelsMalloc (sizeof (SPicBuff), "PPicBuff");
|
||||
|
||||
if (NULL == pPicNewBuf) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pPicNewBuf->ppPic = (PPicture*)WelsMalloc (kiNewSize * sizeof (PPicture), "PPicture*");
|
||||
|
||||
if (NULL == pPicNewBuf->ppPic) {
|
||||
pPicNewBuf->iCapacity = 0;
|
||||
DestroyPicBuff (&pPicNewBuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t iPrevPicIdx = -1;
|
||||
for (iPrevPicIdx = 0; iPrevPicIdx < kiOldSize; ++iPrevPicIdx) {
|
||||
if (pCtx->pPreviousDecodedPictureInDpb == pPicOldBuf->ppPic[iPrevPicIdx]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int32_t iDelIdx;
|
||||
if (iPrevPicIdx < kiOldSize && iPrevPicIdx >= kiNewSize) {
|
||||
// found pPreviousDecodedPictureInDpb,
|
||||
pPicNewBuf->ppPic[0] = pPicOldBuf->ppPic[iPrevPicIdx];
|
||||
pPicNewBuf->iCurrentIdx = 0;
|
||||
memcpy (pPicNewBuf->ppPic + 1, pPicOldBuf->ppPic, (kiNewSize - 1) * sizeof (PPicture));
|
||||
iDelIdx = kiNewSize - 1;
|
||||
} else {
|
||||
memcpy (pPicNewBuf->ppPic, pPicOldBuf->ppPic, kiNewSize * sizeof (PPicture));
|
||||
pPicNewBuf->iCurrentIdx = iPrevPicIdx < kiNewSize ? iPrevPicIdx : 0;
|
||||
iDelIdx = kiNewSize;
|
||||
}
|
||||
|
||||
for (iPicIdx = iDelIdx; iPicIdx < kiOldSize; iPicIdx++) {
|
||||
if (iPrevPicIdx != iPicIdx) {
|
||||
if (pPicOldBuf->ppPic[iPicIdx] != NULL) {
|
||||
FreePicture (pPicOldBuf->ppPic[iPicIdx]);
|
||||
pPicOldBuf->ppPic[iPicIdx] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// initialize context in queue
|
||||
pPicNewBuf->iCapacity = kiNewSize;
|
||||
*ppPicBuf = pPicNewBuf;
|
||||
|
||||
for (int32_t i = 0; i < pPicNewBuf->iCapacity; i++) {
|
||||
pPicNewBuf->ppPic[i]->bUsedAsRef = false;
|
||||
pPicNewBuf->ppPic[i]->bIsLongRef = false;
|
||||
pPicNewBuf->ppPic[i]->uiRefCount = 0;
|
||||
pPicNewBuf->ppPic[i]->bAvailableFlag = true;
|
||||
pPicNewBuf->ppPic[i]->bIsComplete = false;
|
||||
}
|
||||
// remove old PicBuf
|
||||
if (pPicOldBuf->ppPic != NULL) {
|
||||
WelsFree (pPicOldBuf->ppPic, "pPicOldBuf->queue");
|
||||
pPicOldBuf->ppPic = NULL;
|
||||
}
|
||||
pPicOldBuf->iCapacity = 0;
|
||||
pPicOldBuf->iCurrentIdx = 0;
|
||||
WelsFree (pPicOldBuf, "pPicOldBuf");
|
||||
pPicOldBuf = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DestroyPicBuff (PPicBuff* ppPicBuf) {
|
||||
PPicBuff pPicBuf = NULL;
|
||||
|
||||
if (NULL == ppPicBuf || NULL == *ppPicBuf)
|
||||
@@ -139,12 +282,15 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
||||
pCtx->uiCpuFlag = 0;
|
||||
|
||||
pCtx->bAuReadyFlag = 0; // au data is not ready
|
||||
|
||||
pCtx->bCabacInited = false;
|
||||
|
||||
pCtx->uiCpuFlag = WelsCPUFeatureDetect (&iCpuCores);
|
||||
|
||||
pCtx->iImgWidthInPixel = 0;
|
||||
pCtx->iImgHeightInPixel = 0; // alloc picture data when picture size is available
|
||||
pCtx->iLastImgWidthInPixel = 0;
|
||||
pCtx->iLastImgHeightInPixel = 0;
|
||||
pCtx->bFreezeOutput = true;
|
||||
|
||||
pCtx->iFrameNum = -1;
|
||||
pCtx->iPrevFrameNum = -1;
|
||||
@@ -160,8 +306,9 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
||||
pCtx->pPicBuff[LIST_1] = NULL;
|
||||
|
||||
pCtx->bAvcBasedFlag = true;
|
||||
pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY;
|
||||
pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
|
||||
pCtx->pPreviousDecodedPictureInDpb = NULL;
|
||||
pCtx->sDecoderStatistics.iAvgLumaQp = -1;
|
||||
|
||||
}
|
||||
|
||||
@@ -175,10 +322,11 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
||||
*/
|
||||
static inline int32_t GetTargetRefListSize (PWelsDecoderContext pCtx) {
|
||||
int32_t iNumRefFrames = 0;
|
||||
// +2 for EC MV Copy buffer exchange
|
||||
if ((pCtx == NULL) || (pCtx->pSps == NULL)) {
|
||||
iNumRefFrames = MAX_REF_PIC_COUNT;
|
||||
iNumRefFrames = MAX_REF_PIC_COUNT + 2;
|
||||
} else {
|
||||
iNumRefFrames = pCtx->pSps->iNumRefFrames + 1;
|
||||
iNumRefFrames = pCtx->pSps->iNumRefFrames + 2;
|
||||
}
|
||||
|
||||
#ifdef LONG_TERM_REF
|
||||
@@ -220,18 +368,42 @@ int32_t WelsRequestMem (PWelsDecoderContext pCtx, const int32_t kiMbWidth, const
|
||||
// sync update pRefList
|
||||
WelsResetRefPic (pCtx); // added to sync update ref list due to pictures are free
|
||||
|
||||
// for Recycled_Pic_Queue
|
||||
for (iListIdx = LIST_0; iListIdx < LIST_A; ++ iListIdx) {
|
||||
PPicBuff* ppPic = &pCtx->pPicBuff[iListIdx];
|
||||
if (NULL != ppPic && NULL != *ppPic) {
|
||||
DestroyPicBuff (ppPic);
|
||||
if (pCtx->bHaveGotMemory && (kiPicWidth == pCtx->iImgWidthInPixel && kiPicHeight == pCtx->iImgHeightInPixel)
|
||||
&& pCtx->pPicBuff[LIST_0] != NULL && pCtx->pPicBuff[LIST_0]->iCapacity != iPicQueueSize) {
|
||||
// currently only active for LIST_0 due to have no B frames
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||
"WelsRequestMem(): memory re-alloc for no resolution change (size = %d * %d), ref list size change from %d to %d",
|
||||
kiPicWidth, kiPicHeight, pCtx->pPicBuff[LIST_0]->iCapacity, iPicQueueSize);
|
||||
if (pCtx->pPicBuff[LIST_0]->iCapacity < iPicQueueSize) {
|
||||
iErr = IncreasePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], pCtx->pPicBuff[LIST_0]->iCapacity, kiPicWidth, kiPicHeight,
|
||||
iPicQueueSize);
|
||||
} else {
|
||||
iErr = DecreasePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], pCtx->pPicBuff[LIST_0]->iCapacity, kiPicWidth, kiPicHeight,
|
||||
iPicQueueSize);
|
||||
}
|
||||
} else {
|
||||
if (pCtx->bHaveGotMemory)
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||
"WelsRequestMem(): memory re-alloc for resolution change, size change from %d * %d to %d * %d, ref list size change from %d to %d",
|
||||
pCtx->iImgWidthInPixel, pCtx->iImgHeightInPixel, kiPicWidth, kiPicHeight, pCtx->pPicBuff[LIST_0]->iCapacity,
|
||||
iPicQueueSize);
|
||||
else
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "WelsRequestMem(): memory alloc size = %d * %d, ref list size = %d",
|
||||
kiPicWidth, kiPicHeight, iPicQueueSize);
|
||||
// for Recycled_Pic_Queue
|
||||
for (iListIdx = LIST_0; iListIdx < LIST_A; ++ iListIdx) {
|
||||
PPicBuff* ppPic = &pCtx->pPicBuff[iListIdx];
|
||||
if (NULL != ppPic && NULL != *ppPic) {
|
||||
DestroyPicBuff (ppPic);
|
||||
}
|
||||
}
|
||||
|
||||
pCtx->pPreviousDecodedPictureInDpb = NULL;
|
||||
|
||||
// currently only active for LIST_0 due to have no B frames
|
||||
iErr = CreatePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], iPicQueueSize, kiPicWidth, kiPicHeight);
|
||||
}
|
||||
|
||||
pCtx->pPreviousDecodedPictureInDpb = NULL;
|
||||
|
||||
// currently only active for LIST_0 due to have no B frames
|
||||
iErr = CreatePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], iPicQueueSize, kiPicWidth, kiPicHeight);
|
||||
if (iErr != ERR_NONE)
|
||||
return iErr;
|
||||
|
||||
@@ -241,6 +413,10 @@ int32_t WelsRequestMem (PWelsDecoderContext pCtx, const int32_t kiMbWidth, const
|
||||
|
||||
pCtx->bHaveGotMemory = true; // global memory for decoder context related is requested
|
||||
pCtx->pDec = NULL; // need prefetch a new pic due to spatial size changed
|
||||
|
||||
if (pCtx->pCabacDecEngine == NULL)
|
||||
pCtx->pCabacDecEngine = (SWelsCabacDecEngine*) WelsMalloc (sizeof (SWelsCabacDecEngine), "pCtx->pCabacDecEngine");
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -266,8 +442,11 @@ void WelsFreeMem (PWelsDecoderContext pCtx) {
|
||||
// added for safe memory
|
||||
pCtx->iImgWidthInPixel = 0;
|
||||
pCtx->iImgHeightInPixel = 0;
|
||||
pCtx->iLastImgWidthInPixel = 0;
|
||||
pCtx->iLastImgHeightInPixel = 0;
|
||||
pCtx->bFreezeOutput = true;
|
||||
pCtx->bHaveGotMemory = false;
|
||||
|
||||
WelsFree (pCtx->pCabacDecEngine, "pCtx->pCabacDecEngine");
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -340,6 +519,9 @@ int32_t DecoderConfigParam (PWelsDecoderContext pCtx, const SDecodingParam* kpPa
|
||||
return iRet;
|
||||
pCtx->eErrorConMethod = pCtx->pParam->eEcActiveIdc;
|
||||
|
||||
if (pCtx->bParseOnly) //parse only, disable EC method
|
||||
pCtx->eErrorConMethod = ERROR_CON_DISABLE;
|
||||
|
||||
if (VIDEO_BITSTREAM_SVC == pCtx->pParam->sVideoProperty.eVideoBsType ||
|
||||
VIDEO_BITSTREAM_AVC == pCtx->pParam->sVideoProperty.eVideoBsType) {
|
||||
pCtx->eVideoType = pCtx->pParam->sVideoProperty.eVideoBsType;
|
||||
@@ -364,7 +546,7 @@ int32_t DecoderConfigParam (PWelsDecoderContext pCtx, const SDecodingParam* kpPa
|
||||
* \note N/A
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t WelsInitDecoder (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
||||
int32_t WelsInitDecoder (PWelsDecoderContext pCtx, const bool bParseOnly, SLogContext* pLogCtx) {
|
||||
if (pCtx == NULL) {
|
||||
return ERR_INFO_INVALID_PTR;
|
||||
}
|
||||
@@ -372,6 +554,7 @@ int32_t WelsInitDecoder (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
|
||||
// default
|
||||
WelsDecoderDefaults (pCtx, pLogCtx);
|
||||
|
||||
pCtx->bParseOnly = bParseOnly;
|
||||
// open decoder
|
||||
return WelsOpenDecoder (pCtx);
|
||||
}
|
||||
@@ -417,9 +600,10 @@ void GetVclNalTemporalId (PWelsDecoderContext pCtx) {
|
||||
*************************************************************************************
|
||||
*/
|
||||
int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const int32_t kiBsLen,
|
||||
uint8_t** ppDst, SBufferInfo* pDstBufInfo) {
|
||||
uint8_t** ppDst, SBufferInfo* pDstBufInfo, SParserBsInfo* pDstBsInfo) {
|
||||
if (!pCtx->bEndOfStreamFlag) {
|
||||
SDataBuffer* pRawData = &pCtx->sRawData;
|
||||
SDataBuffer* pSavedData = NULL;
|
||||
|
||||
int32_t iSrcIdx = 0; //the index of source bit-stream till now after parsing one or more NALs
|
||||
int32_t iSrcConsumed = 0; // consumed bit count of source bs
|
||||
@@ -447,7 +631,12 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
pRawData->pCurPos = pRawData->pHead;
|
||||
}
|
||||
|
||||
|
||||
if (pCtx->bParseOnly) {
|
||||
pSavedData = &pCtx->sSavedData;
|
||||
if ((kiBsLen + 4) > (pSavedData->pEnd - pSavedData->pCurPos)) {
|
||||
pSavedData->pCurPos = pSavedData->pHead;
|
||||
}
|
||||
}
|
||||
//copy raw data from source buffer (application) to raw data buffer (codec inside)
|
||||
//0x03 removal and extract all of NAL Unit from current raw data
|
||||
pDstNal = pRawData->pCurPos;
|
||||
@@ -464,27 +653,28 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
} else {
|
||||
|
||||
iConsumedBytes = 0;
|
||||
pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] =
|
||||
0; // set 4 reserved bytes to zero
|
||||
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
||||
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);
|
||||
}
|
||||
if (pCtx->bAuReadyFlag) {
|
||||
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||
if (pNalPayload) { //parse correct
|
||||
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
|
||||
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
|
||||
}
|
||||
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
|
||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
|
||||
}
|
||||
if (pCtx->bAuReadyFlag) {
|
||||
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||
|
||||
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
||||
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
||||
#ifdef LONG_TERM_REF
|
||||
pCtx->bParamSetsLostFlag = true;
|
||||
pCtx->bParamSetsLostFlag = true;
|
||||
#else
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
#endif
|
||||
if ((pCtx->eErrorConMethod == ERROR_CON_DISABLE) || (dsOutOfMemory & pCtx->iErrorCode))
|
||||
ResetParameterSetsState (pCtx);
|
||||
|
||||
if (dsOutOfMemory & pCtx->iErrorCode) {
|
||||
return pCtx->iErrorCode;
|
||||
if (dsOutOfMemory & pCtx->iErrorCode) {
|
||||
return pCtx->iErrorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,19 +686,16 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
#else
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
#endif
|
||||
if ((pCtx->eErrorConMethod == ERROR_CON_DISABLE) || (dsOutOfMemory & pCtx->iErrorCode))
|
||||
ResetParameterSetsState (pCtx);
|
||||
}
|
||||
return pCtx->iErrorCode;
|
||||
}
|
||||
|
||||
pDstNal += iDstIdx; //update current position
|
||||
pDstNal += (iDstIdx + 4); //init, increase 4 reserved zero bytes, used to store the next NAL
|
||||
if ((iSrcLength - iSrcConsumed + 4) > (pRawData->pEnd - pDstNal)) {
|
||||
pRawData->pCurPos = pRawData->pHead;
|
||||
pDstNal = pRawData->pCurPos = pRawData->pHead;
|
||||
} else {
|
||||
pRawData->pCurPos = pDstNal;
|
||||
}
|
||||
pDstNal = pRawData->pCurPos + 4; //init, 4 bytes used to store the next NAL
|
||||
|
||||
pSrcNal += iSrcIdx + 3;
|
||||
iSrcConsumed += 3;
|
||||
@@ -524,25 +711,27 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
//last NAL decoding
|
||||
|
||||
iConsumedBytes = 0;
|
||||
pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] =
|
||||
0; // set 4 reserved bytes to zero
|
||||
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
||||
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);
|
||||
}
|
||||
if (pCtx->bAuReadyFlag) {
|
||||
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||
if (pNalPayload) { //parse correct
|
||||
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
|
||||
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
|
||||
}
|
||||
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
|
||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
|
||||
}
|
||||
if (pCtx->bAuReadyFlag) {
|
||||
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||
|
||||
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
||||
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
||||
#ifdef LONG_TERM_REF
|
||||
pCtx->bParamSetsLostFlag = true;
|
||||
pCtx->bParamSetsLostFlag = true;
|
||||
#else
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
#endif
|
||||
if ((pCtx->eErrorConMethod == ERROR_CON_DISABLE) || (dsOutOfMemory & pCtx->iErrorCode))
|
||||
ResetParameterSetsState (pCtx);
|
||||
return pCtx->iErrorCode;
|
||||
return pCtx->iErrorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (iRet) {
|
||||
@@ -553,12 +742,10 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
#else
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
#endif
|
||||
ResetParameterSetsState (pCtx);
|
||||
}
|
||||
return pCtx->iErrorCode;
|
||||
}
|
||||
pDstNal += iDstIdx;
|
||||
pRawData->pCurPos = pDstNal; //init the pCurPos for next NAL(s) storage
|
||||
pRawData->pCurPos = pDstNal + iDstIdx + 4; //init, increase 4 reserved zero bytes, used to store the next NAL
|
||||
} else { /* no supplementary picture payload input, but stored a picture */
|
||||
PAccessUnit pCurAu =
|
||||
pCtx->pAccessUnitList; // current access unit, it will never point to NULL after decode's successful initialization
|
||||
@@ -576,8 +763,6 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
#else
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
#endif
|
||||
if ((pCtx->eErrorConMethod == ERROR_CON_DISABLE) || (dsOutOfMemory & pCtx->iErrorCode))
|
||||
ResetParameterSetsState (pCtx);
|
||||
return pCtx->iErrorCode;
|
||||
}
|
||||
}
|
||||
@@ -765,4 +950,62 @@ void AssignFuncPointerForRec (PWelsDecoderContext pCtx) {
|
||||
WelsBlockFuncInit (&pCtx->sBlockFunc, pCtx->uiCpuFlag);
|
||||
}
|
||||
|
||||
//reset decoder number related statistics info
|
||||
void ResetDecStatNums (SDecoderStatistics* pDecStat) {
|
||||
uint32_t uiWidth = pDecStat->uiWidth;
|
||||
uint32_t uiHeight = pDecStat->uiHeight;
|
||||
int32_t iAvgLumaQp = pDecStat->iAvgLumaQp;
|
||||
memset (pDecStat, 0, sizeof (SDecoderStatistics));
|
||||
pDecStat->uiWidth = uiWidth;
|
||||
pDecStat->uiHeight = uiHeight;
|
||||
pDecStat->iAvgLumaQp = iAvgLumaQp;
|
||||
}
|
||||
|
||||
//update information when freezing occurs, including IDR/non-IDR number
|
||||
void UpdateDecStatFreezingInfo (const bool kbIdrFlag, SDecoderStatistics* pDecStat) {
|
||||
if (kbIdrFlag)
|
||||
pDecStat->uiFreezingIDRNum++;
|
||||
else
|
||||
pDecStat->uiFreezingNonIDRNum++;
|
||||
}
|
||||
|
||||
//update information when no freezing occurs, including QP, correct IDR number, ECed IDR number
|
||||
void UpdateDecStatNoFreezingInfo (PWelsDecoderContext pCtx) {
|
||||
PDqLayer pCurDq = pCtx->pCurDqLayer;
|
||||
PPicture pPic = pCtx->pDec;
|
||||
SDecoderStatistics* pDecStat = &pCtx->sDecoderStatistics;
|
||||
|
||||
if (pDecStat->iAvgLumaQp == -1) //first correct frame received
|
||||
pDecStat->iAvgLumaQp = 0;
|
||||
|
||||
//update QP info
|
||||
int32_t iTotalQp = 0;
|
||||
const int32_t kiMbNum = pCurDq->iMbWidth * pCurDq->iMbHeight;
|
||||
for (int32_t iMb = 0; iMb < kiMbNum; ++iMb) {
|
||||
iTotalQp += pCurDq->pLumaQp[iMb] * pCurDq->pMbCorrectlyDecodedFlag[iMb];
|
||||
}
|
||||
iTotalQp /= kiMbNum;
|
||||
if (pDecStat->uiDecodedFrameCount + 1 == 0) { //maximum uint32_t reached
|
||||
ResetDecStatNums (pDecStat);
|
||||
pDecStat->iAvgLumaQp = iTotalQp;
|
||||
} else
|
||||
pDecStat->iAvgLumaQp = (uint64_t) (pDecStat->iAvgLumaQp * pDecStat->uiDecodedFrameCount + iTotalQp) /
|
||||
(pDecStat->uiDecodedFrameCount + 1);
|
||||
|
||||
//update IDR number
|
||||
if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag) {
|
||||
pDecStat->uiIDRCorrectNum += (pPic->bIsComplete);
|
||||
pDecStat->uiEcIDRNum += (!pPic->bIsComplete);
|
||||
}
|
||||
}
|
||||
|
||||
//update decoder statistics information
|
||||
void UpdateDecStat (PWelsDecoderContext pCtx, const bool kbOutput) {
|
||||
if (pCtx->bFreezeOutput)
|
||||
UpdateDecStatFreezingInfo (pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag, &pCtx->sDecoderStatistics);
|
||||
else if (kbOutput)
|
||||
UpdateDecStatNoFreezingInfo (pCtx);
|
||||
}
|
||||
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include "error_concealment.h"
|
||||
|
||||
namespace WelsDec {
|
||||
|
||||
static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
PDqLayer pCurDq = pCtx->pCurDqLayer;
|
||||
PPicture pPic = pCtx->pDec;
|
||||
@@ -55,7 +54,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight;
|
||||
bool bFrameCompleteFlag = true;
|
||||
|
||||
if (pCtx->bNewSeqBegin) {
|
||||
if (pPic->bNewSeqBegin) {
|
||||
memcpy (& (pCtx->sFrameCrop), & (pCurDq->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.pSps->sFrameCrop),
|
||||
sizeof (SPosOffset)); //confirmed_safe_unsafe_usage
|
||||
#ifdef LONG_TERM_REF
|
||||
@@ -66,7 +65,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
if (pCtx->iTotalNumMbRec == kiTotalNumMbInCurLayer) {
|
||||
pCtx->bPrintFrameErrorTraceFlag = true;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||
"DecodeFrameConstruction()::::output first frame of new sequence, %d x %d, crop_left:%d, crop_right:%d, crop_top:%d, crop_bottom:%d, ignored error packet:%d.",
|
||||
"DecodeFrameConstruction(): will output first frame of new sequence, %d x %d, crop_left:%d, crop_right:%d, crop_top:%d, crop_bottom:%d, ignored error packet:%d.",
|
||||
kiWidth, kiHeight, pCtx->sFrameCrop.iLeftOffset, pCtx->sFrameCrop.iRightOffset, pCtx->sFrameCrop.iTopOffset,
|
||||
pCtx->sFrameCrop.iBottomOffset, pCtx->iIgnoredErrorInfoPacketCount);
|
||||
pCtx->iIgnoredErrorInfoPacketCount = 0;
|
||||
@@ -75,7 +74,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
|
||||
if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ",
|
||||
"DecodeFrameConstruction(): iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ",
|
||||
pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight);
|
||||
bFrameCompleteFlag = false; //return later after output buffer is done
|
||||
if (pCtx->bInstantDecFlag) //no-delay decoding, wait for new slice
|
||||
@@ -83,11 +82,13 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
} else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
|
||||
&& (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
|
||||
pCtx->pDec->bIsComplete = true;
|
||||
pCtx->bFreezeOutput = false;
|
||||
}
|
||||
|
||||
pCtx->iTotalNumMbRec = 0;
|
||||
|
||||
//////output:::normal path
|
||||
pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp;
|
||||
ppDst[0] = pPic->pData[0];
|
||||
ppDst[1] = pPic->pData[1];
|
||||
ppDst[2] = pPic->pData[2];
|
||||
@@ -103,15 +104,33 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
|
||||
pDstInfo->iBufferStatus = 1;
|
||||
|
||||
bool bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth)
|
||||
|| (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight);
|
||||
pCtx->iLastImgWidthInPixel = pDstInfo->UsrData.sSystemBuffer.iWidth;
|
||||
pCtx->iLastImgHeightInPixel = pDstInfo->UsrData.sSystemBuffer.iHeight;
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete
|
||||
pDstInfo->iBufferStatus = (int32_t) (bFrameCompleteFlag
|
||||
&& pPic->bIsComplete); // When EC disable, ECed picture not output
|
||||
else if ((pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE
|
||||
|| pCtx->eErrorConMethod == ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE)
|
||||
&& pCtx->iErrorCode && bOutResChange)
|
||||
pCtx->bFreezeOutput = true;
|
||||
|
||||
if (pDstInfo->iBufferStatus == 0) {
|
||||
if (!bFrameCompleteFlag)
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return -1;
|
||||
}
|
||||
if (pCtx->bFreezeOutput) {
|
||||
pDstInfo->iBufferStatus = 0;
|
||||
if (pPic->bNewSeqBegin) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "DecodeFrameConstruction():New sequence detected, but freezed.");
|
||||
}
|
||||
}
|
||||
pCtx->iMbEcedNum = pPic->iMbEcedNum;
|
||||
pCtx->iMbNum = pPic->iMbNum;
|
||||
pCtx->iMbEcedPropNum = pPic->iMbEcedPropNum;
|
||||
UpdateDecStat (pCtx, pDstInfo->iBufferStatus != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -131,13 +150,6 @@ inline void HandleReferenceLostL0 (PWelsDecoderContext pCtx, PNalUnit pCurNal
|
||||
if (0 == pCurNal->sNalHeaderExt.uiTemporalId) {
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
}
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
#ifndef LONG_TERM_REF
|
||||
if (pCtx->bReferenceLostAtT0Flag) {
|
||||
ResetParameterSetsState (pCtx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
}
|
||||
|
||||
@@ -145,13 +157,6 @@ inline void HandleReferenceLost (PWelsDecoderContext pCtx, PNalUnit pCurNal)
|
||||
if ((0 == pCurNal->sNalHeaderExt.uiTemporalId) || (1 == pCurNal->sNalHeaderExt.uiTemporalId)) {
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
}
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
#ifndef LONG_TERM_REF
|
||||
if (pCtx->bReferenceLostAtT0Flag) {
|
||||
ResetParameterSetsState (pCtx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
pCtx->iErrorCode |= dsRefLost;
|
||||
}
|
||||
|
||||
@@ -314,6 +319,14 @@ int32_t InitBsBuffer (PWelsDecoderContext pCtx) {
|
||||
}
|
||||
pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead;
|
||||
pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte;
|
||||
if (pCtx->bParseOnly) {
|
||||
if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (WelsMalloc (pCtx->iMaxBsBufferSizeInByte,
|
||||
"pCtx->sSavedData.pHead"))) == NULL) {
|
||||
return ERR_INFO_OUT_OF_MEMORY;
|
||||
}
|
||||
pCtx->sSavedData.pStartPos = pCtx->sSavedData.pCurPos = pCtx->sSavedData.pHead;
|
||||
pCtx->sSavedData.pEnd = pCtx->sSavedData.pHead + pCtx->iMaxBsBufferSizeInByte;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -384,8 +397,6 @@ int32_t WelsInitMemory (PWelsDecoderContext pCtx) {
|
||||
|
||||
pCtx->uiTargetDqId = (uint8_t) - 1;
|
||||
pCtx->bEndOfStreamFlag = false;
|
||||
pCtx->iImgWidthInPixel = 0;
|
||||
pCtx->iImgHeightInPixel = 0;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
@@ -414,6 +425,13 @@ void WelsFreeMemory (PWelsDecoderContext pCtx) {
|
||||
pCtx->sRawData.pEnd = NULL;
|
||||
pCtx->sRawData.pStartPos = NULL;
|
||||
pCtx->sRawData.pCurPos = NULL;
|
||||
if (pCtx->sSavedData.pHead) {
|
||||
WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData->pHead");
|
||||
}
|
||||
pCtx->sSavedData.pHead = NULL;
|
||||
pCtx->sSavedData.pEnd = NULL;
|
||||
pCtx->sSavedData.pStartPos = NULL;
|
||||
pCtx->sSavedData.pCurPos = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -451,6 +469,7 @@ void DecodeNalHeaderExt (PNalUnit pNal, uint8_t* pSrc) {
|
||||
#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MIN -12
|
||||
#define SLICE_HEADER_INTER_LAYER_ALPHAC0_BETA_OFFSET_MAX 12
|
||||
#define MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1 15
|
||||
#define SLICE_HEADER_CABAC_INIT_IDC_MAX 2
|
||||
/*
|
||||
* decode_slice_header_avc
|
||||
* Parse slice header of bitstream in avc for storing data structure
|
||||
@@ -584,6 +603,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
pSliceHeadExt->pSubsetSps = pSubsetSps;
|
||||
|
||||
bIdrFlag = (!kbExtensionFlag && eNalType == NAL_UNIT_CODED_SLICE_IDR) || (kbExtensionFlag && pNalHeaderExt->bIdrFlag);
|
||||
pSliceHead->bIdrFlag = bIdrFlag;
|
||||
|
||||
if (pSps->uiLog2MaxFrameNum == 0) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "non existing SPS referenced");
|
||||
@@ -707,8 +727,13 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
}
|
||||
|
||||
if (pPps->bEntropyCodingModeFlag) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "ParseSliceHeaderSyntaxs(): CABAC in Enhancement layer not supported.");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_CABAC_EL);
|
||||
if (pSliceHead->eSliceType != I_SLICE && pSliceHead->eSliceType != SI_SLICE) {
|
||||
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
|
||||
pSliceHead->iCabacInitIdc = uiCode;
|
||||
WELS_CHECK_SE_UPPER_ERROR (pSliceHead->iCabacInitIdc, SLICE_HEADER_CABAC_INIT_IDC_MAX, "cabac_init_idc",
|
||||
ERR_INFO_INVALID_CABAC_INIT_IDC);
|
||||
} else
|
||||
pSliceHead->iCabacInitIdc = 0;
|
||||
}
|
||||
|
||||
WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //slice_qp_delta
|
||||
@@ -841,8 +866,8 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
||||
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //slice_skip_flag
|
||||
pSliceHeadExt->bSliceSkipFlag = !!uiCode;
|
||||
if (pSliceHeadExt->bSliceSkipFlag) {
|
||||
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //num_mbs_in_slice_minus1
|
||||
pSliceHeadExt->uiNumMbsInSlice = 1 + uiCode;
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "bSliceSkipFlag == 1 not supported.");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_SLICESKIP);
|
||||
} else {
|
||||
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //adaptive_base_mode_flag
|
||||
pSliceHeadExt->bAdaptiveBaseModeFlag = !!uiCode;
|
||||
@@ -971,6 +996,8 @@ int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) {
|
||||
}
|
||||
if (uiActualIdx ==
|
||||
pCurAu->uiActualUnitsNum) { // no found IDR nal within incoming AU, need exit to avoid mosaic issue, 11/19/2009
|
||||
|
||||
pCtx->sDecoderStatistics.uiIDRLostNum++;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
|
||||
"UpdateAccessUnit():::::Key frame lost.....CAN NOT find IDR from current AU.");
|
||||
pCtx->iErrorCode |= dsRefLost;
|
||||
@@ -1021,6 +1048,10 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid
|
||||
"pCtx->sMb.pLumaQp[]");
|
||||
pCtx->sMb.pChromaQp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
|
||||
"pCtx->sMb.pChromaQp[]");
|
||||
pCtx->sMb.pMvd[i][0] = (int16_t (*)[16][2])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
|
||||
int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]");
|
||||
pCtx->sMb.pCbfDc[i] = (uint8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint8_t),
|
||||
"pCtx->sMb.pCbfDc[]");
|
||||
pCtx->sMb.pNzc[i] = (int8_t (*)[24])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
|
||||
"pCtx->sMb.pNzc[]");
|
||||
pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
|
||||
@@ -1049,6 +1080,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid
|
||||
|
||||
pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
|
||||
"pCtx->sMb.pMbCorrectlyDecodedFlag[]");
|
||||
pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
|
||||
"pCtx->pMbRefConcealedFlag[]");
|
||||
|
||||
// check memory block valid due above allocated..
|
||||
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY,
|
||||
@@ -1057,6 +1090,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid
|
||||
(NULL == pCtx->sMb.pRefIndex[i][0]) ||
|
||||
(NULL == pCtx->sMb.pLumaQp[i]) ||
|
||||
(NULL == pCtx->sMb.pChromaQp[i]) ||
|
||||
(NULL == pCtx->sMb.pMvd[i][0]) ||
|
||||
(NULL == pCtx->sMb.pCbfDc[i]) ||
|
||||
(NULL == pCtx->sMb.pNzc[i]) ||
|
||||
(NULL == pCtx->sMb.pNzcRs[i]) ||
|
||||
(NULL == pCtx->sMb.pScaledTCoeff[i]) ||
|
||||
@@ -1068,6 +1103,7 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid
|
||||
(NULL == pCtx->sMb.pSliceIdc[i]) ||
|
||||
(NULL == pCtx->sMb.pResidualPredFlag[i]) ||
|
||||
(NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) ||
|
||||
(NULL == pCtx->sMb.pMbRefConcealedFlag[i]) ||
|
||||
(NULL == pCtx->sMb.pMbCorrectlyDecodedFlag[i])
|
||||
)
|
||||
)
|
||||
@@ -1076,7 +1112,6 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid
|
||||
++ i;
|
||||
} while (i < LAYER_NUM_EXCHANGEABLE);
|
||||
|
||||
|
||||
pCtx->bInitialDqLayersMem = true;
|
||||
pCtx->iPicWidthReq = kiMaxWidth;
|
||||
pCtx->iPicHeightReq = kiMaxHeight;
|
||||
@@ -1124,6 +1159,16 @@ void UninitialDqLayersContext (PWelsDecoderContext pCtx) {
|
||||
pCtx->sMb.pChromaQp[i] = NULL;
|
||||
}
|
||||
|
||||
if (pCtx->sMb.pMvd[i][0]) {
|
||||
WelsFree (pCtx->sMb.pMvd[i][0], "pCtx->sMb.pMvd[][]");
|
||||
pCtx->sMb.pMvd[i][0] = NULL;
|
||||
}
|
||||
|
||||
if (pCtx->sMb.pCbfDc[i]) {
|
||||
WelsFree (pCtx->sMb.pCbfDc[i], "pCtx->sMb.pCbfDc[]");
|
||||
pCtx->sMb.pCbfDc[i] = NULL;
|
||||
}
|
||||
|
||||
if (pCtx->sMb.pNzc[i]) {
|
||||
WelsFree (pCtx->sMb.pNzc[i], "pCtx->sMb.pNzc[]");
|
||||
|
||||
@@ -1202,6 +1247,10 @@ void UninitialDqLayersContext (PWelsDecoderContext pCtx) {
|
||||
pCtx->sMb.pMbCorrectlyDecodedFlag[i] = NULL;
|
||||
}
|
||||
|
||||
if (pCtx->sMb.pMbRefConcealedFlag[i]) {
|
||||
WelsFree (pCtx->sMb.pMbRefConcealedFlag[i], "pCtx->sMb.pMbRefConcealedFlag[]");
|
||||
pCtx->sMb.pMbRefConcealedFlag[i] = NULL;
|
||||
}
|
||||
WelsFree (pDq, "pDq");
|
||||
|
||||
pDq = NULL;
|
||||
@@ -1272,6 +1321,18 @@ void ForceClearCurrentNal (PAccessUnit pAu) {
|
||||
-- pAu->uiAvailUnitsNum;
|
||||
}
|
||||
|
||||
void ForceResetParaSetStatusAndAUList (PWelsDecoderContext pCtx) {
|
||||
pCtx->bSpsExistAheadFlag = false;
|
||||
pCtx->bSubspsExistAheadFlag = false;
|
||||
pCtx->bPpsExistAheadFlag = false;
|
||||
|
||||
// Force clear the AU list
|
||||
pCtx->pAccessUnitList->uiAvailUnitsNum = 0;
|
||||
pCtx->pAccessUnitList->uiActualUnitsNum = 0;
|
||||
pCtx->pAccessUnitList->uiStartPos = 0;
|
||||
pCtx->pAccessUnitList->uiEndPos = 0;
|
||||
pCtx->pAccessUnitList->bCompletedAuFlag = false;
|
||||
}
|
||||
|
||||
void CheckAvailNalUnitsListContinuity (PWelsDecoderContext pCtx, int32_t iStartIdx, int32_t iEndIdx) {
|
||||
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
||||
@@ -1642,7 +1703,6 @@ static void WriteBackActiveParameters (PWelsDecoderContext pCtx) {
|
||||
int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
int32_t iErr;
|
||||
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
||||
|
||||
pCtx->bAuReadyFlag = false;
|
||||
pCtx->bLastHasMmco5 = false;
|
||||
bool bTmpNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps (pCtx);
|
||||
@@ -1652,7 +1712,8 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
||||
|
||||
if (ERR_NONE != iErr) {
|
||||
ForceResetCurrentAccessUnit (pCtx->pAccessUnitList);
|
||||
pDstInfo->iBufferStatus = 0;
|
||||
if (!pCtx->bParseOnly)
|
||||
pDstInfo->iBufferStatus = 0;
|
||||
return iErr;
|
||||
}
|
||||
|
||||
@@ -1673,6 +1734,54 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
||||
|
||||
iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo);
|
||||
|
||||
if (pCtx->bParseOnly) {
|
||||
if (dsErrorFree == pCtx->iErrorCode) {
|
||||
SParserBsInfo* pParser = pCtx->pParserBsInfo;
|
||||
uint8_t* pDstBuf = pParser->pDstBuff;
|
||||
SNalUnit* pCurNal = NULL;
|
||||
int32_t iNalLen = 0;
|
||||
int32_t iIdx = pCurAu->uiStartPos;
|
||||
int32_t iEndIdx = pCurAu->uiEndPos;
|
||||
uint8_t* pNalBs = NULL;
|
||||
pParser->uiOutBsTimeStamp = (pCurAu->pNalUnitsList [iIdx]) ? pCurAu->pNalUnitsList [iIdx]->uiTimeStamp : 0;
|
||||
pParser->iNalNum = 0;
|
||||
pParser->iSpsWidthInPixel = (pCtx->pSps->iMbWidth << 4);
|
||||
pParser->iSpsHeightInPixel = (pCtx->pSps->iMbHeight << 4);
|
||||
|
||||
if (pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.bIdrFlag) { //IDR
|
||||
bool bSubSps = (NAL_UNIT_CODED_SLICE_EXT == pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.sNalUnitHeader.eNalUnitType);
|
||||
SSpsBsInfo* pSpsBs = NULL;
|
||||
SPpsBsInfo* pPpsBs = NULL;
|
||||
int32_t iSpsId = pCtx->pSps->iSpsId;
|
||||
int32_t iPpsId = pCtx->pPps->iPpsId;
|
||||
pCtx->bParamSetsLostFlag = false;
|
||||
//find required sps, pps and write into dst buff
|
||||
pSpsBs = bSubSps ? &pCtx->sSubsetSpsBsInfo [iSpsId] : &pCtx->sSpsBsInfo [iSpsId];
|
||||
memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen);
|
||||
pParser->iNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen;
|
||||
pDstBuf += pSpsBs->uiSpsBsLen;
|
||||
pPpsBs = &pCtx->sPpsBsInfo [iPpsId];
|
||||
memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen);
|
||||
pParser->iNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen;
|
||||
pDstBuf += pPpsBs->uiPpsBsLen;
|
||||
} //IDR required SPS, PPS
|
||||
//then VCL data re-write
|
||||
while (iIdx <= iEndIdx) {
|
||||
pCurNal = pCurAu->pNalUnitsList [iIdx ++];
|
||||
iNalLen = pCurNal->sNalData.sVclNal.iNalLength;
|
||||
pNalBs = pCurNal->sNalData.sVclNal.pNalPos;
|
||||
pParser->iNalLenInByte [pParser->iNalNum ++] = iNalLen;
|
||||
memcpy (pDstBuf, pNalBs, iNalLen);
|
||||
pDstBuf += iNalLen;
|
||||
}
|
||||
} else { //error
|
||||
pCtx->pParserBsInfo->uiOutBsTimeStamp = 0;
|
||||
pCtx->pParserBsInfo->iNalNum = 0;
|
||||
pCtx->pParserBsInfo->iSpsWidthInPixel = 0;
|
||||
pCtx->pParserBsInfo->iSpsHeightInPixel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
WelsDecodeAccessUnitEnd (pCtx);
|
||||
|
||||
pCtx->bNewSeqBegin = false;
|
||||
@@ -1754,6 +1863,8 @@ void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) {
|
||||
pCurDq->pRefIndex[0] = pCtx->sMb.pRefIndex[0][0];
|
||||
pCurDq->pLumaQp = pCtx->sMb.pLumaQp[0];
|
||||
pCurDq->pChromaQp = pCtx->sMb.pChromaQp[0];
|
||||
pCurDq->pMvd[0] = pCtx->sMb.pMvd[0][0];
|
||||
pCurDq->pCbfDc = pCtx->sMb.pCbfDc[0];
|
||||
pCurDq->pNzc = pCtx->sMb.pNzc[0];
|
||||
pCurDq->pNzcRs = pCtx->sMb.pNzcRs[0];
|
||||
pCurDq->pScaledTCoeff = pCtx->sMb.pScaledTCoeff[0];
|
||||
@@ -1765,17 +1876,10 @@ void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) {
|
||||
pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0];
|
||||
pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0];
|
||||
pCurDq->pMbCorrectlyDecodedFlag = pCtx->sMb.pMbCorrectlyDecodedFlag[0];
|
||||
pCurDq->pMbRefConcealedFlag = pCtx->sMb.pMbRefConcealedFlag[0];
|
||||
}
|
||||
}
|
||||
|
||||
// added to reset state of parameter sets to waiting successive incoming IDR, 6/4/2010
|
||||
// It will be called in case packets lost/ broken and decoded failed at temporal level 0
|
||||
void ResetParameterSetsState (PWelsDecoderContext pCtx) {
|
||||
pCtx->bSpsExistAheadFlag = false;
|
||||
pCtx->bSubspsExistAheadFlag = false;
|
||||
pCtx->bPpsExistAheadFlag = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* DecodeCurrentAccessUnit
|
||||
* Decode current access unit when current AU is completed.
|
||||
@@ -1825,13 +1929,20 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
pCtx->iErrorCode |= dsOutOfMemory;
|
||||
return ERR_INFO_REF_COUNT_OVERFLOW;
|
||||
}
|
||||
pCtx->pDec->bNewSeqBegin = pCtx->bNewSeqBegin; //set flag for start decoding
|
||||
}
|
||||
pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp;
|
||||
|
||||
if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
|
||||
for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
|
||||
memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
|
||||
memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight);
|
||||
memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));
|
||||
memset (pCtx->pCurDqLayer->pMbRefConcealedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight * sizeof (bool));
|
||||
pCtx->pDec->iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
||||
pCtx->pDec->iMbEcedNum = 0;
|
||||
pCtx->pDec->iMbEcedPropNum = 0;
|
||||
}
|
||||
pCtx->bRPLRError = false;
|
||||
GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]);
|
||||
|
||||
if (pNalCur->sNalHeaderExt.uiLayerDqId > kuiTargetLayerDqId) { // confirmed pNalCur will never be NULL
|
||||
@@ -1849,12 +1960,14 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
iCurrIdD = pNalCur->sNalHeaderExt.uiDependencyId;
|
||||
pSh = &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
|
||||
pShExt = &pNalCur->sNalData.sVclNal.sSliceHeaderExt;
|
||||
|
||||
pCtx->bRPLRError = false;
|
||||
bReconstructSlice = CheckSliceNeedReconstruct (pNalCur->sNalHeaderExt.uiLayerDqId, kuiTargetLayerDqId);
|
||||
|
||||
memcpy (&pLayerInfo.sNalHeaderExt, &pNalCur->sNalHeaderExt, sizeof (SNalUnitHeaderExt)); //confirmed_safe_unsafe_usage
|
||||
|
||||
pCtx->pDec->iFrameNum = pSh->iFrameNum;
|
||||
pCtx->pDec->iFramePoc = pSh->iPicOrderCntLsb; // still can not obtain correct, because current do not support POCtype 2
|
||||
pCtx->pDec->bIdrFlag = pNalCur->sNalHeaderExt.bIdrFlag;
|
||||
|
||||
memcpy (&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof (SSliceHeaderExt)); //confirmed_safe_unsafe_usage
|
||||
pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag;
|
||||
@@ -1910,7 +2023,6 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
#else
|
||||
pCtx->bReferenceLostAtT0Flag = true;
|
||||
#endif
|
||||
ResetParameterSetsState (pCtx);
|
||||
return ERR_INFO_REFERENCE_PIC_LOST;
|
||||
}
|
||||
}
|
||||
@@ -1919,6 +2031,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) {
|
||||
pCtx->bRPLRError = true;
|
||||
bAllRefComplete = false; // RPLR error, set ref pictures complete flag false
|
||||
HandleReferenceLost (pCtx, pNalCur);
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
|
||||
@@ -1943,14 +2056,21 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
return iRet;
|
||||
}
|
||||
}
|
||||
if (bReconstructSlice) {
|
||||
if (WelsDecodeConstructSlice (pCtx, pNalCur)) {
|
||||
pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false
|
||||
return -1;
|
||||
|
||||
if (!pCtx->bParseOnly) {
|
||||
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 (bAllRefComplete && pCtx->eSliceType != I_SLICE) {
|
||||
if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) {
|
||||
bAllRefComplete &= CheckRefPicturesComplete (pCtx);
|
||||
} else {
|
||||
bAllRefComplete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
|
||||
@@ -1989,22 +2109,23 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
#endif//#if !CODEC_FOR_TESTBED
|
||||
|
||||
if (dq_cur->uiLayerDqId == kuiTargetLayerDqId) {
|
||||
if (!pCtx->bInstantDecFlag) {
|
||||
//Do error concealment here
|
||||
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;
|
||||
if (!pCtx->bParseOnly) {
|
||||
if (!pCtx->bInstantDecFlag) {
|
||||
//Do error concealment here
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC
|
||||
if (uiNalRefIdc > 0) {
|
||||
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC
|
||||
iRet = WelsMarkAsRef (pCtx);
|
||||
if (iRet != ERR_NONE) {
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
|
||||
@@ -2015,8 +2136,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel,
|
||||
pCtx->pDec->iLinesize,
|
||||
pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
|
||||
pCtx->pDec = NULL;
|
||||
}
|
||||
pCtx->pDec = NULL; //after frame decoding, always set to NULL
|
||||
}
|
||||
|
||||
// need update frame_num due current frame is well decoded
|
||||
@@ -2030,6 +2151,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
||||
|
||||
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
PAccessUnit pAu = pCtx->pAccessUnitList;
|
||||
if (pAu->uiAvailUnitsNum == 0)
|
||||
return true;
|
||||
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
|
||||
if ((pCtx->iTotalNumMbRec != 0)
|
||||
&& (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
|
||||
@@ -2043,14 +2166,17 @@ bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferIn
|
||||
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
|
||||
|
||||
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
|
||||
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
|
||||
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
|
||||
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
|
||||
MarkECFrameAsRef (pCtx);
|
||||
}
|
||||
} else {
|
||||
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo))
|
||||
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
|
||||
pCtx->pDec = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pCtx->pDec = NULL;
|
||||
pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
|
||||
if (pCtx->bLastHasMmco5)
|
||||
pCtx->iPrevFrameNum = 0;
|
||||
@@ -2059,7 +2185,7 @@ bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferIn
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx) {
|
||||
bool CheckRefPicturesComplete (PWelsDecoderContext pCtx) {
|
||||
// Multi Reference, RefIdx may differ
|
||||
bool bAllRefComplete = true;
|
||||
int32_t iRealMbIdx;
|
||||
|
||||
@@ -54,6 +54,56 @@ const uint8_t g_kuiScan4[16] = { //for mb cache in sMb (only current element, wi
|
||||
// extern at wels_common_basis.h
|
||||
|
||||
/*common use table*/
|
||||
const uint8_t g_kMbNonZeroCountIdx[24] = {
|
||||
// 0 1 | 4 5 luma 8*8 block pNonZeroCount[16+8]
|
||||
0, 1, 4, 5, // 2 3 | 6 7 0 | 1 0 1 2 3
|
||||
2, 3, 6, 7, //--------------- --------- 4 5 6 7
|
||||
8, 9, 12, 13, // 8 9 | 12 13 2 | 3 8 9 10 11
|
||||
10, 11, 14, 15, // 10 11 | 14 15-----------------------------> 12 13 14 15
|
||||
16, 17, 20, 21, //---------------- chroma 8*8 block 16 17 18 19
|
||||
18, 19, 22, 23 // 16 17 | 20 21 0 1 20 21 22 23
|
||||
};
|
||||
//cache element equal to 26
|
||||
|
||||
const uint8_t g_kCacheNzcScanIdx[4 * 4 + 4 + 4 + 3] = {
|
||||
/* Luma */
|
||||
9, 10, 17, 18, // 1+1*8, 2+1*8, 1+2*8, 2+2*8,
|
||||
11, 12, 19, 20, // 3+1*8, 4+1*8, 3+2*8, 4+2*8,
|
||||
25, 26, 33, 34, // 1+3*8, 2+3*8, 1+4*8, 2+4*8,
|
||||
27, 28, 35, 36, // 3+3*8, 4+3*8, 3+4*8, 4+4*8,
|
||||
/* Cb */
|
||||
14, 15, // 6+1*8, 7+1*8,
|
||||
22, 23, // 6+2*8, 7+2*8,
|
||||
|
||||
/* Cr */
|
||||
38, 39, // 6+4*8, 7+4*8,
|
||||
46, 47, // 6+5*8, 7+5*8,
|
||||
/* Luma DC */
|
||||
41, // 1+5*8
|
||||
/* Chroma DC */
|
||||
42, 43 // 2+5*8, 3+5*8,
|
||||
};
|
||||
|
||||
const uint8_t g_kCache26ScanIdx[16] = { //intra4*4_pred_mode and pNonZeroCount cache scan index, 4*4 block as basic unit
|
||||
6, 7, 11, 12,
|
||||
8, 9, 13, 14,
|
||||
16, 17, 21, 22,
|
||||
18, 19, 23, 24
|
||||
};
|
||||
|
||||
//cache element equal to 30
|
||||
const uint8_t g_kCache30ScanIdx[16] = { //mv or pRefIndex cache scan index, 4*4 block as basic unit
|
||||
7, 8, 13, 14,
|
||||
9, 10, 15, 16,
|
||||
19, 20, 25, 26,
|
||||
21, 22, 27, 28
|
||||
};
|
||||
|
||||
const uint8_t g_kNonZeroScanIdxC[4] = { //pNonZeroCount cache for chroma, 4*4 block as basic unit
|
||||
4, 5,
|
||||
7, 8
|
||||
};
|
||||
|
||||
const uint8_t g_kuiScan8[24] = { // [16 + 2*4]
|
||||
9, 10, 17, 18, // 1+1*8, 2+1*8, 1+2*8, 2+2*8,
|
||||
11, 12, 19, 20, // 3+1*8, 4+1*8, 3+2*8, 4+2*8,
|
||||
|
||||
@@ -41,7 +41,14 @@
|
||||
namespace WelsDec {
|
||||
//Init
|
||||
void InitErrorCon (PWelsDecoderContext pCtx) {
|
||||
if (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) {
|
||||
if ((pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) || (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR)
|
||||
|| (pCtx->eErrorConMethod == ERROR_CON_SLICE_MV_COPY_CROSS_IDR)
|
||||
|| (pCtx->eErrorConMethod == ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE)
|
||||
|| (pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE)) {
|
||||
if ((pCtx->eErrorConMethod != ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE)
|
||||
&& (pCtx->eErrorConMethod != ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE)) {
|
||||
pCtx->bFreezeOutput = false;
|
||||
}
|
||||
pCtx->sCopyFunc.pCopyLumaFunc = WelsCopy16x16_c;
|
||||
pCtx->sCopyFunc.pCopyChromaFunc = WelsCopy8x8_c;
|
||||
|
||||
@@ -79,6 +86,9 @@ void DoErrorConFrameCopy (PWelsDecoderContext pCtx) {
|
||||
uint32_t uiHeightInPixelY = (pCtx->pSps->iMbHeight) << 4;
|
||||
int32_t iStrideY = pDstPic->iLinesize[0];
|
||||
int32_t iStrideUV = pDstPic->iLinesize[1];
|
||||
pCtx->pDec->iMbEcedNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
||||
if ((pCtx->eErrorConMethod == ERROR_CON_FRAME_COPY) && (pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag))
|
||||
pSrcPic = NULL; //no cross IDR method, should fill in data instead of copy
|
||||
if (pSrcPic == NULL) { //no ref pic, assign specific data to picture
|
||||
memset (pDstPic->pData[0], 128, uiHeightInPixelY * iStrideY);
|
||||
memset (pDstPic->pData[1], 128, (uiHeightInPixelY >> 1) * iStrideUV);
|
||||
@@ -97,10 +107,11 @@ void DoErrorConSliceCopy (PWelsDecoderContext pCtx) {
|
||||
int32_t iMbHeight = (int32_t) pCtx->pSps->iMbHeight;
|
||||
PPicture pDstPic = pCtx->pDec;
|
||||
PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb;
|
||||
if ((pCtx->eErrorConMethod == ERROR_CON_SLICE_COPY) && (pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag))
|
||||
pSrcPic = NULL; //no cross IDR method, should fill in data instead of copy
|
||||
|
||||
//uint8_t *pDstData[3], *pSrcData[3];
|
||||
bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag;
|
||||
|
||||
//Do slice copy late
|
||||
int32_t iMbXyIndex;
|
||||
uint8_t* pSrcData, *pDstData;
|
||||
@@ -110,6 +121,7 @@ void DoErrorConSliceCopy (PWelsDecoderContext pCtx) {
|
||||
for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
|
||||
iMbXyIndex = iMbY * iMbWidth + iMbX;
|
||||
if (!pMbCorrectlyDecodedFlag[iMbXyIndex]) {
|
||||
pCtx->pDec->iMbEcedNum++;
|
||||
if (pSrcPic != NULL) {
|
||||
iSrcStride = pSrcPic->iLinesize[0];
|
||||
//Y component
|
||||
@@ -149,18 +161,275 @@ void DoErrorConSliceCopy (PWelsDecoderContext pCtx) {
|
||||
} //iMbY
|
||||
}
|
||||
|
||||
//Do error concealment using slice MV copy method
|
||||
void DoMbECMvCopy (PWelsDecoderContext pCtx, PPicture pDec, PPicture pRef, int32_t iMbXy, int32_t iMbX, int32_t iMbY,
|
||||
sMCRefMember* pMCRefMem) {
|
||||
if (pDec == pRef) {
|
||||
return; // for protection, shall never go into this logic, error info printed outside.
|
||||
}
|
||||
int16_t iMVs[2];
|
||||
int32_t iMbXInPix = iMbX << 4;
|
||||
int32_t iMbYInPix = iMbY << 4;
|
||||
int32_t iScale0;
|
||||
int32_t iScale1;
|
||||
uint8_t* pDst[3];
|
||||
int32_t iCurrPoc = pDec->iFramePoc;
|
||||
pDst[0] = pDec->pData[0] + iMbXInPix + iMbYInPix * pMCRefMem->iDstLineLuma;
|
||||
pDst[1] = pDec->pData[1] + (iMbXInPix >> 1) + (iMbYInPix >> 1) * pMCRefMem->iDstLineChroma;
|
||||
pDst[2] = pDec->pData[2] + (iMbXInPix >> 1) + (iMbYInPix >> 1) * pMCRefMem->iDstLineChroma;
|
||||
if (pDec->bIdrFlag == true || pCtx->pECRefPic[0] == NULL) {
|
||||
uint8_t* pSrcData;
|
||||
//Y component
|
||||
pSrcData = pMCRefMem->pSrcY + iMbY * 16 * pMCRefMem->iSrcLineLuma + iMbX * 16;
|
||||
pCtx->sCopyFunc.pCopyLumaFunc (pDst[0], pMCRefMem->iDstLineLuma, pSrcData, pMCRefMem->iSrcLineLuma);
|
||||
//U component
|
||||
pSrcData = pMCRefMem->pSrcU + iMbY * 8 * pMCRefMem->iSrcLineChroma + iMbX * 8;
|
||||
pCtx->sCopyFunc.pCopyChromaFunc (pDst[1], pMCRefMem->iDstLineChroma, pSrcData, pMCRefMem->iSrcLineChroma);
|
||||
//V component
|
||||
pSrcData = pMCRefMem->pSrcV + iMbY * 8 * pMCRefMem->iSrcLineChroma + iMbX * 8;
|
||||
pCtx->sCopyFunc.pCopyChromaFunc (pDst[2], pMCRefMem->iDstLineChroma, pSrcData, pMCRefMem->iSrcLineChroma);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCtx->pECRefPic[0]) {
|
||||
if (pCtx->pECRefPic[0] == pRef) {
|
||||
iMVs[0] = pCtx->iECMVs[0][0];
|
||||
iMVs[1] = pCtx->iECMVs[0][1];
|
||||
} else {
|
||||
iScale0 = pCtx->pECRefPic[0]->iFramePoc - iCurrPoc;
|
||||
iScale1 = pRef->iFramePoc - iCurrPoc;
|
||||
iMVs[0] = iScale0 == 0 ? 0 : pCtx->iECMVs[0][0] * iScale1 / iScale0;
|
||||
iMVs[1] = iScale0 == 0 ? 0 : pCtx->iECMVs[0][1] * iScale1 / iScale0;
|
||||
}
|
||||
pMCRefMem->pDstY = pDst[0];
|
||||
pMCRefMem->pDstU = pDst[1];
|
||||
pMCRefMem->pDstV = pDst[2];
|
||||
int32_t iFullMVx = (iMbXInPix << 2) + iMVs[0]; //quarter pixel
|
||||
int32_t iFullMVy = (iMbYInPix << 2) + iMVs[1];
|
||||
// only use to be output pixels to EC;
|
||||
int32_t iPicWidthLeftLimit = 0;
|
||||
int32_t iPicHeightTopLimit = 0;
|
||||
int32_t iPicWidthRightLimit = pMCRefMem->iPicWidth;
|
||||
int32_t iPicHeightBottomLimit = pMCRefMem->iPicHeight;
|
||||
if (pCtx->pSps->bFrameCroppingFlag) {
|
||||
iPicWidthLeftLimit = 0 + pCtx->sFrameCrop.iLeftOffset * 2;
|
||||
iPicWidthRightLimit = (pMCRefMem->iPicWidth - pCtx->sFrameCrop.iRightOffset * 2);
|
||||
iPicHeightTopLimit = 0 + pCtx->sFrameCrop.iTopOffset * 2;
|
||||
iPicHeightBottomLimit = (pMCRefMem->iPicHeight - pCtx->sFrameCrop.iTopOffset * 2);
|
||||
}
|
||||
// further make sure no need to expand picture
|
||||
int32_t iMinLeftOffset = (iPicWidthLeftLimit + 2) << 2;
|
||||
int32_t iMaxRightOffset = ((iPicWidthRightLimit - 19) << 2);
|
||||
int32_t iMinTopOffset = (iPicHeightTopLimit + 2) << 2;
|
||||
int32_t iMaxBottomOffset = ((iPicHeightBottomLimit - 19) << 2);
|
||||
if (iFullMVx < iMinLeftOffset) {
|
||||
iFullMVx = (iFullMVx >> 2) << 2;
|
||||
iFullMVx = WELS_MAX (iPicWidthLeftLimit, iFullMVx);
|
||||
} else if (iFullMVx > iMaxRightOffset) {
|
||||
iFullMVx = (iFullMVx >> 2) << 2;
|
||||
iFullMVx = WELS_MIN (((iPicWidthRightLimit - 17) << 2), iFullMVx);
|
||||
}
|
||||
if (iFullMVy < iMinTopOffset) {
|
||||
iFullMVy = (iFullMVy >> 2) << 2;
|
||||
iFullMVy = WELS_MAX (iPicHeightTopLimit, iFullMVy);
|
||||
} else if (iFullMVy > iMaxBottomOffset) {
|
||||
iFullMVy = (iFullMVy >> 2) << 2;
|
||||
iFullMVy = WELS_MIN (((iPicHeightBottomLimit - 17) << 2), iFullMVy);
|
||||
}
|
||||
iMVs[0] = iFullMVx - (iMbXInPix << 2);
|
||||
iMVs[1] = iFullMVy - (iMbYInPix << 2);
|
||||
BaseMC (pMCRefMem, iMbXInPix, iMbYInPix, &pCtx->sMcFunc, 16, 16, iMVs);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
void GetAvilInfoFromCorrectMb (PWelsDecoderContext pCtx) {
|
||||
int32_t iMbWidth = (int32_t) pCtx->pSps->iMbWidth;
|
||||
int32_t iMbHeight = (int32_t) pCtx->pSps->iMbHeight;
|
||||
bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag;
|
||||
PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
|
||||
int32_t iInterMbCorrectNum[16];
|
||||
int32_t iMbXyIndex;
|
||||
|
||||
int8_t iRefIdx;
|
||||
memset (pCtx->iECMVs, 0, sizeof (int32_t) * 32);
|
||||
memset (pCtx->pECRefPic, 0, sizeof (PPicture) * 16);
|
||||
memset (iInterMbCorrectNum, 0, sizeof (int32_t) * 16);
|
||||
|
||||
for (int32_t iMbY = 0; iMbY < iMbHeight; ++iMbY) {
|
||||
for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
|
||||
iMbXyIndex = iMbY * iMbWidth + iMbX;
|
||||
if (pMbCorrectlyDecodedFlag[iMbXyIndex] && IS_INTER (pCurDqLayer->pMbType[iMbXyIndex])) {
|
||||
int32_t iMBType = pCurDqLayer->pMbType[iMbXyIndex];
|
||||
switch (iMBType) {
|
||||
case MB_TYPE_SKIP:
|
||||
case MB_TYPE_16x16:
|
||||
iRefIdx = pCurDqLayer->pRefIndex[0][iMbXyIndex][0];
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][0][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][0][1];
|
||||
pCtx->pECRefPic[iRefIdx] = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];
|
||||
iInterMbCorrectNum[iRefIdx]++;
|
||||
break;
|
||||
case MB_TYPE_16x8:
|
||||
iRefIdx = pCurDqLayer->pRefIndex[0][iMbXyIndex][0];
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][0][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][0][1];
|
||||
pCtx->pECRefPic[iRefIdx] = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];
|
||||
iInterMbCorrectNum[iRefIdx]++;
|
||||
|
||||
iRefIdx = pCurDqLayer->pRefIndex[0][iMbXyIndex][8];
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][8][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][8][1];
|
||||
pCtx->pECRefPic[iRefIdx] = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];
|
||||
iInterMbCorrectNum[iRefIdx]++;
|
||||
break;
|
||||
case MB_TYPE_8x16:
|
||||
iRefIdx = pCurDqLayer->pRefIndex[0][iMbXyIndex][0];
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][0][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][0][1];
|
||||
pCtx->pECRefPic[iRefIdx] = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];
|
||||
iInterMbCorrectNum[iRefIdx]++;
|
||||
|
||||
iRefIdx = pCurDqLayer->pRefIndex[0][iMbXyIndex][2];
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][2][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][2][1];
|
||||
pCtx->pECRefPic[iRefIdx] = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];
|
||||
iInterMbCorrectNum[iRefIdx]++;
|
||||
break;
|
||||
case MB_TYPE_8x8:
|
||||
case MB_TYPE_8x8_REF0: {
|
||||
uint32_t iSubMBType;
|
||||
int32_t i, j, iIIdx, iJIdx;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
iSubMBType = pCurDqLayer->pSubMbType[iMbXyIndex][i];
|
||||
iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
|
||||
iRefIdx = pCurDqLayer->pRefIndex[0][iMbXyIndex][iIIdx];
|
||||
pCtx->pECRefPic[iRefIdx] = pCtx->sRefPic.pRefList[LIST_0][iRefIdx];
|
||||
switch (iSubMBType) {
|
||||
case SUB_MB_TYPE_8x8:
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx][1];
|
||||
iInterMbCorrectNum[iRefIdx]++;
|
||||
|
||||
break;
|
||||
case SUB_MB_TYPE_8x4:
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx][1];
|
||||
|
||||
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx + 4][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx + 4][1];
|
||||
iInterMbCorrectNum[iRefIdx] += 2;
|
||||
|
||||
break;
|
||||
case SUB_MB_TYPE_4x8:
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx][1];
|
||||
|
||||
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx + 1][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx + 1][1];
|
||||
iInterMbCorrectNum[iRefIdx] += 2;
|
||||
break;
|
||||
case SUB_MB_TYPE_4x4: {
|
||||
for (j = 0; j < 4; j++) {
|
||||
iJIdx = ((j >> 1) << 2) + (j & 1);
|
||||
pCtx->iECMVs[iRefIdx][0] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx + iJIdx][0];
|
||||
pCtx->iECMVs[iRefIdx][1] += pCurDqLayer->pMv[0][iMbXyIndex][iIIdx + iJIdx][1];
|
||||
}
|
||||
iInterMbCorrectNum[iRefIdx] += 4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} //pMbCorrectlyDecodedFlag[iMbXyIndex]
|
||||
} //iMbX
|
||||
} //iMbY
|
||||
for (int32_t i = 0; i < 16; i++) {
|
||||
if (iInterMbCorrectNum[i]) {
|
||||
pCtx->iECMVs[i][0] = pCtx->iECMVs[i][0] / iInterMbCorrectNum[i];
|
||||
pCtx->iECMVs[i][1] = pCtx->iECMVs[i][1] / iInterMbCorrectNum[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoErrorConSliceMVCopy (PWelsDecoderContext pCtx) {
|
||||
int32_t iMbWidth = (int32_t) pCtx->pSps->iMbWidth;
|
||||
int32_t iMbHeight = (int32_t) pCtx->pSps->iMbHeight;
|
||||
PPicture pDstPic = pCtx->pDec;
|
||||
PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb;
|
||||
|
||||
bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag;
|
||||
int32_t iMbXyIndex;
|
||||
uint8_t* pDstData;
|
||||
uint32_t iDstStride = pDstPic->iLinesize[0];
|
||||
sMCRefMember sMCRefMem;
|
||||
if (pSrcPic != NULL) {
|
||||
sMCRefMem.iSrcLineLuma = pSrcPic->iLinesize[0];
|
||||
sMCRefMem.iSrcLineChroma = pSrcPic->iLinesize[1];
|
||||
sMCRefMem.pSrcY = pSrcPic->pData[0];
|
||||
sMCRefMem.pSrcU = pSrcPic->pData[1];
|
||||
sMCRefMem.pSrcV = pSrcPic->pData[2];
|
||||
sMCRefMem.iDstLineLuma = pDstPic->iLinesize[0];
|
||||
sMCRefMem.iDstLineChroma = pDstPic->iLinesize[1];
|
||||
sMCRefMem.iPicWidth = pDstPic->iWidthInPixel;
|
||||
sMCRefMem.iPicHeight = pDstPic->iHeightInPixel;
|
||||
if (pDstPic == pSrcPic) {
|
||||
// output error info, EC will be ignored in DoMbECMvCopy
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "DoErrorConSliceMVCopy()::pPreviousPic and pDec use same buffer, ignored.");
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t iMbY = 0; iMbY < iMbHeight; ++iMbY) {
|
||||
for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
|
||||
iMbXyIndex = iMbY * iMbWidth + iMbX;
|
||||
if (!pMbCorrectlyDecodedFlag[iMbXyIndex]) {
|
||||
pCtx->pDec->iMbEcedNum++;
|
||||
if (pSrcPic != NULL) {
|
||||
DoMbECMvCopy (pCtx, pDstPic, pSrcPic, iMbXyIndex, iMbX, iMbY, &sMCRefMem);
|
||||
} else { //pSrcPic == NULL
|
||||
//Y component
|
||||
pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;
|
||||
for (int32_t i = 0; i < 16; ++i) {
|
||||
memset (pDstData, 128, 16);
|
||||
pDstData += iDstStride;
|
||||
}
|
||||
//U component
|
||||
pDstData = pDstPic->pData[1] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
|
||||
for (int32_t i = 0; i < 8; ++i) {
|
||||
memset (pDstData, 128, 8);
|
||||
pDstData += iDstStride / 2;
|
||||
}
|
||||
//V component
|
||||
pDstData = pDstPic->pData[2] + iMbY * 8 * iDstStride / 2 + iMbX * 8;
|
||||
for (int32_t i = 0; i < 8; ++i) {
|
||||
memset (pDstData, 128, 8);
|
||||
pDstData += iDstStride / 2;
|
||||
}
|
||||
} //
|
||||
|
||||
} //!pMbCorrectlyDecodedFlag[iMbXyIndex]
|
||||
} //iMbX
|
||||
} //iMbY
|
||||
}
|
||||
|
||||
//Mark erroneous frame as Ref Pic into DPB
|
||||
int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx) {
|
||||
int32_t iRet = WelsMarkAsRef (pCtx);
|
||||
if (iRet != ERR_NONE) {
|
||||
pCtx->pDec = NULL;
|
||||
return iRet;
|
||||
}
|
||||
ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel,
|
||||
pCtx->pDec->iLinesize,
|
||||
pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
|
||||
pCtx->pDec = NULL;
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
@@ -183,10 +452,17 @@ void ImplementErrorCon (PWelsDecoderContext pCtx) {
|
||||
if (ERROR_CON_DISABLE == pCtx->eErrorConMethod) {
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
return;
|
||||
} else if (ERROR_CON_FRAME_COPY == pCtx->eErrorConMethod) {
|
||||
} else if ((ERROR_CON_FRAME_COPY == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)) {
|
||||
DoErrorConFrameCopy (pCtx);
|
||||
} else if (ERROR_CON_SLICE_COPY == pCtx->eErrorConMethod) {
|
||||
} else if ((ERROR_CON_SLICE_COPY == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod)) {
|
||||
DoErrorConSliceCopy (pCtx);
|
||||
} else if ((ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod)) {
|
||||
GetAvilInfoFromCorrectMb (pCtx);
|
||||
DoErrorConSliceMVCopy (pCtx);
|
||||
} //TODO add other EC methods here in the future
|
||||
pCtx->iErrorCode |= dsDataErrorConcealed;
|
||||
pCtx->pDec->bIsComplete = false; // Set complete flag to false after do EC.
|
||||
|
||||
@@ -90,7 +90,7 @@ static inline int32_t FmoGenerateMbAllocMapType0 (PFmo pFmo, PPps pPps) {
|
||||
static inline int32_t FmoGenerateMbAllocMapType1 (PFmo pFmo, PPps pPps, const int32_t kiMbWidth) {
|
||||
uint32_t uiNumSliceGroups = 0;
|
||||
int32_t iMbNum = 0;
|
||||
int16_t i = 0;
|
||||
int32_t i = 0;
|
||||
WELS_VERIFY_RETURN_IF (1, (NULL == pFmo || NULL == pPps))
|
||||
uiNumSliceGroups = pPps->uiNumSliceGroups;
|
||||
iMbNum = pFmo->iCountMbNum;
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "manage_dec_ref.h"
|
||||
#include "error_concealment.h"
|
||||
#include "error_code.h"
|
||||
|
||||
namespace WelsDec {
|
||||
@@ -67,7 +68,7 @@ static void SetUnRef (PPicture pRef) {
|
||||
pRef->bUsedAsRef = false;
|
||||
pRef->bIsLongRef = false;
|
||||
pRef->iFrameNum = -1;
|
||||
pRef->iFramePoc = 0;
|
||||
//pRef->iFramePoc = 0;
|
||||
pRef->iLongTermFrameIdx = -1;
|
||||
pRef->uiQualityId = -1;
|
||||
pRef->uiTemporalId = -1;
|
||||
@@ -118,10 +119,27 @@ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
|
||||
if (pRef != NULL) {
|
||||
// IDR lost, set new
|
||||
pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
|
||||
pRef->iSpsId = pCtx->pSps->iSpsId;
|
||||
pRef->iPpsId = pCtx->pPps->iPpsId;
|
||||
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);
|
||||
bool bCopyPrevious = ((ERROR_CON_FRAME_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_SLICE_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_SLICE_MV_COPY_CROSS_IDR == pCtx->eErrorConMethod)
|
||||
|| (ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE == pCtx->eErrorConMethod))
|
||||
&& (NULL != pCtx->pPreviousDecodedPictureInDpb);
|
||||
bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
|
||||
&& (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
|
||||
|
||||
if (bCopyPrevious) {
|
||||
memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
|
||||
memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
|
||||
memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
pRef->iFrameNum = 0;
|
||||
pRef->iFramePoc = 0;
|
||||
pRef->uiTemporalId = pRef->uiQualityId = 0;
|
||||
@@ -244,6 +262,8 @@ int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) {
|
||||
|
||||
pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId;
|
||||
pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId;
|
||||
pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
|
||||
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
|
||||
|
||||
for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) {
|
||||
if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR
|
||||
|
||||
917
codec/decoder/core/src/parse_mb_syn_cabac.cpp
Normal file
917
codec/decoder/core/src/parse_mb_syn_cabac.cpp
Normal file
@@ -0,0 +1,917 @@
|
||||
/*!
|
||||
* \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.
|
||||
*
|
||||
* cabac_decoder.cpp: cabac parse for syntax elements
|
||||
*/
|
||||
#include "parse_mb_syn_cabac.h"
|
||||
#include "mv_pred.h"
|
||||
#include "error_code.h"
|
||||
namespace WelsDec {
|
||||
#define IDX_UNUSED -1
|
||||
static const int16_t g_kMaxPos [] = {IDX_UNUSED, 15, 14, 15, 3, 14, 3, 3, 14, 14};
|
||||
static const int16_t g_kMaxC2 [] = {IDX_UNUSED, 4, 4, 4, 3, 4, 3, 3, 4, 4};
|
||||
static const int16_t g_kBlockCat2CtxOffsetCBF[] = {IDX_UNUSED, 0, 4, 8, 12, 16, 12, 12, 16, 16};
|
||||
static const int16_t g_kBlockCat2CtxOffsetMap [] = {IDX_UNUSED, 0, 15, 29, 44, 47, 44, 44, 47, 47};
|
||||
static const int16_t g_kBlockCat2CtxOffsetLast[] = {IDX_UNUSED, 0, 15, 29, 44, 47, 44, 44, 47, 47};
|
||||
static const int16_t g_kBlockCat2CtxOffsetOne [] = {IDX_UNUSED, 0 , 10, 20, 30, 39, 30, 30, 39, 39};
|
||||
static const int16_t g_kBlockCat2CtxOffsetAbs [] = {IDX_UNUSED, 0 , 10, 20, 30, 39, 30, 30, 39, 39};
|
||||
|
||||
const uint8_t g_kTopBlkInsideMb[24] = { //for index with z-order 0~23
|
||||
// 0 1 | 4 5 luma 8*8 block pNonZeroCount[16+8]
|
||||
0, 0, 1, 1, // 2 3 | 6 7 0 | 1 0 1 2 3
|
||||
0, 0, 1, 1, //--------------- --------- 4 5 6 7
|
||||
1, 1, 1, 1, // 8 9 | 12 13 2 | 3 8 9 10 11
|
||||
1, 1, 1, 1, // 10 11 | 14 15-----------------------------> 12 13 14 15
|
||||
0, 0, 1, 1, //---------------- chroma 8*8 block 16 17 18 19
|
||||
0, 0, 1, 1 // 16 17 | 20 21 0 1 20 21 22 23
|
||||
// 18 19 | 22 23
|
||||
};
|
||||
|
||||
const uint8_t g_kLeftBlkInsideMb[24] = { //for index with z-order 0~23
|
||||
// 0 1 | 4 5 luma 8*8 block pNonZeroCount[16+8]
|
||||
0, 1, 0, 1, // 2 3 | 6 7 0 | 1 0 1 2 3
|
||||
1, 1, 1, 1, //--------------- --------- 4 5 6 7
|
||||
0, 1, 0, 1, // 8 9 | 12 13 2 | 3 8 9 10 11
|
||||
1, 1, 1, 1, // 10 11 | 14 15-----------------------------> 12 13 14 15
|
||||
0, 1, 0, 1, //---------------- chroma 8*8 block 16 17 18 19
|
||||
0, 1, 0, 1 // 16 17 | 20 21 0 1 20 21 22 23
|
||||
// 18 19 | 22 23
|
||||
};
|
||||
|
||||
void UpdateP16x8RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
|
||||
const int8_t iListIdx) {
|
||||
int32_t iRef32Bit = (int32_t) iRef;
|
||||
const int32_t iRef4Bytes = (iRef32Bit << 24) | (iRef32Bit << 16) | (iRef32Bit << 8) | iRef32Bit;
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
|
||||
const uint8_t iScan4Idx4 = 4 + iScan4Idx;
|
||||
const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
|
||||
const uint8_t iCacheIdx6 = 6 + iCacheIdx;
|
||||
//mb
|
||||
ST32 (&pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx ], iRef4Bytes);
|
||||
ST32 (&pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx4], iRef4Bytes);
|
||||
//cache
|
||||
ST32 (&pRefIndex[iListIdx][iCacheIdx ], iRef4Bytes);
|
||||
ST32 (&pRefIndex[iListIdx][iCacheIdx6], iRef4Bytes);
|
||||
}
|
||||
|
||||
void UpdateP8x16RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
|
||||
const int8_t iListIdx) {
|
||||
int16_t iRef16Bit = (int16_t) iRef;
|
||||
const int16_t iRef2Bytes = (iRef16Bit << 8) | iRef16Bit;
|
||||
int32_t i;
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
for (i = 0; i < 2; i++, iPartIdx += 8) {
|
||||
const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
|
||||
const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
|
||||
const uint8_t iScan4Idx4 = 4 + iScan4Idx;
|
||||
const uint8_t iCacheIdx6 = 6 + iCacheIdx;
|
||||
//mb
|
||||
ST16 (&pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx ], iRef2Bytes);
|
||||
ST16 (&pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx4], iRef2Bytes);
|
||||
//cache
|
||||
ST16 (&pRefIndex[iListIdx][iCacheIdx ], iRef2Bytes);
|
||||
ST16 (&pRefIndex[iListIdx][iCacheIdx6], iRef2Bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateP8x8RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
|
||||
const int8_t iListIdx) {
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
|
||||
pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx] = pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx + 1] =
|
||||
pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx + 4] = pCurDqLayer->pRefIndex[iListIdx][iMbXy][iScan4Idx + 5] = iRef;
|
||||
}
|
||||
|
||||
void UpdateP16x16MvdCabac (SDqLayer* pCurDqLayer, int16_t pMvd[2], const int8_t iListIdx) {
|
||||
int32_t pMvd32[2];
|
||||
ST32 (&pMvd32[0], LD32 (pMvd));
|
||||
ST32 (&pMvd32[1], LD32 (pMvd));
|
||||
int32_t i;
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][i], LD64 (pMvd32));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateP16x8MvdCabac (SDqLayer* pCurDqLayer, int16_t pMvdCache[LIST_A][30][MV_A], int32_t iPartIdx, int16_t pMvd[2],
|
||||
const int8_t iListIdx) {
|
||||
int32_t pMvd32[2];
|
||||
ST32 (&pMvd32[0], LD32 (pMvd));
|
||||
ST32 (&pMvd32[1], LD32 (pMvd));
|
||||
int32_t i;
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
for (i = 0; i < 2; i++, iPartIdx += 4) {
|
||||
const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
|
||||
const uint8_t iScan4Idx4 = 4 + iScan4Idx;
|
||||
const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
|
||||
const uint8_t iCacheIdx6 = 6 + iCacheIdx;
|
||||
//mb
|
||||
ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][ iScan4Idx ], LD64 (pMvd32));
|
||||
ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][ iScan4Idx4], LD64 (pMvd32));
|
||||
//cache
|
||||
ST64 (pMvdCache[iListIdx][ iCacheIdx ], LD64 (pMvd32));
|
||||
ST64 (pMvdCache[iListIdx][ iCacheIdx6], LD64 (pMvd32));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateP8x16MvdCabac (SDqLayer* pCurDqLayer, int16_t pMvdCache[LIST_A][30][MV_A], int32_t iPartIdx, int16_t pMvd[2],
|
||||
const int8_t iListIdx) {
|
||||
int32_t pMvd32[2];
|
||||
ST32 (&pMvd32[0], LD32 (pMvd));
|
||||
ST32 (&pMvd32[1], LD32 (pMvd));
|
||||
int32_t i;
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
|
||||
for (i = 0; i < 2; i++, iPartIdx += 8) {
|
||||
const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
|
||||
const uint8_t iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
|
||||
const uint8_t iScan4Idx4 = 4 + iScan4Idx;
|
||||
const uint8_t iCacheIdx6 = 6 + iCacheIdx;
|
||||
//mb
|
||||
ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][ iScan4Idx ], LD64 (pMvd32));
|
||||
ST64 (pCurDqLayer->pMvd[iListIdx][iMbXy][ iScan4Idx4], LD64 (pMvd32));
|
||||
//cache
|
||||
ST64 (pMvdCache[iListIdx][ iCacheIdx ], LD64 (pMvd32));
|
||||
ST64 (pMvdCache[iListIdx][ iCacheIdx6], LD64 (pMvd32));
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ParseEndOfSliceCabac (PWelsDecoderContext pCtx, uint32_t& uiBinVal) {
|
||||
uiBinVal = 0;
|
||||
WELS_READ_VERIFY (DecodeTerminateCabac (pCtx->pCabacDecEngine, uiBinVal));
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseSkipFlagCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiSkip) {
|
||||
uiSkip = 0;
|
||||
int32_t iCtxInc = (pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_SKIP) + (pNeighAvail->iTopAvail
|
||||
&& pNeighAvail->iTopType != MB_TYPE_SKIP);
|
||||
PWelsCabacCtx pBinCtx = (pCtx->pCabacCtx + NEW_CTX_OFFSET_SKIP + iCtxInc);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pBinCtx, uiSkip));
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
int32_t ParseMBTypeISliceCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiBinVal) {
|
||||
uint32_t uiCode;
|
||||
int32_t iIdxA = 0, iIdxB = 0;
|
||||
int32_t iCtxInc;
|
||||
uiBinVal = 0;
|
||||
PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
|
||||
PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_MB_TYPE_I; //I mode in I slice
|
||||
iIdxA = (pNeighAvail->iLeftAvail) && (pNeighAvail->iLeftType != MB_TYPE_INTRA4x4
|
||||
&& pNeighAvail->iLeftType != MB_TYPE_INTRA8x8);
|
||||
iIdxB = (pNeighAvail->iTopAvail) && (pNeighAvail->iTopType != MB_TYPE_INTRA4x4
|
||||
&& pNeighAvail->iTopType != MB_TYPE_INTRA8x8);
|
||||
iCtxInc = iIdxA + iIdxB;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + iCtxInc, uiCode));
|
||||
uiBinVal = uiCode;
|
||||
if (uiBinVal != 0) { //I16x16
|
||||
WELS_READ_VERIFY (DecodeTerminateCabac (pCabacDecEngine, uiCode));
|
||||
if (uiCode == 1)
|
||||
uiBinVal = 25; //I_PCM
|
||||
else {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
|
||||
uiBinVal = 1 + uiCode * 12;
|
||||
//decoding of uiCbp:0,1,2
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 4, uiCode));
|
||||
if (uiCode != 0) {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
|
||||
uiBinVal += 4;
|
||||
if (uiCode != 0)
|
||||
uiBinVal += 4;
|
||||
}
|
||||
//decoding of I pred-mode: 0,1,2,3
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 6, uiCode));
|
||||
uiBinVal += (uiCode << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 7, uiCode));
|
||||
uiBinVal += uiCode;
|
||||
}
|
||||
}
|
||||
//I4x4
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseMBTypePSliceCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiMbType) {
|
||||
uint32_t uiCode;
|
||||
uiMbType = 0;
|
||||
PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
|
||||
|
||||
PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_SKIP;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 3, uiCode));
|
||||
if (uiCode) {
|
||||
// Intra MB
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 6, uiCode));
|
||||
if (uiCode) { // Intra 16x16
|
||||
WELS_READ_VERIFY (DecodeTerminateCabac (pCabacDecEngine, uiCode));
|
||||
if (uiCode) {
|
||||
uiMbType = 30;
|
||||
return ERR_NONE;//MB_TYPE_INTRA_PCM;
|
||||
}
|
||||
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 7, uiCode));
|
||||
uiMbType = 6 + uiCode * 12;
|
||||
|
||||
//uiCbp: 0,1,2
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 8, uiCode));
|
||||
if (uiCode) {
|
||||
uiMbType += 4;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 8, uiCode));
|
||||
if (uiCode)
|
||||
uiMbType += 4;
|
||||
}
|
||||
|
||||
//IPredMode: 0,1,2,3
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 9, uiCode));
|
||||
uiMbType += (uiCode << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 9, uiCode));
|
||||
uiMbType += uiCode;
|
||||
} else
|
||||
// Intra 4x4
|
||||
uiMbType = 5;
|
||||
} else { // P MB
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 4, uiCode));
|
||||
if (uiCode) { //second bit
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 6, uiCode));
|
||||
if (uiCode)
|
||||
uiMbType = 1;
|
||||
else
|
||||
uiMbType = 2;
|
||||
} else {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 5, uiCode));
|
||||
if (uiCode)
|
||||
uiMbType = 3;
|
||||
else
|
||||
uiMbType = 0;
|
||||
}
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
int32_t ParseSubMBTypeCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiSubMbType) {
|
||||
uint32_t uiCode;
|
||||
PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
|
||||
PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_SUBMB_TYPE;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx, uiCode));
|
||||
if (uiCode)
|
||||
uiSubMbType = 0;
|
||||
else {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 1, uiCode));
|
||||
if (uiCode) {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCabacDecEngine, pBinCtx + 2, uiCode));
|
||||
uiSubMbType = 3 - uiCode;
|
||||
} else {
|
||||
uiSubMbType = 1;
|
||||
}
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseIntraPredModeLumaCabac (PWelsDecoderContext pCtx, int32_t& iBinVal) {
|
||||
uint32_t uiCode;
|
||||
iBinVal = 0;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR, uiCode));
|
||||
if (uiCode == 1)
|
||||
iBinVal = -1;
|
||||
else {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR + 1, uiCode));
|
||||
iBinVal |= uiCode;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR + 1, uiCode));
|
||||
iBinVal |= (uiCode << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_IPR + 1, uiCode));
|
||||
iBinVal |= (uiCode << 2);
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseIntraPredModeChromaCabac (PWelsDecoderContext pCtx, uint8_t uiNeighAvail, int32_t& iBinVal) {
|
||||
uint32_t uiCode;
|
||||
int32_t iIdxA, iIdxB, iCtxInc;
|
||||
int8_t* pChromaPredMode = pCtx->pCurDqLayer->pChromaPredMode;
|
||||
int8_t* pMbType = pCtx->pCurDqLayer->pMbType;
|
||||
int32_t iLeftAvail = uiNeighAvail & 0x04;
|
||||
int32_t iTopAvail = uiNeighAvail & 0x01;
|
||||
|
||||
int32_t iMbXy = pCtx->pCurDqLayer->iMbXyIndex;
|
||||
int32_t iMbXyTop = iMbXy - pCtx->pCurDqLayer->iMbWidth;
|
||||
int32_t iMbXyLeft = iMbXy - 1;
|
||||
|
||||
iBinVal = 0;
|
||||
|
||||
iIdxB = iTopAvail && (pChromaPredMode[iMbXyTop] > 0 && pChromaPredMode[iMbXyTop] <= 3)
|
||||
&& pMbType[iMbXyTop] != MB_TYPE_INTRA_PCM;
|
||||
iIdxA = iLeftAvail && (pChromaPredMode[iMbXyLeft] > 0 && pChromaPredMode[iMbXyLeft] <= 3)
|
||||
&& pMbType[iMbXyLeft] != MB_TYPE_INTRA_PCM;
|
||||
iCtxInc = iIdxA + iIdxB;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CIPR + iCtxInc, uiCode));
|
||||
iBinVal = uiCode;
|
||||
if (iBinVal != 0) {
|
||||
uint32_t iSym;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CIPR + 3, iSym));
|
||||
if (iSym == 0) {
|
||||
iBinVal = (iSym + 1);
|
||||
return ERR_NONE;
|
||||
}
|
||||
iSym = 0;
|
||||
do {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CIPR + 3, uiCode));
|
||||
++iSym;
|
||||
} while ((uiCode != 0) && (iSym < 1));
|
||||
|
||||
if ((uiCode != 0) && (iSym == 1))
|
||||
++ iSym;
|
||||
iBinVal = (iSym + 1);
|
||||
return ERR_NONE;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseInterMotionInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int16_t pMotionVector[LIST_A][30][MV_A], int16_t pMvdCache[LIST_A][30][MV_A], int8_t pRefIndex[LIST_A][30]) {
|
||||
PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
|
||||
PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
|
||||
PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
|
||||
PPicture* ppRefPic = pCtx->sRefPic.pRefList[LIST_0];
|
||||
int32_t pRefCount[2];
|
||||
int32_t i, j;
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
int16_t pMv[4] = {0};
|
||||
int16_t pMvd[4] = {0};
|
||||
int8_t iRef[2] = {0};
|
||||
int32_t iPartIdx;
|
||||
int16_t iMinVmv = pSliceHeader->pSps->pSLevelLimits->iMinVmv;
|
||||
int16_t iMaxVmv = pSliceHeader->pSps->pSLevelLimits->iMaxVmv;
|
||||
pRefCount[0] = pSliceHeader->uiRefCount[0];
|
||||
pRefCount[1] = pSliceHeader->uiRefCount[1];
|
||||
|
||||
switch (pCurDqLayer->pMbType[iMbXy]) {
|
||||
case MB_TYPE_16x16: {
|
||||
iPartIdx = 0;
|
||||
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iPartIdx, pRefCount[0], 0,
|
||||
iRef[0]));
|
||||
if ((iRef[0] < 0) || (iRef[0] >= pRefCount[0]) || (ppRefPic[iRef[0]] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
iRef[0] = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
} else {
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRef[0]]&&ppRefPic[iRef[0]]->bIsComplete);
|
||||
PredMv (pMotionVector, pRefIndex, 0, 4, iRef[0], pMv);
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
|
||||
pMv[0] += pMvd[0];
|
||||
pMv[1] += pMvd[1];
|
||||
WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
UpdateP16x16MotionInfo (pCurDqLayer, iRef[0], pMv);
|
||||
UpdateP16x16MvdCabac (pCurDqLayer, pMvd, LIST_0);
|
||||
}
|
||||
break;
|
||||
case MB_TYPE_16x8:
|
||||
for (i = 0; i < 2; i++) {
|
||||
iPartIdx = i << 3;
|
||||
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iPartIdx, pRefCount[0], 0,
|
||||
iRef[i]));
|
||||
if ((iRef[i] < 0) || (iRef[i] >= pRefCount[0]) || (ppRefPic[iRef[i]] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
iRef[i] = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
} else {
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRef[i]]&&ppRefPic[iRef[i]]->bIsComplete);
|
||||
UpdateP16x8RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, iRef[i], LIST_0);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
iPartIdx = i << 3;
|
||||
PredInter16x8Mv (pMotionVector, pRefIndex, iPartIdx, iRef[i], pMv);
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
|
||||
pMv[0] += pMvd[0];
|
||||
pMv[1] += pMvd[1];
|
||||
WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
UpdateP16x8MotionInfo (pCurDqLayer, pMotionVector, pRefIndex, iPartIdx, iRef[i], pMv);
|
||||
UpdateP16x8MvdCabac (pCurDqLayer, pMvdCache, iPartIdx, pMvd, LIST_0);
|
||||
}
|
||||
break;
|
||||
case MB_TYPE_8x16:
|
||||
for (i = 0; i < 2; i++) {
|
||||
iPartIdx = i << 2;
|
||||
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iPartIdx, pRefCount[0], 0,
|
||||
iRef[i]));
|
||||
if ((iRef[i] < 0) || (iRef[i] >= pRefCount[0]) || (ppRefPic[iRef[i]] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
iRef[i] = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
} else {
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRef[i]]&&ppRefPic[iRef[i]]->bIsComplete);
|
||||
UpdateP8x16RefIdxCabac (pCurDqLayer, pRefIndex, iPartIdx, iRef[i], LIST_0);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
iPartIdx = i << 2;
|
||||
PredInter8x16Mv (pMotionVector, pRefIndex, i << 2, iRef[i], pMv/*&mv[0], &mv[1]*/);
|
||||
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
|
||||
pMv[0] += pMvd[0];
|
||||
pMv[1] += pMvd[1];
|
||||
WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
UpdateP8x16MotionInfo (pCurDqLayer, pMotionVector, pRefIndex, iPartIdx, iRef[i], pMv);
|
||||
UpdateP8x16MvdCabac (pCurDqLayer, pMvdCache, iPartIdx, pMvd, LIST_0);
|
||||
}
|
||||
break;
|
||||
case MB_TYPE_8x8:
|
||||
case MB_TYPE_8x8_REF0: {
|
||||
int8_t pRefIdx[4] = {0}, pSubPartCount[4], pPartW[4];
|
||||
uint32_t uiSubMbType;
|
||||
//sub_mb_type, partition
|
||||
for (i = 0; i < 4; i++) {
|
||||
WELS_READ_VERIFY (ParseSubMBTypeCabac (pCtx, pNeighAvail, uiSubMbType));
|
||||
if (uiSubMbType >= 4) { //invalid sub_mb_type
|
||||
return ERR_INFO_INVALID_SUB_MB_TYPE;
|
||||
}
|
||||
pCurDqLayer->pSubMbType[iMbXy][i] = g_ksInterSubMbTypeInfo[uiSubMbType].iType;
|
||||
pSubPartCount[i] = g_ksInterSubMbTypeInfo[uiSubMbType].iPartCount;
|
||||
pPartW[i] = g_ksInterSubMbTypeInfo[uiSubMbType].iPartWidth;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int16_t iIdx8 = i << 2;
|
||||
WELS_READ_VERIFY (ParseRefIdxCabac (pCtx, pNeighAvail, pNonZeroCount, pRefIndex, LIST_0, iIdx8, pRefCount[0], 1,
|
||||
pRefIdx[i]));
|
||||
if ((pRefIdx[i] < 0) || (pRefIdx[i] >= pRefCount[0]) || (ppRefPic[pRefIdx[i]] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
pRefIdx[i] = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
} else {
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[pRefIdx[i]]&&ppRefPic[pRefIdx[i]]->bIsComplete);
|
||||
UpdateP8x8RefIdxCabac (pCurDqLayer, pRefIndex, iIdx8, pRefIdx[i], LIST_0);
|
||||
}
|
||||
//mv
|
||||
for (i = 0; i < 4; i++) {
|
||||
int8_t iPartCount = pSubPartCount[i];
|
||||
uiSubMbType = pCurDqLayer->pSubMbType[iMbXy][i];
|
||||
int16_t iPartIdx, iBlockW = pPartW[i];
|
||||
uint8_t iScan4Idx, iCacheIdx;
|
||||
iCacheIdx = g_kuiCache30ScanIdx[i << 2];
|
||||
pRefIndex[0][iCacheIdx ] = pRefIndex[0][iCacheIdx + 1]
|
||||
= pRefIndex[0][iCacheIdx + 6] = pRefIndex[0][iCacheIdx + 7] = pRefIdx[i];
|
||||
|
||||
for (j = 0; j < iPartCount; j++) {
|
||||
iPartIdx = (i << 2) + j * iBlockW;
|
||||
iScan4Idx = g_kuiScan4[iPartIdx];
|
||||
iCacheIdx = g_kuiCache30ScanIdx[iPartIdx];
|
||||
PredMv (pMotionVector, pRefIndex, iPartIdx, iBlockW, pRefIdx[i], pMv);
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 0, pMvd[0]));
|
||||
WELS_READ_VERIFY (ParseMvdInfoCabac (pCtx, pNeighAvail, pRefIndex, pMvdCache, iPartIdx, LIST_0, 1, pMvd[1]));
|
||||
pMv[0] += pMvd[0];
|
||||
pMv[1] += pMvd[1];
|
||||
WELS_CHECK_SE_BOTH_WARNING (pMv[1], iMinVmv, iMaxVmv, "vertical mv");
|
||||
if (SUB_MB_TYPE_8x8 == uiSubMbType) {
|
||||
ST32 ((pMv + 2), LD32 (pMv));
|
||||
ST32 ((pMvd + 2), LD32 (pMvd));
|
||||
ST64 (pCurDqLayer->pMv[0][iMbXy][iScan4Idx], LD64 (pMv));
|
||||
ST64 (pCurDqLayer->pMv[0][iMbXy][iScan4Idx + 4], LD64 (pMv));
|
||||
ST64 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx], LD64 (pMvd));
|
||||
ST64 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx + 4], LD64 (pMvd));
|
||||
ST64 (pMotionVector[0][iCacheIdx ], LD64 (pMv));
|
||||
ST64 (pMotionVector[0][iCacheIdx + 6], LD64 (pMv));
|
||||
ST64 (pMvdCache[0][iCacheIdx ], LD64 (pMvd));
|
||||
ST64 (pMvdCache[0][iCacheIdx + 6], LD64 (pMvd));
|
||||
} else if (SUB_MB_TYPE_8x4 == uiSubMbType) {
|
||||
ST32 ((pMv + 2), LD32 (pMv));
|
||||
ST32 ((pMvd + 2), LD32 (pMvd));
|
||||
ST64 (pCurDqLayer->pMv[0][iMbXy][iScan4Idx ], LD64 (pMv));
|
||||
ST64 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx ], LD64 (pMvd));
|
||||
ST64 (pMotionVector[0][iCacheIdx ], LD64 (pMv));
|
||||
ST64 (pMvdCache[0][iCacheIdx ], LD64 (pMvd));
|
||||
} else if (SUB_MB_TYPE_4x8 == uiSubMbType) {
|
||||
ST32 (pCurDqLayer->pMv[0][iMbXy][iScan4Idx ], LD32 (pMv));
|
||||
ST32 (pCurDqLayer->pMv[0][iMbXy][iScan4Idx + 4], LD32 (pMv));
|
||||
ST32 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx ], LD32 (pMvd));
|
||||
ST32 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx + 4], LD32 (pMvd));
|
||||
ST32 (pMotionVector[0][iCacheIdx ], LD32 (pMv));
|
||||
ST32 (pMotionVector[0][iCacheIdx + 6], LD32 (pMv));
|
||||
ST32 (pMvdCache[0][iCacheIdx ], LD32 (pMvd));
|
||||
ST32 (pMvdCache[0][iCacheIdx + 6], LD32 (pMvd));
|
||||
} else { //SUB_MB_TYPE_4x4
|
||||
ST32 (pCurDqLayer->pMv[0][iMbXy][iScan4Idx ], LD32 (pMv));
|
||||
ST32 (pCurDqLayer->pMvd[0][iMbXy][iScan4Idx ], LD32 (pMvd));
|
||||
ST32 (pMotionVector[0][iCacheIdx ], LD32 (pMv));
|
||||
ST32 (pMvdCache[0][iCacheIdx ], LD32 (pMvd));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseRefIdxCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint8_t* nzc,
|
||||
int8_t ref_idx[LIST_A][30],
|
||||
int32_t iListIdx, int32_t iZOrderIdx, int32_t iActiveRefNum, int32_t b8mode, int8_t& iRefIdxVal) {
|
||||
if (iActiveRefNum == 1) {
|
||||
iRefIdxVal = 0;
|
||||
return ERR_NONE;
|
||||
}
|
||||
uint32_t uiCode;
|
||||
int32_t iIdxA = 0, iIdxB = 0;
|
||||
int32_t iCtxInc;
|
||||
int8_t* pRefIdxInMB = pCtx->pCurDqLayer->pRefIndex[LIST_0][pCtx->pCurDqLayer->iMbXyIndex];
|
||||
if (iZOrderIdx == 0) {
|
||||
iIdxB = (pNeighAvail->iTopAvail && pNeighAvail->iTopType != MB_TYPE_INTRA_PCM
|
||||
&& ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 6] > 0);
|
||||
iIdxA = (pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
|
||||
&& ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 1] > 0);
|
||||
} else if (iZOrderIdx == 4) {
|
||||
iIdxB = (pNeighAvail->iTopAvail && pNeighAvail->iTopType != MB_TYPE_INTRA_PCM
|
||||
&& ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 6] > 0);
|
||||
iIdxA = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 1] > 0;
|
||||
} else if (iZOrderIdx == 8) {
|
||||
iIdxB = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 4] > 0;
|
||||
iIdxA = (pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
|
||||
&& ref_idx[iListIdx][g_kuiCache30ScanIdx[iZOrderIdx] - 1] > 0);
|
||||
} else {
|
||||
iIdxB = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 4] > 0;
|
||||
iIdxA = pRefIdxInMB[g_kuiScan4[iZOrderIdx] - 1] > 0;
|
||||
}
|
||||
|
||||
iCtxInc = iIdxA + (iIdxB << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_REF_NO + iCtxInc, uiCode));
|
||||
if (uiCode) {
|
||||
WELS_READ_VERIFY (DecodeUnaryBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_REF_NO + 4, 1, uiCode));
|
||||
++uiCode;
|
||||
}
|
||||
iRefIdxVal = (int8_t) uiCode;
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseMvdInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, int8_t pRefIndex[LIST_A][30],
|
||||
int16_t pMvdCache[LIST_A][30][2], int32_t index, int8_t iListIdx, int8_t iMvComp, int16_t& iMvdVal) {
|
||||
uint32_t uiCode;
|
||||
int32_t iIdxA = 0;
|
||||
//int32_t sym;
|
||||
int32_t iCtxInc;
|
||||
PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_MVD + iMvComp * CTX_NUM_MVD;
|
||||
iMvdVal = 0;
|
||||
if (pRefIndex[iListIdx][g_kuiCache30ScanIdx[index] - 6] >= 0)
|
||||
iIdxA = WELS_ABS (pMvdCache[iListIdx][g_kuiCache30ScanIdx[index] - 6][iMvComp]);
|
||||
if (pRefIndex[iListIdx][g_kuiCache30ScanIdx[index] - 1] >= 0)
|
||||
iIdxA += WELS_ABS (pMvdCache[iListIdx][g_kuiCache30ScanIdx[index] - 1][iMvComp]);
|
||||
|
||||
if (iIdxA < 3)
|
||||
iCtxInc = 0;
|
||||
else if (iIdxA > 32)
|
||||
iCtxInc = 2;
|
||||
else
|
||||
iCtxInc = 1;
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pBinCtx + iCtxInc, uiCode));
|
||||
if (uiCode) {
|
||||
WELS_READ_VERIFY (DecodeUEGMvCabac (pCtx->pCabacDecEngine, pBinCtx + 3, 3, uiCode));
|
||||
iMvdVal = (int16_t) (uiCode + 1);
|
||||
WELS_READ_VERIFY (DecodeBypassCabac (pCtx->pCabacDecEngine, uiCode));
|
||||
if (uiCode) {
|
||||
iMvdVal = -iMvdVal;
|
||||
}
|
||||
} else {
|
||||
iMvdVal = 0;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseCbpInfoCabac (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiCbp) {
|
||||
int32_t iIdxA = 0, iIdxB = 0, pALeftMb[2], pBTopMb[2];
|
||||
uiCbp = 0;
|
||||
uint32_t pCbpBit[6];
|
||||
int32_t iCtxInc;
|
||||
|
||||
//Luma: bit by bit for 4 8x8 blocks in z-order
|
||||
pBTopMb[0] = pNeighAvail->iTopAvail && pNeighAvail->iTopType != MB_TYPE_INTRA_PCM
|
||||
&& ((pNeighAvail->iTopCbp & (1 << 2)) == 0);
|
||||
pBTopMb[1] = pNeighAvail->iTopAvail && pNeighAvail->iTopType != MB_TYPE_INTRA_PCM
|
||||
&& ((pNeighAvail->iTopCbp & (1 << 3)) == 0);
|
||||
pALeftMb[0] = pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
|
||||
&& ((pNeighAvail->iLeftCbp & (1 << 1)) == 0);
|
||||
pALeftMb[1] = pNeighAvail->iLeftAvail && pNeighAvail->iLeftType != MB_TYPE_INTRA_PCM
|
||||
&& ((pNeighAvail->iLeftCbp & (1 << 3)) == 0);
|
||||
|
||||
//left_top 8x8 block
|
||||
iCtxInc = pALeftMb[0] + (pBTopMb[0] << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[0]));
|
||||
if (pCbpBit[0])
|
||||
uiCbp += 0x01;
|
||||
|
||||
//right_top 8x8 block
|
||||
iIdxA = !pCbpBit[0];
|
||||
iCtxInc = iIdxA + (pBTopMb[1] << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[1]));
|
||||
if (pCbpBit[1])
|
||||
uiCbp += 0x02;
|
||||
|
||||
//left_bottom 8x8 block
|
||||
iIdxB = !pCbpBit[0];
|
||||
iCtxInc = pALeftMb[1] + (iIdxB << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[2]));
|
||||
if (pCbpBit[2])
|
||||
uiCbp += 0x04;
|
||||
|
||||
//right_bottom 8x8 block
|
||||
iIdxB = !pCbpBit[1];
|
||||
iIdxA = !pCbpBit[2];
|
||||
iCtxInc = iIdxA + (iIdxB << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + iCtxInc, pCbpBit[3]));
|
||||
if (pCbpBit[3])
|
||||
uiCbp += 0x08;
|
||||
|
||||
//Chroma: bit by bit
|
||||
iIdxB = pNeighAvail->iTopAvail && (pNeighAvail->iTopType == MB_TYPE_INTRA_PCM || (pNeighAvail->iTopCbp >> 4));
|
||||
iIdxA = pNeighAvail->iLeftAvail && (pNeighAvail->iLeftType == MB_TYPE_INTRA_PCM || (pNeighAvail->iLeftCbp >> 4));
|
||||
|
||||
//BitIdx = 0
|
||||
iCtxInc = iIdxA + (iIdxB << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + CTX_NUM_CBP + iCtxInc,
|
||||
pCbpBit[4]));
|
||||
|
||||
//BitIdx = 1
|
||||
if (pCbpBit[4]) {
|
||||
iIdxB = pNeighAvail->iTopAvail && (pNeighAvail->iTopType == MB_TYPE_INTRA_PCM || (pNeighAvail->iTopCbp >> 4) == 2);
|
||||
iIdxA = pNeighAvail->iLeftAvail && (pNeighAvail->iLeftType == MB_TYPE_INTRA_PCM || (pNeighAvail->iLeftCbp >> 4) == 2);
|
||||
iCtxInc = iIdxA + (iIdxB << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine,
|
||||
pCtx->pCabacCtx + NEW_CTX_OFFSET_CBP + 2 * CTX_NUM_CBP + iCtxInc,
|
||||
pCbpBit[5]));
|
||||
uiCbp += 1 << (4 + pCbpBit[5]);
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseDeltaQpCabac (PWelsDecoderContext pCtx, int32_t& iQpDelta) {
|
||||
uint32_t uiCode;
|
||||
PSlice pCurrSlice = & (pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer);
|
||||
iQpDelta = 0;
|
||||
PWelsCabacCtx pBinCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_DELTA_QP;
|
||||
int32_t iCtxInc = (pCurrSlice->iLastDeltaQp != 0);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pBinCtx + iCtxInc, uiCode));
|
||||
if (uiCode != 0) {
|
||||
WELS_READ_VERIFY (DecodeUnaryBinCabac (pCtx->pCabacDecEngine, pBinCtx + 2, 1, uiCode));
|
||||
uiCode++;
|
||||
iQpDelta = (uiCode + 1) >> 1;
|
||||
if ((uiCode & 1) == 0)
|
||||
iQpDelta = - iQpDelta;
|
||||
}
|
||||
pCurrSlice->iLastDeltaQp = iQpDelta;
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseCbfInfoCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNzcCache, int32_t iZIndex, int32_t iResProperty,
|
||||
PWelsDecoderContext pCtx, uint32_t& uiCbfBit) {
|
||||
int8_t nA, nB/*, zigzag_idx = 0*/;
|
||||
int32_t iCurrBlkXy = pCtx->pCurDqLayer->iMbXyIndex;
|
||||
int32_t iTopBlkXy = iCurrBlkXy - pCtx->pCurDqLayer->iMbWidth; //default value: MB neighboring
|
||||
int32_t iLeftBlkXy = iCurrBlkXy - 1; //default value: MB neighboring
|
||||
uint8_t* pCbfDc = pCtx->pCurDqLayer->pCbfDc;
|
||||
int8_t* pMbType = pCtx->pCurDqLayer->pMbType;
|
||||
int32_t iCtxInc;
|
||||
uiCbfBit = 0;
|
||||
nA = nB = IS_INTRA (pMbType[iCurrBlkXy]);
|
||||
|
||||
if (iResProperty == I16_LUMA_DC || iResProperty == CHROMA_DC_U || iResProperty == CHROMA_DC_V) { //DC
|
||||
if (pNeighAvail->iTopAvail)
|
||||
nB = (pMbType[iTopBlkXy] == MB_TYPE_INTRA_PCM) || ((pCbfDc[iTopBlkXy] >> iResProperty) & 1);
|
||||
if (pNeighAvail->iLeftAvail)
|
||||
nA = (pMbType[iLeftBlkXy] == MB_TYPE_INTRA_PCM) || ((pCbfDc[iLeftBlkXy] >> iResProperty) & 1);
|
||||
iCtxInc = nA + (nB << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine,
|
||||
pCtx->pCabacCtx + NEW_CTX_OFFSET_CBF + g_kBlockCat2CtxOffsetCBF[iResProperty] + iCtxInc, uiCbfBit));
|
||||
if (uiCbfBit)
|
||||
pCbfDc[iCurrBlkXy] |= (1 << iResProperty);
|
||||
} else { //AC
|
||||
//for 4x4 blk, make sure blk-idx is correct
|
||||
if (pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 8] != 0xff) { //top blk available
|
||||
if (g_kTopBlkInsideMb[iZIndex])
|
||||
iTopBlkXy = iCurrBlkXy;
|
||||
nB = pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 8] || pMbType[iTopBlkXy] == MB_TYPE_INTRA_PCM;
|
||||
}
|
||||
if (pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 1] != 0xff) { //left blk available
|
||||
if (g_kLeftBlkInsideMb[iZIndex])
|
||||
iLeftBlkXy = iCurrBlkXy;
|
||||
nA = pNzcCache[g_kCacheNzcScanIdx[iZIndex] - 1] || pMbType[iLeftBlkXy] == MB_TYPE_INTRA_PCM;
|
||||
}
|
||||
|
||||
iCtxInc = nA + (nB << 1);
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine,
|
||||
pCtx->pCabacCtx + NEW_CTX_OFFSET_CBF + g_kBlockCat2CtxOffsetCBF[iResProperty] + iCtxInc, uiCbfBit));
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseSignificantMapCabac (int32_t* pSignificantMap, int32_t iResProperty, PWelsDecoderContext pCtx,
|
||||
uint32_t& uiCoeffNum) {
|
||||
uint32_t uiCode;
|
||||
PWelsCabacCtx pMapCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_MAP + g_kBlockCat2CtxOffsetMap [iResProperty];
|
||||
PWelsCabacCtx pLastCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_LAST + g_kBlockCat2CtxOffsetLast[iResProperty];
|
||||
|
||||
int32_t i;
|
||||
uiCoeffNum = 0;
|
||||
int32_t i0 = 0;
|
||||
int32_t i1 = g_kMaxPos[iResProperty];
|
||||
|
||||
for (i = i0; i < i1; ++i) {
|
||||
//read significant
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pMapCtx + i, uiCode));
|
||||
if (uiCode) {
|
||||
* (pSignificantMap++) = 1;
|
||||
++ uiCoeffNum;
|
||||
//read last significant
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pLastCtx + i, uiCode));
|
||||
if (uiCode) {
|
||||
memset (pSignificantMap, 0, (i1 - i) * sizeof (int32_t));
|
||||
return ERR_NONE;
|
||||
}
|
||||
} else
|
||||
* (pSignificantMap++) = 0;
|
||||
}
|
||||
|
||||
//deal with last pSignificantMap if no data
|
||||
//if(i < i1+1)
|
||||
{
|
||||
*pSignificantMap = 1;
|
||||
++uiCoeffNum;
|
||||
}
|
||||
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseSignificantCoeffCabac (int32_t* pSignificant, int32_t iResProperty, PWelsDecoderContext pCtx) {
|
||||
uint32_t uiCode;
|
||||
PWelsCabacCtx pOneCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_ONE + g_kBlockCat2CtxOffsetOne[iResProperty];
|
||||
PWelsCabacCtx pAbsCtx = pCtx->pCabacCtx + NEW_CTX_OFFSET_ABS + g_kBlockCat2CtxOffsetAbs[iResProperty];
|
||||
const int16_t iMaxType = g_kMaxC2[iResProperty];
|
||||
int32_t i = g_kMaxPos[iResProperty];
|
||||
int32_t* pCoff = pSignificant + i;
|
||||
int32_t c1 = 1;
|
||||
int32_t c2 = 0;
|
||||
for (; i >= 0; --i) {
|
||||
if (*pCoff != 0) {
|
||||
WELS_READ_VERIFY (DecodeBinCabac (pCtx->pCabacDecEngine, pOneCtx + c1, uiCode));
|
||||
*pCoff += uiCode;
|
||||
if (*pCoff == 2) {
|
||||
WELS_READ_VERIFY (DecodeUEGLevelCabac (pCtx->pCabacDecEngine, pAbsCtx + c2, uiCode));
|
||||
*pCoff += uiCode;
|
||||
++c2;
|
||||
c2 = WELS_MIN (c2, iMaxType);
|
||||
c1 = 0;
|
||||
} else if (c1) {
|
||||
++c1;
|
||||
c1 = WELS_MIN (c1, 4);
|
||||
}
|
||||
WELS_READ_VERIFY (DecodeBypassCabac (pCtx->pCabacDecEngine, uiCode));
|
||||
if (uiCode)
|
||||
*pCoff = - *pCoff;
|
||||
}
|
||||
pCoff--;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseResidualBlockCabac (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCountCache, SBitStringAux* pBsAux,
|
||||
int32_t iIndex, int32_t iMaxNumCoeff,
|
||||
const uint8_t* pScanTable, int32_t iResProperty, short* sTCoeff, /*int mb_mode*/ uint8_t uiQp,
|
||||
PWelsDecoderContext pCtx) {
|
||||
int32_t iCurNzCacheIdx;
|
||||
const uint16_t* pDeQuantMul = g_kuiDequantCoeff[uiQp];
|
||||
uint32_t uiTotalCoeffNum = 0;
|
||||
uint32_t uiCbpBit;
|
||||
int32_t pSignificantMap[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
WELS_READ_VERIFY (ParseCbfInfoCabac (pNeighAvail, pNonZeroCountCache, iIndex, iResProperty, pCtx, uiCbpBit));
|
||||
if (uiCbpBit) { //has coeff
|
||||
WELS_READ_VERIFY (ParseSignificantMapCabac (pSignificantMap, iResProperty, pCtx, uiTotalCoeffNum));
|
||||
WELS_READ_VERIFY (ParseSignificantCoeffCabac (pSignificantMap, iResProperty, pCtx));
|
||||
}
|
||||
|
||||
iCurNzCacheIdx = g_kCacheNzcScanIdx[iIndex];
|
||||
pNonZeroCountCache[iCurNzCacheIdx] = (uint8_t)uiTotalCoeffNum;
|
||||
if (uiTotalCoeffNum == 0) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
int32_t j = 0;
|
||||
if (iResProperty == I16_LUMA_DC) {
|
||||
do {
|
||||
if (pSignificantMap[j] != 0)
|
||||
sTCoeff[pScanTable[j]] = pSignificantMap[j];
|
||||
++j;
|
||||
} while (j < 16);
|
||||
} else if (iResProperty == CHROMA_DC_U || iResProperty == CHROMA_DC_V) {
|
||||
do {
|
||||
if (pSignificantMap[j] != 0)
|
||||
sTCoeff[pScanTable[j]] = pSignificantMap[j] * pDeQuantMul[0];
|
||||
++j;
|
||||
} while (j < 16);
|
||||
} else { //luma ac, chroma ac
|
||||
do {
|
||||
if (pSignificantMap[j] != 0)
|
||||
sTCoeff[pScanTable[j]] = pSignificantMap[j] * pDeQuantMul[pScanTable[j] & 0x07];
|
||||
++j;
|
||||
} while (j < 16);
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t ParseIPCMInfoCabac (PWelsDecoderContext pCtx) {
|
||||
int32_t i;
|
||||
PWelsCabacDecEngine pCabacDecEngine = pCtx->pCabacDecEngine;
|
||||
SBitStringAux* pBsAux = pCtx->pCurDqLayer->pBitStringAux;
|
||||
SDqLayer* pCurLayer = pCtx->pCurDqLayer;
|
||||
int32_t iDstStrideLuma = pCurLayer->pDec->iLinesize[0];
|
||||
int32_t iDstStrideChroma = pCurLayer->pDec->iLinesize[1];
|
||||
int32_t iMbX = pCurLayer->iMbX;
|
||||
int32_t iMbY = pCurLayer->iMbY;
|
||||
int32_t iMbXy = pCurLayer->iMbXyIndex;
|
||||
|
||||
int32_t iMbOffsetLuma = (iMbX + iMbY * iDstStrideLuma) << 4;
|
||||
int32_t iMbOffsetChroma = (iMbX + iMbY * iDstStrideChroma) << 3;
|
||||
|
||||
uint8_t* pMbDstY = pCtx->pDec->pData[0] + iMbOffsetLuma;
|
||||
uint8_t* pMbDstU = pCtx->pDec->pData[1] + iMbOffsetChroma;
|
||||
uint8_t* pMbDstV = pCtx->pDec->pData[2] + iMbOffsetChroma;
|
||||
|
||||
uint8_t* pPtrSrc;
|
||||
|
||||
pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA_PCM;
|
||||
RestoreCabacDecEngineToBS (pCabacDecEngine, pBsAux);
|
||||
intX_t iBytesLeft = pBsAux->pEndBuf - pBsAux->pCurBuf;
|
||||
if (iBytesLeft < 384) {
|
||||
return ERR_CABAC_NO_BS_TO_READ;
|
||||
}
|
||||
pPtrSrc = pBsAux->pCurBuf;
|
||||
for (i = 0; i < 16; i++) { //luma
|
||||
memcpy (pMbDstY , pPtrSrc, 16);
|
||||
pMbDstY += iDstStrideLuma;
|
||||
pPtrSrc += 16;
|
||||
}
|
||||
for (i = 0; i < 8; i++) { //cb
|
||||
memcpy (pMbDstU, pPtrSrc, 8);
|
||||
pMbDstU += iDstStrideChroma;
|
||||
pPtrSrc += 8;
|
||||
}
|
||||
for (i = 0; i < 8; i++) { //cr
|
||||
memcpy (pMbDstV, pPtrSrc, 8);
|
||||
pMbDstV += iDstStrideChroma;
|
||||
pPtrSrc += 8;
|
||||
}
|
||||
|
||||
pBsAux->pCurBuf += 384;
|
||||
|
||||
pCurLayer->pLumaQp[iMbXy] = 0;
|
||||
pCurLayer->pChromaQp[iMbXy] = 0;
|
||||
memset (pCurLayer->pNzc[iMbXy], 16, sizeof (pCurLayer->pNzc[iMbXy]));
|
||||
|
||||
//step 4: cabac engine init
|
||||
WELS_READ_VERIFY (InitReadBits (pBsAux, 1));
|
||||
WELS_READ_VERIFY (InitCabacDecEngineFromBS (pCabacDecEngine, pBsAux));
|
||||
return ERR_NONE;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
namespace WelsDec {
|
||||
#define MAX_LEVEL_PREFIX 15
|
||||
void GetNeighborAvailMbType (PNeighAvail pNeighAvail, PDqLayer pCurLayer) {
|
||||
void GetNeighborAvailMbType (PWelsNeighAvail pNeighAvail, PDqLayer pCurLayer) {
|
||||
int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
|
||||
int32_t iCurXy, iTopXy = 0, iLeftXy = 0, iLeftTopXy = 0, iRightTopXy = 0;
|
||||
int32_t iCurX, iCurY;
|
||||
@@ -58,15 +58,18 @@ void GetNeighborAvailMbType (PNeighAvail pNeighAvail, PDqLayer pCurLayer) {
|
||||
iLeftXy = iCurXy - 1;
|
||||
iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
|
||||
pNeighAvail->iLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
|
||||
pNeighAvail->iLeftCbp = pNeighAvail->iLeftAvail ? pCurLayer->pCbp[iLeftXy] : 0;
|
||||
} else {
|
||||
pNeighAvail->iLeftAvail = 0;
|
||||
pNeighAvail->iLeftTopAvail = 0;
|
||||
pNeighAvail->iLeftCbp = 0;
|
||||
}
|
||||
|
||||
if (iCurY != 0) {
|
||||
iTopXy = iCurXy - pCurLayer->iMbWidth;
|
||||
iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
|
||||
pNeighAvail->iTopAvail = (iTopSliceIdc == iCurSliceIdc);
|
||||
pNeighAvail->iTopCbp = pNeighAvail->iTopAvail ? pCurLayer->pCbp[iTopXy] : 0;
|
||||
if (iCurX != 0) {
|
||||
iLeftTopXy = iTopXy - 1;
|
||||
iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
|
||||
@@ -85,6 +88,7 @@ void GetNeighborAvailMbType (PNeighAvail pNeighAvail, PDqLayer pCurLayer) {
|
||||
pNeighAvail->iTopAvail = 0;
|
||||
pNeighAvail->iLeftTopAvail = 0;
|
||||
pNeighAvail->iRightTopAvail = 0;
|
||||
pNeighAvail->iTopCbp = 0;
|
||||
}
|
||||
|
||||
pNeighAvail->iLeftType = (pNeighAvail->iLeftAvail ? pCurLayer->pMbType[iLeftXy] : 0);
|
||||
@@ -92,14 +96,11 @@ void GetNeighborAvailMbType (PNeighAvail pNeighAvail, PDqLayer pCurLayer) {
|
||||
pNeighAvail->iLeftTopType = (pNeighAvail->iLeftTopAvail ? pCurLayer->pMbType[iLeftTopXy] : 0);
|
||||
pNeighAvail->iRightTopType = (pNeighAvail->iRightTopAvail ? pCurLayer->pMbType[iRightTopXy] : 0);
|
||||
}
|
||||
void WelsFillCacheNonZeroCount (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
void WelsFillCacheNonZeroCount (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
PDqLayer pCurLayer) { //no matter slice type, intra_pred_constrained_flag
|
||||
int32_t iCurXy = pCurLayer->iMbXyIndex;
|
||||
int32_t iTopXy = 0;
|
||||
int32_t iLeftXy = 0;
|
||||
|
||||
GetNeighborAvailMbType (pNeighAvail, pCurLayer);
|
||||
|
||||
if (pNeighAvail->iTopAvail) {
|
||||
iTopXy = iCurXy - pCurLayer->iMbWidth;
|
||||
}
|
||||
@@ -143,7 +144,7 @@ void WelsFillCacheNonZeroCount (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
pNonZeroCount[5 + 8 * 5] = -1;//unavailable
|
||||
}
|
||||
}
|
||||
void WelsFillCacheConstrain1Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
void WelsFillCacheConstrain1Intra4x4 (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
PDqLayer pCurLayer) { //no matter slice type
|
||||
int32_t iCurXy = pCurLayer->iMbXyIndex;
|
||||
int32_t iTopXy = 0;
|
||||
@@ -189,7 +190,7 @@ void WelsFillCacheConstrain1Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZero
|
||||
}
|
||||
}
|
||||
|
||||
void WelsFillCacheConstrain0Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
void WelsFillCacheConstrain0Intra4x4 (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int8_t* pIntraPredMode,
|
||||
PDqLayer pCurLayer) { //no matter slice type
|
||||
int32_t iCurXy = pCurLayer->iMbXyIndex;
|
||||
int32_t iTopXy = 0;
|
||||
@@ -235,8 +236,142 @@ void WelsFillCacheConstrain0Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZero
|
||||
}
|
||||
}
|
||||
|
||||
void WelsFillCacheInter (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int16_t iMvArray[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurLayer) {
|
||||
void WelsFillCacheInterCabac(PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount, int16_t iMvArray[LIST_A][30][MV_A], int16_t iMvdCache[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurLayer)
|
||||
{
|
||||
int32_t iCurXy = pCurLayer->iMbXyIndex;
|
||||
int32_t iTopXy = 0;
|
||||
int32_t iLeftXy = 0;
|
||||
int32_t iLeftTopXy = 0;
|
||||
int32_t iRightTopXy = 0;
|
||||
|
||||
//stuff non_zero_coeff_count from pNeighAvail(left and top)
|
||||
WelsFillCacheNonZeroCount (pNeighAvail, pNonZeroCount, pCurLayer);
|
||||
|
||||
if (pNeighAvail->iTopAvail) {
|
||||
iTopXy = iCurXy - pCurLayer->iMbWidth;
|
||||
}
|
||||
if (pNeighAvail->iLeftAvail) {
|
||||
iLeftXy = iCurXy - 1;
|
||||
}
|
||||
if (pNeighAvail->iLeftTopAvail) {
|
||||
iLeftTopXy = iCurXy - 1 - pCurLayer->iMbWidth;
|
||||
}
|
||||
if (pNeighAvail->iRightTopAvail) {
|
||||
iRightTopXy = iCurXy + 1 - pCurLayer->iMbWidth;
|
||||
}
|
||||
|
||||
//stuff mv_cache and iRefIdxArray from left and top (inter)
|
||||
if (pNeighAvail->iLeftAvail && IS_INTER (pNeighAvail->iLeftType)) {
|
||||
ST32 (iMvArray[0][ 6], LD32 (pCurLayer->pMv[0][iLeftXy][ 3]));
|
||||
ST32 (iMvArray[0][12], LD32 (pCurLayer->pMv[0][iLeftXy][ 7]));
|
||||
ST32 (iMvArray[0][18], LD32 (pCurLayer->pMv[0][iLeftXy][11]));
|
||||
ST32 (iMvArray[0][24], LD32 (pCurLayer->pMv[0][iLeftXy][15]));
|
||||
|
||||
ST32(iMvdCache[0][ 6], LD32(pCurLayer->pMvd[0][iLeftXy][ 3]));
|
||||
ST32(iMvdCache[0][12], LD32(pCurLayer->pMvd[0][iLeftXy][ 7]));
|
||||
ST32(iMvdCache[0][18], LD32(pCurLayer->pMvd[0][iLeftXy][11]));
|
||||
ST32(iMvdCache[0][24], LD32(pCurLayer->pMvd[0][iLeftXy][15]));
|
||||
|
||||
iRefIdxArray[0][ 6] = pCurLayer->pRefIndex[0][iLeftXy][ 3];
|
||||
iRefIdxArray[0][12] = pCurLayer->pRefIndex[0][iLeftXy][ 7];
|
||||
iRefIdxArray[0][18] = pCurLayer->pRefIndex[0][iLeftXy][11];
|
||||
iRefIdxArray[0][24] = pCurLayer->pRefIndex[0][iLeftXy][15];
|
||||
} else {
|
||||
ST32 (iMvArray[0][ 6], 0);
|
||||
ST32 (iMvArray[0][12], 0);
|
||||
ST32 (iMvArray[0][18], 0);
|
||||
ST32 (iMvArray[0][24], 0);
|
||||
|
||||
ST32(iMvdCache[0][ 6], 0);
|
||||
ST32(iMvdCache[0][12], 0);
|
||||
ST32(iMvdCache[0][18], 0);
|
||||
ST32(iMvdCache[0][24], 0);
|
||||
|
||||
|
||||
if (0 == pNeighAvail->iLeftAvail) { //not available
|
||||
iRefIdxArray[0][ 6] =
|
||||
iRefIdxArray[0][12] =
|
||||
iRefIdxArray[0][18] =
|
||||
iRefIdxArray[0][24] = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iRefIdxArray[0][ 6] =
|
||||
iRefIdxArray[0][12] =
|
||||
iRefIdxArray[0][18] =
|
||||
iRefIdxArray[0][24] = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
if (pNeighAvail->iLeftTopAvail && IS_INTER (pNeighAvail->iLeftTopType)) {
|
||||
ST32 (iMvArray[0][0], LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
|
||||
ST32(iMvdCache[0][0], LD32(pCurLayer->pMvd[0][iLeftTopXy][15]));
|
||||
iRefIdxArray[0][0] = pCurLayer->pRefIndex[0][iLeftTopXy][15];
|
||||
} else {
|
||||
ST32 (iMvArray[0][0], 0);
|
||||
ST32(iMvdCache[0][0], 0);
|
||||
if (0 == pNeighAvail->iLeftTopAvail) { //not available
|
||||
iRefIdxArray[0][0] = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iRefIdxArray[0][0] = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
if (pNeighAvail->iTopAvail && IS_INTER (pNeighAvail->iTopType)) {
|
||||
ST64 (iMvArray[0][1], LD64 (pCurLayer->pMv[0][iTopXy][12]));
|
||||
ST64 (iMvArray[0][3], LD64 (pCurLayer->pMv[0][iTopXy][14]));
|
||||
ST64(iMvdCache[0][1], LD64(pCurLayer->pMvd[0][iTopXy][12]));
|
||||
ST64(iMvdCache[0][3], LD64(pCurLayer->pMvd[0][iTopXy][14]));
|
||||
ST32 (&iRefIdxArray[0][1], LD32 (&pCurLayer->pRefIndex[0][iTopXy][12]));
|
||||
} else {
|
||||
ST64 (iMvArray[0][1], 0);
|
||||
ST64 (iMvArray[0][3], 0);
|
||||
ST64(iMvdCache[0][1], 0);
|
||||
ST64(iMvdCache[0][3], 0);
|
||||
if (0 == pNeighAvail->iTopAvail) { //not available
|
||||
iRefIdxArray[0][1] =
|
||||
iRefIdxArray[0][2] =
|
||||
iRefIdxArray[0][3] =
|
||||
iRefIdxArray[0][4] = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iRefIdxArray[0][1] =
|
||||
iRefIdxArray[0][2] =
|
||||
iRefIdxArray[0][3] =
|
||||
iRefIdxArray[0][4] = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
if (pNeighAvail->iRightTopAvail && IS_INTER (pNeighAvail->iRightTopType)) {
|
||||
ST32 (iMvArray[0][5], LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
|
||||
ST32(iMvdCache[0][5], LD32(pCurLayer->pMvd[0][iRightTopXy][12]));
|
||||
iRefIdxArray[0][5] = pCurLayer->pRefIndex[0][iRightTopXy][12];
|
||||
} else {
|
||||
ST32 (iMvArray[0][5], 0);
|
||||
if (0 == pNeighAvail->iRightTopAvail) { //not available
|
||||
iRefIdxArray[0][5] = REF_NOT_AVAIL;
|
||||
} else { //available but is intra mb type
|
||||
iRefIdxArray[0][5] = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
//right-top 4*4 block unavailable
|
||||
ST32 (iMvArray[0][ 9], 0);
|
||||
ST32 (iMvArray[0][21], 0);
|
||||
ST32 (iMvArray[0][11], 0);
|
||||
ST32 (iMvArray[0][17], 0);
|
||||
ST32 (iMvArray[0][23], 0);
|
||||
ST32(iMvdCache[0][ 9], 0);
|
||||
ST32(iMvdCache[0][21], 0);
|
||||
ST32(iMvdCache[0][11], 0);
|
||||
ST32(iMvdCache[0][17], 0);
|
||||
ST32(iMvdCache[0][23], 0);
|
||||
iRefIdxArray[0][ 9] =
|
||||
iRefIdxArray[0][21] =
|
||||
iRefIdxArray[0][11] =
|
||||
iRefIdxArray[0][17] =
|
||||
iRefIdxArray[0][23] = REF_NOT_AVAIL;
|
||||
}
|
||||
|
||||
void WelsFillCacheInter (PWelsNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
int16_t iMvArray[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30], PDqLayer pCurLayer)
|
||||
{
|
||||
int32_t iCurXy = pCurLayer->iMbXyIndex;
|
||||
int32_t iTopXy = 0;
|
||||
int32_t iLeftXy = 0;
|
||||
@@ -298,7 +433,6 @@ void WelsFillCacheInter (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
iRefIdxArray[0][0] = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
if (pNeighAvail->iTopAvail && IS_INTER (pNeighAvail->iTopType)) {
|
||||
ST64 (iMvArray[0][1], LD64 (pCurLayer->pMv[0][iTopXy][12]));
|
||||
ST64 (iMvArray[0][3], LD64 (pCurLayer->pMv[0][iTopXy][14]));
|
||||
@@ -306,7 +440,6 @@ void WelsFillCacheInter (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
} else {
|
||||
ST64 (iMvArray[0][1], 0);
|
||||
ST64 (iMvArray[0][3], 0);
|
||||
|
||||
if (0 == pNeighAvail->iTopAvail) { //not available
|
||||
iRefIdxArray[0][1] =
|
||||
iRefIdxArray[0][2] =
|
||||
@@ -319,7 +452,6 @@ void WelsFillCacheInter (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
iRefIdxArray[0][4] = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
if (pNeighAvail->iRightTopAvail && IS_INTER (pNeighAvail->iRightTopType)) {
|
||||
ST32 (iMvArray[0][5], LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
|
||||
iRefIdxArray[0][5] = pCurLayer->pRefIndex[0][iRightTopXy][12];
|
||||
@@ -331,7 +463,6 @@ void WelsFillCacheInter (PNeighAvail pNeighAvail, uint8_t* pNonZeroCount,
|
||||
iRefIdxArray[0][5] = REF_NOT_IN_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
//right-top 4*4 block unavailable
|
||||
ST32 (iMvArray[0][ 9], 0);
|
||||
ST32 (iMvArray[0][21], 0);
|
||||
@@ -358,9 +489,6 @@ int32_t PredIntra4x4Mode (int8_t* pIntraPredMode, int32_t iIdx4) {
|
||||
return iBestMode;
|
||||
}
|
||||
|
||||
#define MAX_PRED_MODE_ID_I16x16 3
|
||||
#define MAX_PRED_MODE_ID_CHROMA 3
|
||||
#define MAX_PRED_MODE_ID_I4x4 8
|
||||
#define CHECK_I16_MODE(a, b, c, d) \
|
||||
((a == g_ksI16PredInfo[a].iPredMode) && \
|
||||
(b >= g_ksI16PredInfo[a].iLeftAvail) && \
|
||||
@@ -760,216 +888,6 @@ int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCach
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ParseIntra4x4ModeConstrain0 (PNeighAvail pNeighAvail, int8_t* pIntraPredMode, PBitStringAux pBs,
|
||||
PDqLayer pCurDqLayer) {
|
||||
int32_t iSampleAvail[5 * 6] = { 0 }; //initialize as 0
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
int32_t iFinalMode, i;
|
||||
|
||||
uint8_t uiNeighAvail = 0;
|
||||
uint32_t uiCode;
|
||||
if (pNeighAvail->iLeftAvail) { //left
|
||||
iSampleAvail[ 6] =
|
||||
iSampleAvail[12] =
|
||||
iSampleAvail[18] =
|
||||
iSampleAvail[24] = 1;
|
||||
}
|
||||
if (pNeighAvail->iLeftTopAvail) { //top_left
|
||||
iSampleAvail[0] = 1;
|
||||
}
|
||||
if (pNeighAvail->iTopAvail) { //top
|
||||
iSampleAvail[1] =
|
||||
iSampleAvail[2] =
|
||||
iSampleAvail[3] =
|
||||
iSampleAvail[4] = 1;
|
||||
}
|
||||
if (pNeighAvail->iRightTopAvail) { //top_right
|
||||
iSampleAvail[5] = 1;
|
||||
}
|
||||
|
||||
uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ]
|
||||
const int32_t kiPrevIntra4x4PredMode = uiCode;
|
||||
const int32_t kiPredMode = PredIntra4x4Mode (pIntraPredMode, i);
|
||||
|
||||
int8_t iBestMode;
|
||||
if (kiPrevIntra4x4PredMode) {
|
||||
iBestMode = kiPredMode;
|
||||
} else { //kPrevIntra4x4PredMode == 0
|
||||
WELS_READ_VERIFY (BsGetBits (pBs, 3, &uiCode)); //rem_intra4x4_pred_mode[ luma4x4BlkIdx ]
|
||||
const int32_t kiRemIntra4x4PredMode = uiCode;
|
||||
if (kiRemIntra4x4PredMode < kiPredMode) {
|
||||
iBestMode = kiRemIntra4x4PredMode;
|
||||
} else {
|
||||
iBestMode = kiRemIntra4x4PredMode + 1;
|
||||
}
|
||||
}
|
||||
|
||||
iFinalMode = CheckIntra4x4PredMode (&iSampleAvail[0], &iBestMode, i);
|
||||
if (iFinalMode == ERR_INVALID_INTRA4X4_MODE) {
|
||||
return ERR_INFO_INVALID_I4x4_PRED_MODE;
|
||||
}
|
||||
|
||||
pCurDqLayer->pIntra4x4FinalMode[iMbXy][g_kuiScan4[i]] = iFinalMode;
|
||||
|
||||
pIntraPredMode[g_kuiScan8[i]] = iBestMode;
|
||||
|
||||
iSampleAvail[g_kuiCache30ScanIdx[i]] = 1;
|
||||
}
|
||||
ST32 (&pCurDqLayer->pIntraPredMode[iMbXy][0], LD32 (&pIntraPredMode[1 + 8 * 4]));
|
||||
pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1];
|
||||
pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2];
|
||||
pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3];
|
||||
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
|
||||
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
|
||||
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ParseIntra4x4ModeConstrain1 (PNeighAvail pNeighAvail, int8_t* pIntraPredMode, PBitStringAux pBs,
|
||||
PDqLayer pCurDqLayer) {
|
||||
int32_t iSampleAvail[5 * 6] = { 0 }; //initialize as 0
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
int32_t iFinalMode, i;
|
||||
|
||||
uint8_t uiNeighAvail = 0;
|
||||
uint32_t uiCode;
|
||||
if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) { //left
|
||||
iSampleAvail[ 6] =
|
||||
iSampleAvail[12] =
|
||||
iSampleAvail[18] =
|
||||
iSampleAvail[24] = 1;
|
||||
}
|
||||
if (pNeighAvail->iLeftTopAvail && IS_INTRA (pNeighAvail->iLeftTopType)) { //top_left
|
||||
iSampleAvail[0] = 1;
|
||||
}
|
||||
if (pNeighAvail->iTopAvail && IS_INTRA (pNeighAvail->iTopType)) { //top
|
||||
iSampleAvail[1] =
|
||||
iSampleAvail[2] =
|
||||
iSampleAvail[3] =
|
||||
iSampleAvail[4] = 1;
|
||||
}
|
||||
if (pNeighAvail->iRightTopAvail && IS_INTRA (pNeighAvail->iRightTopType)) { //top_right
|
||||
iSampleAvail[5] = 1;
|
||||
}
|
||||
|
||||
uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ]
|
||||
const int32_t kiPrevIntra4x4PredMode = uiCode; //1bit
|
||||
const int32_t kiPredMode = PredIntra4x4Mode (pIntraPredMode, i);
|
||||
|
||||
int8_t iBestMode;
|
||||
if (kiPrevIntra4x4PredMode) {
|
||||
iBestMode = kiPredMode;
|
||||
} else { //kPrevIntra4x4PredMode == 0
|
||||
WELS_READ_VERIFY (BsGetBits (pBs, 3, &uiCode)); //rem_intra4x4_pred_mode[ luma4x4BlkIdx ]
|
||||
const int32_t kiRemIntra4x4PredMode = uiCode;
|
||||
if (kiRemIntra4x4PredMode < kiPredMode) {
|
||||
iBestMode = kiRemIntra4x4PredMode;
|
||||
} else {
|
||||
iBestMode = kiRemIntra4x4PredMode + 1;
|
||||
}
|
||||
}
|
||||
|
||||
iFinalMode = CheckIntra4x4PredMode (&iSampleAvail[0], &iBestMode, i);
|
||||
if (iFinalMode == ERR_INVALID_INTRA4X4_MODE) {
|
||||
return ERR_INFO_INVALID_I4x4_PRED_MODE;
|
||||
}
|
||||
|
||||
pCurDqLayer->pIntra4x4FinalMode[iMbXy][g_kuiScan4[i]] = iFinalMode;
|
||||
|
||||
pIntraPredMode[g_kuiScan8[i]] = iBestMode;
|
||||
|
||||
iSampleAvail[g_kuiCache30ScanIdx[i]] = 1;
|
||||
}
|
||||
ST32 (&pCurDqLayer->pIntraPredMode[iMbXy][0], LD32 (&pIntraPredMode[1 + 8 * 4]));
|
||||
pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1];
|
||||
pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2];
|
||||
pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3];
|
||||
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
|
||||
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
|
||||
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ParseIntra16x16ModeConstrain0 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer) {
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
uint8_t uiNeighAvail = 0; //0x07 = 0 1 1 1, means left, top-left, top avail or not. (1: avail, 0: unavail)
|
||||
uint32_t uiCode;
|
||||
if (pNeighAvail->iLeftAvail) {
|
||||
uiNeighAvail = (1 << 2);
|
||||
}
|
||||
if (pNeighAvail->iLeftTopAvail) {
|
||||
uiNeighAvail |= (1 << 1);
|
||||
}
|
||||
if (pNeighAvail->iTopAvail) {
|
||||
uiNeighAvail |= 1;
|
||||
}
|
||||
|
||||
if (CheckIntra16x16PredMode (uiNeighAvail,
|
||||
&pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding
|
||||
return ERR_INFO_INVALID_I16x16_PRED_MODE;
|
||||
}
|
||||
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
|
||||
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
|
||||
|
||||
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ParseIntra16x16ModeConstrain1 (PNeighAvail pNeighAvail, PBitStringAux pBs, PDqLayer pCurDqLayer) {
|
||||
int32_t iMbXy = pCurDqLayer->iMbXyIndex;
|
||||
uint8_t uiNeighAvail = 0; //0x07 = 0 1 1 1, means left, top-left, top avail or not. (1: avail, 0: unavail)
|
||||
uint32_t uiCode;
|
||||
if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) {
|
||||
uiNeighAvail = (1 << 2);
|
||||
}
|
||||
if (pNeighAvail->iLeftTopAvail && IS_INTRA (pNeighAvail->iLeftTopType)) {
|
||||
uiNeighAvail |= (1 << 1);
|
||||
}
|
||||
if (pNeighAvail->iTopAvail && IS_INTRA (pNeighAvail->iTopType)) {
|
||||
uiNeighAvail |= 1;
|
||||
}
|
||||
|
||||
if (CheckIntra16x16PredMode (uiNeighAvail,
|
||||
&pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding
|
||||
return ERR_INFO_INVALID_I16x16_PRED_MODE;
|
||||
}
|
||||
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
|
||||
if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
|
||||
|
||||
if (CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
|
||||
return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][MV_A], int8_t iRefIdxArray[LIST_A][30],
|
||||
PBitStringAux pBs) {
|
||||
PSlice pSlice = &pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer;
|
||||
@@ -1003,6 +921,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
// Security check: iRefIdx should be in range 0 to num_ref_idx_l0_active_minus1, includsive
|
||||
// ref to standard section 7.4.5.1. iRefCount[0] is 1 + num_ref_idx_l0_active_minus1.
|
||||
if ((iRefIdx < 0) || (iRefIdx >= iRefCount[0]) || (ppRefPic[iRefIdx] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
iRefIdx = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
@@ -1010,6 +929,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx]&&ppRefPic[iRefIdx]->bIsComplete);
|
||||
} else {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
|
||||
@@ -1041,6 +961,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
|
||||
iRefIdx[i] = uiCode;
|
||||
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
iRefIdx[i] = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
@@ -1048,6 +969,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx[i]]&&ppRefPic[iRefIdx[i]]->bIsComplete);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
PredInter16x8Mv (iMvArray, iRefIdxArray, i << 3, iRefIdx[i], iMv);
|
||||
@@ -1075,6 +997,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
|
||||
iRefIdx[i] = uiCode;
|
||||
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
iRefIdx[i] = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
@@ -1082,6 +1005,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx[i]]&&ppRefPic[iRefIdx[i]]->bIsComplete);
|
||||
} else {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "inter parse: iMotionPredFlag = 1 not supported. ");
|
||||
return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP);
|
||||
@@ -1141,6 +1065,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
WELS_READ_VERIFY (BsGetTe0 (pBs, iRefCount[0], &uiCode)); //ref_idx_l0[ mbPartIdx ]
|
||||
iRefIdx[i] = uiCode;
|
||||
if ((iRefIdx[i] < 0) || (iRefIdx[i] >= iRefCount[0]) || (ppRefPic[iRefIdx[i]] == NULL)) { //error ref_idx
|
||||
pCtx->bMbRefConcealed = true;
|
||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||
iRefIdx[i] = 0;
|
||||
pCtx->iErrorCode |= dsBitstreamError;
|
||||
@@ -1148,6 +1073,7 @@ int32_t ParseInterInfo (PWelsDecoderContext pCtx, int16_t iMvArray[LIST_A][30][M
|
||||
return ERR_INFO_INVALID_REF_INDEX;
|
||||
}
|
||||
}
|
||||
pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || !(ppRefPic[iRefIdx[i]]&&ppRefPic[iRefIdx[i]]->bIsComplete);
|
||||
|
||||
pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx ] = pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx + 1] =
|
||||
pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx + 4] = pCurDqLayer->pRefIndex[0][iMbXy][uiScan4Idx + 5] = iRefIdx[i];
|
||||
|
||||
@@ -81,6 +81,7 @@ PPicture AllocPicture (PWelsDecoderContext pCtx, const int32_t kiPicWidth, const
|
||||
|
||||
iLumaSize = iPicWidth * iPicHeight;
|
||||
iChromaSize = iPicChromaWidth * iPicChromaHeight;
|
||||
|
||||
pPic->pBuffer[0] = static_cast<uint8_t*> (WelsMalloc (iLumaSize /* luma */
|
||||
+ (iChromaSize << 1) /* Cb,Cr */, "_pic->buffer[0]"));
|
||||
memset (pPic->pBuffer[0], 128, (iLumaSize + (iChromaSize << 1)));
|
||||
@@ -94,8 +95,6 @@ PPicture AllocPicture (PWelsDecoderContext pCtx, const int32_t kiPicWidth, const
|
||||
pPic->pData[1] = pPic->pBuffer[1] + /*WELS_ALIGN*/ (((1 + pPic->iLinesize[1]) * PADDING_LENGTH) >> 1);
|
||||
pPic->pData[2] = pPic->pBuffer[2] + /*WELS_ALIGN*/ (((1 + pPic->iLinesize[2]) * PADDING_LENGTH) >> 1);
|
||||
|
||||
|
||||
|
||||
pPic->iPlanes = 3; // yv12 in default
|
||||
pPic->iWidthInPixel = kiPicWidth;
|
||||
pPic->iHeightInPixel = kiPicHeight;
|
||||
|
||||
@@ -164,24 +164,7 @@ int32_t RecI16x16Mb (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLe
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
typedef struct TagMCRefMember {
|
||||
uint8_t* pDstY;
|
||||
uint8_t* pDstU;
|
||||
uint8_t* pDstV;
|
||||
|
||||
uint8_t* pSrcY;
|
||||
uint8_t* pSrcU;
|
||||
uint8_t* pSrcV;
|
||||
|
||||
int32_t iSrcLineLuma;
|
||||
int32_t iSrcLineChroma;
|
||||
|
||||
int32_t iDstLineLuma;
|
||||
int32_t iDstLineChroma;
|
||||
|
||||
int32_t iPicWidth;
|
||||
int32_t iPicHeight;
|
||||
} sMCRefMember;
|
||||
//according to current 8*8 block ref_index to gain reference picture
|
||||
static inline void GetRefPic (sMCRefMember* pMCRefMem, PWelsDecoderContext pCtx, int8_t* pRefIdxList,
|
||||
int32_t iIndex) {
|
||||
@@ -202,32 +185,18 @@ static inline void GetRefPic (sMCRefMember* pMCRefMem, PWelsDecoderContext pCtx,
|
||||
#ifndef MC_FLOW_SIMPLE_JUDGE
|
||||
#define MC_FLOW_SIMPLE_JUDGE 1
|
||||
#endif //MC_FLOW_SIMPLE_JUDGE
|
||||
static inline void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
|
||||
void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
|
||||
int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
|
||||
int32_t iExpandWidth = PADDING_LENGTH;
|
||||
int32_t iExpandHeight = PADDING_LENGTH;
|
||||
|
||||
|
||||
int16_t iMVX = iMVs[0] >> 2;
|
||||
int16_t iMVY = iMVs[1] >> 2;
|
||||
int32_t iMVOffsetLuma = iMVX + iMVY * pMCRefMem->iSrcLineLuma;
|
||||
int32_t iMVOffsetChroma = (iMVX >> 1) + (iMVY >> 1) * pMCRefMem->iSrcLineChroma;
|
||||
|
||||
int32_t iFullMVx = (iXOffset << 2) + iMVs[0]; //quarter pixel
|
||||
int32_t iFullMVy = (iYOffset << 2) + iMVs[1];
|
||||
int32_t iIntMVx = iFullMVx >> 2;//integer pixel
|
||||
int32_t iIntMVy = iFullMVy >> 2;
|
||||
iFullMVx = WELS_CLIP3 (iFullMVx, ((-PADDING_LENGTH + 2) << 2), ((pMCRefMem->iPicWidth + PADDING_LENGTH - 19) << 2));
|
||||
iFullMVy = WELS_CLIP3 (iFullMVy, ((-PADDING_LENGTH + 2) << 2), ((pMCRefMem->iPicHeight + PADDING_LENGTH - 19) << 2));
|
||||
|
||||
int32_t iSrcPixOffsetLuma = iXOffset + iYOffset * pMCRefMem->iSrcLineLuma;
|
||||
int32_t iSrcPixOffsetChroma = (iXOffset >> 1) + (iYOffset >> 1) * pMCRefMem->iSrcLineChroma;
|
||||
int32_t iSrcPixOffsetLuma = (iFullMVx >> 2) + (iFullMVy >> 2) * pMCRefMem->iSrcLineLuma;
|
||||
int32_t iSrcPixOffsetChroma = (iFullMVx >> 3) + (iFullMVy >> 3) * pMCRefMem->iSrcLineChroma;
|
||||
|
||||
int32_t iBlkWidthChroma = iBlkWidth >> 1;
|
||||
int32_t iBlkHeightChroma = iBlkHeight >> 1;
|
||||
int32_t iPicWidthChroma = pMCRefMem->iPicWidth >> 1;
|
||||
int32_t iPicHeightChroma = pMCRefMem->iPicHeight >> 1;
|
||||
|
||||
//the offset only for luma padding if MV violation as there was 5-tap (-2, -1, 0, 1, 2) filter for luma (horizon and vertical)
|
||||
int32_t iPadOffset = 2 + (pMCRefMem->iSrcLineLuma << 1); //(-2, -2) pixel location as the starting point
|
||||
|
||||
uint8_t* pSrcY = pMCRefMem->pSrcY + iSrcPixOffsetLuma;
|
||||
uint8_t* pSrcU = pMCRefMem->pSrcU + iSrcPixOffsetChroma;
|
||||
@@ -235,58 +204,14 @@ static inline void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iY
|
||||
uint8_t* pDstY = pMCRefMem->pDstY;
|
||||
uint8_t* pDstU = pMCRefMem->pDstU;
|
||||
uint8_t* pDstV = pMCRefMem->pDstV;
|
||||
bool bExpand = false;
|
||||
|
||||
ENFORCE_STACK_ALIGN_1D (uint8_t, uiExpandBuf, (PADDING_LENGTH + 6) * (PADDING_LENGTH + 6), 16);
|
||||
pMCFunc->pMcLumaFunc (pSrcY, pMCRefMem->iSrcLineLuma, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,
|
||||
iBlkHeight);
|
||||
pMCFunc->pMcChromaFunc (pSrcU, pMCRefMem->iSrcLineChroma, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
|
||||
iBlkWidthChroma, iBlkHeightChroma);
|
||||
pMCFunc->pMcChromaFunc (pSrcV, pMCRefMem->iSrcLineChroma, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
|
||||
iBlkWidthChroma, iBlkHeightChroma);
|
||||
|
||||
if (iFullMVx & 0x07) {
|
||||
iExpandWidth -= 3;
|
||||
}
|
||||
if (iFullMVy & 0x07) {
|
||||
iExpandHeight -= 3;
|
||||
}
|
||||
|
||||
#ifdef MC_FLOW_SIMPLE_JUDGE
|
||||
if (iIntMVx < -iExpandWidth ||
|
||||
iIntMVy < -iExpandHeight ||
|
||||
iIntMVx + iBlkWidth > pMCRefMem->iPicWidth - 1 + iExpandWidth ||
|
||||
iIntMVy + iBlkHeight > pMCRefMem->iPicHeight - 1 + iExpandHeight)
|
||||
#else
|
||||
if (iIntMVx < -iExpandWidth ||
|
||||
iIntMVy < -iExpandHeight ||
|
||||
iIntMVx + PADDING_LENGTH > pMCRefMem->iPicWidth + iExpandWidth ||
|
||||
iIntMVy + PADDING_LENGTH > pMCRefMem->iPicHeight + iExpandHeight)
|
||||
#endif
|
||||
{
|
||||
FillBufForMc (uiExpandBuf, 21, pSrcY, pMCRefMem->iSrcLineLuma, iMVOffsetLuma - iPadOffset,
|
||||
iBlkWidth + 5, iBlkHeight + 5, iIntMVx - 2, iIntMVy - 2, pMCRefMem->iPicWidth, pMCRefMem->iPicHeight);
|
||||
pMCFunc->pMcLumaFunc (uiExpandBuf + 44, 21, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,
|
||||
iBlkHeight); //44=2+2*21
|
||||
bExpand = true;
|
||||
} else {
|
||||
pSrcY += iMVOffsetLuma;
|
||||
pMCFunc->pMcLumaFunc (pSrcY, pMCRefMem->iSrcLineLuma, pDstY, pMCRefMem->iDstLineLuma, iFullMVx, iFullMVy, iBlkWidth,
|
||||
iBlkHeight);
|
||||
}
|
||||
|
||||
if (bExpand) {
|
||||
FillBufForMc (uiExpandBuf, 21, pSrcU, pMCRefMem->iSrcLineChroma, iMVOffsetChroma, iBlkWidthChroma + 1,
|
||||
iBlkHeightChroma + 1, iFullMVx >> 3, iFullMVy >> 3, iPicWidthChroma, iPicHeightChroma);
|
||||
pMCFunc->pMcChromaFunc (uiExpandBuf, 21, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy, iBlkWidthChroma,
|
||||
iBlkHeightChroma);
|
||||
|
||||
FillBufForMc (uiExpandBuf, 21, pSrcV, pMCRefMem->iSrcLineChroma, iMVOffsetChroma, iBlkWidthChroma + 1,
|
||||
iBlkHeightChroma + 1, iFullMVx >> 3, iFullMVy >> 3, iPicWidthChroma, iPicHeightChroma);
|
||||
pMCFunc->pMcChromaFunc (uiExpandBuf, 21, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy, iBlkWidthChroma,
|
||||
iBlkHeightChroma);
|
||||
} else {
|
||||
pSrcU += iMVOffsetChroma;
|
||||
pSrcV += iMVOffsetChroma;
|
||||
pMCFunc->pMcChromaFunc (pSrcU, pMCRefMem->iSrcLineChroma, pDstU, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
|
||||
iBlkWidthChroma, iBlkHeightChroma);
|
||||
pMCFunc->pMcChromaFunc (pSrcV, pMCRefMem->iSrcLineChroma, pDstV, pMCRefMem->iDstLineChroma, iFullMVx, iFullMVy,
|
||||
iBlkWidthChroma, iBlkHeightChroma);
|
||||
}
|
||||
}
|
||||
|
||||
void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
|
||||
@@ -464,88 +389,4 @@ int32_t RecChroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLeve
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
void FillBufForMc (uint8_t* pBuf, int32_t iBufStride, uint8_t* pSrc, int32_t iSrcStride, int32_t iSrcOffset,
|
||||
int32_t iBlockWidth, int32_t iBlockHeight, int32_t iSrcX, int32_t iSrcY, int32_t iPicWidth, int32_t iPicHeight) {
|
||||
int32_t iY;
|
||||
int32_t iStartY, iStartX, iEndY, iEndX;
|
||||
int32_t iOffsetAdj = 0;
|
||||
int32_t iAddrSrc, iAddrBuf;
|
||||
int32_t iNum, iNum1;
|
||||
uint8_t* pBufSrc, *pBufDst;
|
||||
uint8_t* pBufSrc1, *pBufDst1;
|
||||
|
||||
if (iSrcY >= iPicHeight) {
|
||||
iOffsetAdj += (iPicHeight - 1 - iSrcY) * iSrcStride;
|
||||
iSrcY = iPicHeight - 1;
|
||||
} else if (iSrcY <= -iBlockHeight) {
|
||||
iOffsetAdj += (1 - iBlockHeight - iSrcY) * iSrcStride;
|
||||
iSrcY = 1 - iBlockHeight;
|
||||
}
|
||||
if (iSrcX >= iPicWidth) {
|
||||
iOffsetAdj += (iPicWidth - 1 - iSrcX);
|
||||
iSrcX = iPicWidth - 1;
|
||||
} else if (iSrcX <= -iBlockWidth) {
|
||||
iOffsetAdj += (1 - iBlockWidth - iSrcX);
|
||||
iSrcX = 1 - iBlockWidth;
|
||||
}
|
||||
|
||||
iOffsetAdj += iSrcOffset;
|
||||
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a,b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
iStartY = MAX (0, -iSrcY);
|
||||
iStartX = MAX (0, -iSrcX);
|
||||
iEndY = MIN (iBlockHeight, iPicHeight - iSrcY);
|
||||
iEndX = MIN (iBlockWidth, iPicWidth - iSrcX);
|
||||
|
||||
// copy existing part
|
||||
iAddrSrc = iStartX + iStartY * iSrcStride;
|
||||
iAddrBuf = iStartX + iStartY * iBufStride;
|
||||
iNum = iEndX - iStartX;
|
||||
for (iY = iStartY; iY < iEndY; iY++) {
|
||||
memcpy (pBuf + iAddrBuf, pSrc + iOffsetAdj + iAddrSrc, iNum);
|
||||
iAddrSrc += iSrcStride;
|
||||
iAddrBuf += iBufStride;
|
||||
}
|
||||
|
||||
//top
|
||||
pBufSrc = pBuf + iStartX + iStartY * iBufStride;
|
||||
pBufDst = pBuf + iStartX;
|
||||
iNum = iEndX - iStartX;
|
||||
for (iY = 0; iY < iStartY; iY++) {
|
||||
memcpy (pBufDst, pBufSrc, iNum);
|
||||
pBufDst += iBufStride;
|
||||
}
|
||||
|
||||
//bottom
|
||||
pBufSrc = pBuf + iStartX + (iEndY - 1) * iBufStride;
|
||||
pBufDst = pBuf + iStartX + iEndY * iBufStride;
|
||||
iNum = iEndX - iStartX;
|
||||
for (iY = iEndY; iY < iBlockHeight; iY++) {
|
||||
memcpy (pBufDst, pBufSrc, iNum);
|
||||
pBufDst += iBufStride;
|
||||
}
|
||||
|
||||
|
||||
pBufSrc = pBuf + iStartX;
|
||||
pBufDst = pBuf;
|
||||
iNum = iStartX;
|
||||
|
||||
pBufSrc1 = pBuf + iEndX - 1;
|
||||
pBufDst1 = pBuf + iEndX;
|
||||
iNum1 = iBlockWidth - iEndX;
|
||||
for (iY = 0; iY < iBlockHeight; iY++) {
|
||||
//left
|
||||
memset (pBufDst, pBufSrc[0], iNum);
|
||||
pBufDst += iBufStride;
|
||||
pBufSrc += iBufStride;
|
||||
|
||||
//right
|
||||
memset (pBufDst1, pBufSrc1[0], iNum1);
|
||||
pBufDst1 += iBufStride;
|
||||
pBufSrc1 += iBufStride;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace WelsDec
|
||||
|
||||
@@ -113,3 +113,30 @@ WELS_EXTERN IdctResAddPred_mmx
|
||||
|
||||
emms
|
||||
ret
|
||||
|
||||
;void WelsBlockZero16x16_sse2(int16_t * block, int32_t stride);
|
||||
WELS_EXTERN WelsBlockZero16x16_sse2
|
||||
%assign push_num 0
|
||||
LOAD_2_PARA
|
||||
SIGN_EXTENSION r1, r1d
|
||||
shl r1, 1
|
||||
pxor xmm0, xmm0
|
||||
%rep 16
|
||||
movdqa [r0], xmm0
|
||||
movdqa [r0+16], xmm0
|
||||
add r0, r1
|
||||
%endrep
|
||||
ret
|
||||
|
||||
;void WelsBlockZero8x8_sse2(int16_t * block, int32_t stride);
|
||||
WELS_EXTERN WelsBlockZero8x8_sse2
|
||||
%assign push_num 0
|
||||
LOAD_2_PARA
|
||||
SIGN_EXTENSION r1, r1d
|
||||
shl r1, 1
|
||||
pxor xmm0, xmm0
|
||||
%rep 8
|
||||
movdqa [r0], xmm0
|
||||
add r0, r1
|
||||
%endrep
|
||||
ret
|
||||
|
||||
@@ -104,7 +104,7 @@ virtual long EXTAPI GetOption (DECODER_OPTION eOptID, void* pOption);
|
||||
PWelsDecoderContext m_pDecContext;
|
||||
welsCodecTrace* m_pWelsTrace;
|
||||
|
||||
int32_t InitDecoder (void);
|
||||
int32_t InitDecoder (const bool);
|
||||
void UninitDecoder (void);
|
||||
|
||||
#ifdef OUTPUT_BIT_STREAM
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "decoder_core.h"
|
||||
#include "error_concealment.h"
|
||||
|
||||
#include "measure_time.h"
|
||||
extern "C" {
|
||||
#include "decoder_core.h"
|
||||
#include "manage_dec_ref.h"
|
||||
@@ -103,6 +104,7 @@ CWelsDecoder::CWelsDecoder (void)
|
||||
|
||||
m_pWelsTrace = new welsCodecTrace();
|
||||
if (m_pWelsTrace != NULL) {
|
||||
m_pWelsTrace->SetCodecInstance (this);
|
||||
m_pWelsTrace->SetTraceLevel (WELS_LOG_ERROR);
|
||||
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::CWelsDecoder() entry");
|
||||
@@ -196,7 +198,7 @@ long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
|
||||
}
|
||||
|
||||
// H.264 decoder initialization,including memory allocation,then open it ready to decode
|
||||
iRet = InitDecoder();
|
||||
iRet = InitDecoder (pParam->bParseOnly);
|
||||
if (iRet)
|
||||
return iRet;
|
||||
|
||||
@@ -231,16 +233,18 @@ void CWelsDecoder::UninitDecoder (void) {
|
||||
}
|
||||
|
||||
// the return value of this function is not suitable, it need report failure info to upper layer.
|
||||
int32_t CWelsDecoder::InitDecoder (void) {
|
||||
int32_t CWelsDecoder::InitDecoder (const bool bParseOnly) {
|
||||
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::init_decoder(), openh264 codec version = %s",
|
||||
VERSION_NUMBER);
|
||||
|
||||
if (m_pDecContext) //free
|
||||
UninitDecoder();
|
||||
m_pDecContext = (PWelsDecoderContext)WelsMalloc (sizeof (SWelsDecoderContext), "m_pDecContext");
|
||||
if (NULL == m_pDecContext)
|
||||
return cmMallocMemeError;
|
||||
|
||||
return WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
|
||||
return WelsInitDecoder (m_pDecContext, bParseOnly, &m_pWelsTrace->m_sLogCtx);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -274,7 +278,7 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
|
||||
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);
|
||||
iVal = WELS_CLIP3 (iVal, (int32_t) ERROR_CON_DISABLE, (int32_t) ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
|
||||
m_pDecContext->eErrorConMethod = (ERROR_CON_IDC) iVal;
|
||||
InitErrorCon (m_pDecContext);
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||
@@ -301,8 +305,13 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
|
||||
m_pWelsTrace->SetTraceCallbackContext (ctx);
|
||||
}
|
||||
return cmResultSuccess;
|
||||
} else if (eOptID == DECODER_OPTION_GET_STATISTICS) {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
|
||||
"CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
|
||||
return cmInitParaError;
|
||||
}
|
||||
|
||||
|
||||
return cmInitParaError;
|
||||
}
|
||||
|
||||
@@ -358,6 +367,17 @@ long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
|
||||
iVal = (int) m_pDecContext->eErrorConMethod;
|
||||
* ((int*)pOption) = iVal;
|
||||
return cmResultSuccess;
|
||||
} else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging
|
||||
SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));
|
||||
|
||||
memcpy (pDecoderStatistics, &m_pDecContext->sDecoderStatistics, sizeof (SDecoderStatistics));
|
||||
|
||||
pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
|
||||
(m_pDecContext->sDecoderStatistics.uiDecodedFrameCount);
|
||||
pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
|
||||
(m_pDecContext->sDecoderStatistics.uiDecodedFrameCount + m_pDecContext->sDecoderStatistics.uiFreezingIDRNum +
|
||||
m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum);
|
||||
return cmResultSuccess;
|
||||
}
|
||||
|
||||
return cmInitParaError;
|
||||
@@ -389,11 +409,14 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
m_pDecContext->bInstantDecFlag = true;
|
||||
}
|
||||
|
||||
int64_t iStart, iEnd;
|
||||
iStart = WelsTime();
|
||||
ppDst[0] = ppDst[1] = ppDst[2] = NULL;
|
||||
m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
|
||||
m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
|
||||
unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
|
||||
memset (pDstInfo, 0, sizeof (SBufferInfo));
|
||||
|
||||
pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
|
||||
#ifdef LONG_TERM_REF
|
||||
m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
|
||||
m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
|
||||
@@ -402,9 +425,14 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
#endif
|
||||
|
||||
m_pDecContext->iFeedbackTidInAu = -1; //initialize
|
||||
|
||||
if (pDstInfo) {
|
||||
pDstInfo->uiOutYuvTimeStamp = 0;
|
||||
m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
|
||||
} else {
|
||||
m_pDecContext->uiTimeStamp = 0;
|
||||
}
|
||||
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
|
||||
pDstInfo); //iErrorCode has been modified in this function
|
||||
pDstInfo, NULL); //iErrorCode has been modified in this function
|
||||
m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
|
||||
if (m_pDecContext->iErrorCode) {
|
||||
EWelsNalUnitType eNalType =
|
||||
@@ -412,6 +440,9 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
|
||||
eNalType = m_pDecContext->sCurNalHead.eNalUnitType;
|
||||
|
||||
if (m_pDecContext->iErrorCode & dsOutOfMemory) {
|
||||
ForceResetParaSetStatusAndAUList (m_pDecContext);
|
||||
}
|
||||
//for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
|
||||
if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
|
||||
(VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {
|
||||
@@ -421,7 +452,6 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
#else
|
||||
m_pDecContext->bReferenceLostAtT0Flag = true;
|
||||
#endif
|
||||
ResetParameterSetsState (m_pDecContext); //initial SPS&PPS ready flag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,18 +469,94 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
if ((m_pDecContext->eErrorConMethod != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
|
||||
//TODO after dec status updated
|
||||
m_pDecContext->iErrorCode |= dsDataErrorConcealed;
|
||||
|
||||
//
|
||||
if ((m_pDecContext->sDecoderStatistics.uiWidth != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iWidth)
|
||||
|| (m_pDecContext->sDecoderStatistics.uiHeight != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iHeight)) {
|
||||
m_pDecContext->sDecoderStatistics.uiResolutionChangeTimes++;
|
||||
m_pDecContext->sDecoderStatistics.uiWidth = pDstInfo->UsrData.sSystemBuffer.iWidth;
|
||||
m_pDecContext->sDecoderStatistics.uiHeight = pDstInfo->UsrData.sSystemBuffer.iHeight;
|
||||
|
||||
}
|
||||
m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
|
||||
if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
|
||||
ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
|
||||
m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
|
||||
}
|
||||
int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbNum == 0 ?
|
||||
(m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
|
||||
iMbConcealedNum * 100) / m_pDecContext->iMbNum));
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ?
|
||||
(m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
|
||||
m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));
|
||||
m_pDecContext->sDecoderStatistics.uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
|
||||
m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
|
||||
}
|
||||
iEnd = WelsTime();
|
||||
m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
|
||||
return (DECODING_STATE) m_pDecContext->iErrorCode;
|
||||
}
|
||||
// else Error free, the current codec works well
|
||||
|
||||
if (pDstInfo->iBufferStatus == 1) {
|
||||
|
||||
m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
|
||||
if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
|
||||
ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
|
||||
m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
|
||||
}
|
||||
|
||||
if ((m_pDecContext->sDecoderStatistics.uiWidth != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iWidth)
|
||||
|| (m_pDecContext->sDecoderStatistics.uiHeight != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iHeight)) {
|
||||
m_pDecContext->sDecoderStatistics.uiResolutionChangeTimes++;
|
||||
m_pDecContext->sDecoderStatistics.uiWidth = pDstInfo->UsrData.sSystemBuffer.iWidth;
|
||||
m_pDecContext->sDecoderStatistics.uiHeight = pDstInfo->UsrData.sSystemBuffer.iHeight;
|
||||
}
|
||||
}
|
||||
iEnd = WelsTime();
|
||||
m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
|
||||
return dsErrorFree;
|
||||
}
|
||||
|
||||
DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
|
||||
const int kiSrcLen,
|
||||
SParserBsInfo* pDstInfo) {
|
||||
//TODO, add function here
|
||||
if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
|
||||
return dsOutOfMemory;
|
||||
}
|
||||
if (kiSrcLen > 0 && kpSrc != NULL) {
|
||||
#ifdef OUTPUT_BITSTREAM
|
||||
if (m_pFBS) {
|
||||
WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
|
||||
WelsFflush (m_pFBS);
|
||||
}
|
||||
#endif//OUTPUT_BIT_STREAM
|
||||
m_pDecContext->bEndOfStreamFlag = false;
|
||||
} else {
|
||||
//For application MODE, the error detection should be added for safe.
|
||||
//But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
|
||||
m_pDecContext->bEndOfStreamFlag = true;
|
||||
m_pDecContext->bInstantDecFlag = true;
|
||||
}
|
||||
|
||||
m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
|
||||
m_pDecContext->pParserBsInfo = pDstInfo;
|
||||
pDstInfo->iNalNum = 0;
|
||||
pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
|
||||
if (pDstInfo) {
|
||||
m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
|
||||
pDstInfo->uiOutBsTimeStamp = 0;
|
||||
} else {
|
||||
m_pDecContext->uiTimeStamp = 0;
|
||||
}
|
||||
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
|
||||
|
||||
return (DECODING_STATE) m_pDecContext->iErrorCode;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ DECODER_SRCDIR=codec/decoder
|
||||
DECODER_CPP_SRCS=\
|
||||
$(DECODER_SRCDIR)/core/src/au_parser.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/bit_stream.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/cabac_decoder.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/deblocking.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/decode_mb_aux.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/decode_slice.cpp\
|
||||
@@ -16,6 +17,7 @@ DECODER_CPP_SRCS=\
|
||||
$(DECODER_SRCDIR)/core/src/mem_align.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/memmgr_nal_unit.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/mv_pred.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/parse_mb_syn_cabac.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/parse_mb_syn_cavlc.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/pic_queue.cpp\
|
||||
$(DECODER_SRCDIR)/core/src/rec_mb.cpp\
|
||||
|
||||
@@ -106,7 +106,8 @@ int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaS
|
||||
*/
|
||||
int32_t WelsInitSps (SWelsSPS* pSps, SSpatialLayerConfig* pLayerParam, SSpatialLayerInternal* pLayerParamInternal,
|
||||
const uint32_t kuiIntraPeriod, const int32_t kiNumRefFrame,
|
||||
const uint32_t kiSpsId, const bool kbEnableFrameCropping, bool bEnableRc);
|
||||
const uint32_t kiSpsId, const bool kbEnableFrameCropping, bool bEnableRc,
|
||||
const int32_t kiDlayerCount);
|
||||
|
||||
/*!
|
||||
* \brief initialize subset pSps based on configurable parameters in svc
|
||||
@@ -138,7 +139,9 @@ int32_t WelsInitPps (SWelsPPS* pPps,
|
||||
SSubsetSps* pSubsetSps,
|
||||
const uint32_t kuiPpsId,
|
||||
const bool kbDeblockingFilterPresentFlag,
|
||||
const bool kbUsingSubsetSps);
|
||||
const bool kbUsingSubsetSps,
|
||||
const bool kbEntropyCodingModeFlag);
|
||||
int32_t WelsCheckRefFrameLimitation (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
|
||||
int32_t WelsAdjustLevel( SSpatialLayerConfig* pSpatialLayer);
|
||||
}
|
||||
#endif//WELS_ACCESS_UNIT_PARSER_H__
|
||||
|
||||
@@ -70,7 +70,7 @@ int32_t AllocateBsOutputBuffer (CMemoryAlign* pMa, const int32_t iNeededLen, int
|
||||
* \param pEncCtx sWelsEncCtx*
|
||||
* \return successful - 0; otherwise none 0 for failed
|
||||
*/
|
||||
int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* _param, uint32_t uiCpuFlag);
|
||||
int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* _param, uint32_t uiCpuFlag);
|
||||
|
||||
///*!
|
||||
// * \brief decide frame type (IDR/P frame)
|
||||
|
||||
@@ -169,7 +169,14 @@ typedef struct TagWelsEncCtx {
|
||||
|
||||
// Rate control routine
|
||||
SWelsSvcRc* pWelsSvcRc;
|
||||
bool bCheckWindowStatusRefreshFlag;
|
||||
int64_t iCheckWindowStartTs;
|
||||
int64_t iCheckWindowCurrentTs;
|
||||
int32_t iCheckWindowInterval;
|
||||
int32_t iCheckWindowIntervalShift;
|
||||
bool bCheckWindowShiftResetFlag;
|
||||
int32_t iSkipFrameFlag; //_GOM_RC_
|
||||
int32_t iContinualSkipFrames;
|
||||
int32_t iGlobalQp; // global qp
|
||||
|
||||
// VAA
|
||||
@@ -195,6 +202,7 @@ typedef struct TagWelsEncCtx {
|
||||
SSpatialPicIndex sSpatialIndexMap[MAX_DEPENDENCY_LAYER];
|
||||
|
||||
bool bLongTermRefFlag[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1/*+LONG_TERM_REF_NUM*/];
|
||||
uint16_t uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR
|
||||
|
||||
int16_t iMaxSliceCount;// maximal count number of slices for all layers observation
|
||||
int16_t iActiveThreadsNum; // number of threads active so far
|
||||
@@ -221,11 +229,14 @@ typedef struct TagWelsEncCtx {
|
||||
SEncoderStatistics sEncoderStatistics;
|
||||
int32_t iStatisticsLogInterval;
|
||||
int64_t iLastStatisticsLogTs;
|
||||
int64_t iTotalEncodedBits;
|
||||
int64_t iLastStatisticsBits;
|
||||
int64_t iLastStatisticsFrameCount;
|
||||
|
||||
int32_t iEncoderError;
|
||||
WELS_MUTEX mutexEncoderError;
|
||||
bool bDeliveryFlag;
|
||||
|
||||
SStateCtx sWelsCabacContexts[4][WELS_QP_MAX + 1][WELS_CONTEXT_COUNT];
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
bool bDependencyRecFlag[MAX_DEPENDENCY_LAYER];
|
||||
bool bRecFlag;
|
||||
|
||||
@@ -105,9 +105,11 @@ int32_t ForceCodingIDR (sWelsEncCtx* pCtx);
|
||||
* \brief Wels SVC encoder parameters adjustment
|
||||
* SVC adjustment results in new requirement in memory blocks adjustment
|
||||
*/
|
||||
int32_t WelsBitRateVerification(SLogContext* pLogCtx,SSpatialLayerConfig* pLayerParam,int32_t iLayerId);
|
||||
int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNew);
|
||||
void WelsEncoderApplyFrameRate (SWelsSvcCodingParam* pParam);
|
||||
void WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iLayer);
|
||||
int32_t WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iLayer);
|
||||
int32_t WelsEncoderApplyBitVaryRang(SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iRang);
|
||||
int32_t WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue);
|
||||
int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRecoverRequest);
|
||||
|
||||
|
||||
@@ -111,16 +111,13 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
char* pCurPath; // record current lib path such as:/pData/pData/com.wels.enc/lib/
|
||||
|
||||
bool bDeblockingParallelFlag; // deblocking filter parallelization control flag
|
||||
|
||||
int32_t iBitsVaryPercentage;
|
||||
short
|
||||
iCountThreadsNum; // # derived from disable_multiple_slice_idc (=0 or >1) means;
|
||||
|
||||
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();
|
||||
@@ -139,7 +136,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
|
||||
param.iComplexityMode = MEDIUM_COMPLEXITY;
|
||||
param.iTargetBitrate = 0; // overall target bitrate introduced in RC module
|
||||
param.iMaxBitrate = MAX_BIT_RATE;
|
||||
param.iMaxBitrate = UNSPECIFIED_BIT_RATE;
|
||||
param.iMultipleThreadIdc = 1;
|
||||
|
||||
param.iLTRRefNum = 0;
|
||||
@@ -157,7 +154,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
/* Rate Control */
|
||||
param.iRCMode = RC_QUALITY_MODE;
|
||||
param.iPaddingFlag = 0;
|
||||
|
||||
param.iEntropyCodingModeFlag = 0;
|
||||
param.bEnableDenoise = false; // denoise control
|
||||
param.bEnableSceneChangeDetect = true; // scene change detection control
|
||||
param.bEnableBackgroundDetection = true; // background detection control
|
||||
@@ -173,7 +170,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
param.iMinQp = 0;
|
||||
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||
param.uiMaxNalSize = 0;
|
||||
|
||||
param.bIsLosslessLink = false;
|
||||
for (int32_t iLayer = 0; iLayer < MAX_SPATIAL_LAYER_NUM; iLayer++) {
|
||||
param.sSpatialLayers[iLayer].uiProfileIdc = PRO_BASELINE;
|
||||
param.sSpatialLayers[iLayer].uiLevelIdc = LEVEL_5_0;
|
||||
@@ -182,7 +179,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
|
||||
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
|
||||
|
||||
param.sSpatialLayers[iLayer].iMaxSpatialBitrate = UNSPECIFIED_BIT_RATE;
|
||||
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;
|
||||
@@ -205,22 +202,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
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;
|
||||
|
||||
bIsLosslessLink = false;
|
||||
iBitsVaryPercentage = 0;
|
||||
}
|
||||
|
||||
int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam) {
|
||||
@@ -240,7 +222,8 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
|
||||
int8_t iIdxSpatial = 0;
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
|
||||
if (iEntropyCodingModeFlag)
|
||||
uiProfileIdc = PRO_MAIN;
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
|
||||
while (iIdxSpatial < iSpatialLayerNum) {
|
||||
@@ -298,7 +281,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
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
|
||||
|
||||
iEntropyCodingModeFlag = pCodingParam.iEntropyCodingModeFlag;
|
||||
bEnableFrameCroppingFlag = pCodingParam.bEnableFrameCroppingFlag;
|
||||
|
||||
/* Rate Control */
|
||||
@@ -399,9 +382,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||
#endif//ENABLE_FRAME_DUMP
|
||||
pSpatialLayer->iVideoWidth = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth, MB_WIDTH_LUMA,
|
||||
pSpatialLayer->iVideoWidth = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth, 0,
|
||||
iPicWidth); // frame width
|
||||
pSpatialLayer->iVideoHeight = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight, MB_HEIGHT_LUMA,
|
||||
pSpatialLayer->iVideoHeight = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight, 0,
|
||||
iPicHeight);// frame height
|
||||
|
||||
pSpatialLayer->iSpatialBitrate =
|
||||
@@ -459,7 +442,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
EProfileIdc uiProfileIdc = iEntropyCodingModeFlag ? PRO_MAIN : PRO_BASELINE;
|
||||
int8_t i = 0;
|
||||
|
||||
while (i < iSpatialLayerNum) {
|
||||
@@ -492,7 +475,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
uiProfileIdc = iEntropyCodingModeFlag ? PRO_SCALABLE_HIGH : PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
++ pSpatialLayer;
|
||||
++ i;
|
||||
|
||||
@@ -147,7 +147,7 @@ uint8_t uiChromaQpIndexOffset;
|
||||
// /* potential application for High profile */
|
||||
|
||||
// bool bPicOrderPresentFlag;
|
||||
|
||||
bool bEntropyCodingModeFlag;
|
||||
bool bDeblockingFilterControlPresentFlag;
|
||||
|
||||
// bool bConstainedIntraPredFlag;
|
||||
|
||||
@@ -119,10 +119,23 @@ enum {
|
||||
#define SMOOTH_FACTOR_MIN_VALUE 2 // *INT_MULTIPLY
|
||||
//#define VGOP_BITS_MIN_RATIO 0.8
|
||||
//skip and padding
|
||||
#define TIME_CHECK_WINDOW 5000 // ms
|
||||
#define SKIP_RATIO 50 // *INT_MULTIPLY
|
||||
#define LAST_FRAME_PREDICT_WEIGHT 0.5
|
||||
#define PADDING_BUFFER_RATIO 50 // *INT_MULTIPLY
|
||||
#define PADDING_THRESHOLD 5 //*INT_MULTIPLY
|
||||
|
||||
#define VIRTUAL_BUFFER_LOW_TH 120 //*INT_MULTIPLY
|
||||
#define VIRTUAL_BUFFER_HIGH_TH 180 //*INT_MULTIPLY
|
||||
|
||||
#define _BITS_RANGE 0
|
||||
|
||||
enum {
|
||||
EVEN_TIME_WINDOW =0,
|
||||
ODD_TIME_WINDOW =1,
|
||||
TIME_WINDOW_TOTAL =2
|
||||
};
|
||||
|
||||
typedef struct TagRCSlicing {
|
||||
int32_t iComplexityIndexSlice;
|
||||
int32_t iCalculatedQpSlice;
|
||||
@@ -152,14 +165,15 @@ int32_t iFrameCmplxMean;
|
||||
|
||||
typedef struct TagWelsRc {
|
||||
int32_t iRcVaryPercentage;
|
||||
int32_t iRcVaryRatio;
|
||||
int32_t iRcVaryRatio;
|
||||
|
||||
int32_t iInitialQp; //initial qp
|
||||
int32_t iBitRate;
|
||||
int32_t iPreviousBitrate;
|
||||
int32_t iPreviousGopSize;
|
||||
double fFrameRate;
|
||||
int32_t iBitsPerFrame; // *INT_MULTIPLY
|
||||
int64_t iBitsPerFrame; // *INT_MULTIPLY
|
||||
int64_t iMaxBitsPerFrame; // *INT_MULTIPLY
|
||||
double dPreviousFps;
|
||||
|
||||
// bits allocation and status
|
||||
@@ -185,7 +199,7 @@ int32_t iMinFrameQp;
|
||||
int32_t iMaxFrameQp;
|
||||
int32_t iNumberMbFrame;
|
||||
int32_t iNumberMbGom;
|
||||
int32_t iSliceNum;
|
||||
int32_t iSliceNum;
|
||||
int32_t iGomSize;
|
||||
|
||||
int32_t iSkipFrameNum;
|
||||
@@ -201,15 +215,18 @@ int32_t iMinQp;
|
||||
int32_t iMaxQp;
|
||||
//int32_t delta_adaptive_qp;
|
||||
int32_t iSkipBufferRatio;
|
||||
|
||||
|
||||
int32_t iQStep; // *INT_MULTIPLY
|
||||
int32_t iFrameDeltaQpUpper;
|
||||
int32_t iFrameDeltaQpLower;
|
||||
int32_t iLastCalculatedQScale;
|
||||
|
||||
|
||||
//for skip frame and padding
|
||||
int32_t iBufferSizeSkip;
|
||||
int32_t iBufferFullnessSkip;
|
||||
int32_t iBufferMaxBRFullness[TIME_WINDOW_TOTAL];//0: EVEN_TIME_WINDOW; 1: ODD_TIME_WINDOW
|
||||
int32_t iPredFrameBit;
|
||||
bool bNeedShiftWindowCheck[TIME_WINDOW_TOTAL];
|
||||
int32_t iBufferSizePadding;
|
||||
int32_t iBufferFullnessPadding;
|
||||
int32_t iPaddingSize;
|
||||
@@ -244,6 +261,10 @@ PWelsRCMBInitFunc pfWelsRcMbInit;
|
||||
PWelsRCMBInfoUpdateFunc pfWelsRcMbInfoUpdate;
|
||||
} SWelsRcFunc;
|
||||
|
||||
bool CheckFrameSkipBasedMaxbr (void* pCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
|
||||
const uint32_t uiTimeStamp);
|
||||
void UpdateBufferWhenFrameSkipped(void* pCtx, int32_t iSpatialNum);
|
||||
void UpdateMaxBrCheckWindowStatus(void* pCtx, int32_t iSpatialNum, const long long uiTimeStamp);
|
||||
void RcTraceFrameBits (void* pEncCtx, long long uiTimeStamp);
|
||||
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode);
|
||||
void WelsRcFreeMemory (void* pCtx);
|
||||
|
||||
@@ -72,11 +72,11 @@ void WelsResetRefList (sWelsEncCtx* pCtx);
|
||||
/*
|
||||
* update reference picture list
|
||||
*/
|
||||
bool WelsUpdateRefList (void* pCtx);
|
||||
bool WelsUpdateRefList (sWelsEncCtx* pCtx);
|
||||
/*
|
||||
* build reference picture list
|
||||
*/
|
||||
bool WelsBuildRefList (void* pCtx, const int32_t kiPOC, int32_t iBestLtrRefIdx);
|
||||
bool WelsBuildRefList (sWelsEncCtx* pCtx, const int32_t kiPOC, int32_t iBestLtrRefIdx);
|
||||
|
||||
/*
|
||||
* update syntax for reference base related
|
||||
@@ -91,7 +91,7 @@ bool CheckCurMarkFrameNumUsed (sWelsEncCtx* pCtx);
|
||||
/*
|
||||
* decide whether current frame include long term reference mark and update long term reference mark syntax
|
||||
*/
|
||||
void WelsMarkPic (void* pCtx);
|
||||
void WelsMarkPic (sWelsEncCtx* pCtx);
|
||||
|
||||
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bEnableLongTermReference, const bool bScreenContent);
|
||||
|
||||
|
||||
83
codec/encoder/core/inc/set_mb_syn_cabac.h
Normal file
83
codec/encoder/core/inc/set_mb_syn_cabac.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*!
|
||||
* \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 set_mb_syn_cabac.h
|
||||
*
|
||||
* \brief Seting all syntax elements of mb and encoding residual with cabac
|
||||
*
|
||||
* \date 09/27/2014 Created
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SET_MB_SYN_CABAC_H_
|
||||
#define SET_MB_SYN_CABAC_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "bit_stream.h"
|
||||
#include "wels_common_defs.h"
|
||||
namespace WelsEnc {
|
||||
|
||||
#define WELS_QP_MAX 51
|
||||
|
||||
typedef struct TagStateCtx {
|
||||
uint8_t m_uiState;
|
||||
uint8_t m_uiValMps;
|
||||
} SStateCtx;
|
||||
typedef struct TagCabacCtx {
|
||||
uint32_t m_uiLow;
|
||||
uint32_t m_uiRange;
|
||||
SStateCtx m_sStateCtx[WELS_CONTEXT_COUNT];
|
||||
uint8_t* m_pBufStart;
|
||||
uint8_t* m_pBufEnd;
|
||||
uint8_t* m_pBufCur;
|
||||
uint8_t m_iBitsOutstanding;
|
||||
uint32_t m_uData;
|
||||
uint32_t m_uiBitsUsed;
|
||||
uint32_t m_iFirstFlag;
|
||||
uint32_t m_uiBinCountsInNalUnits;
|
||||
} SCabacCtx;
|
||||
|
||||
|
||||
void WelsCabacContextInit (void* pCtx, SCabacCtx* pCbCtx, int32_t iModel);
|
||||
void WelsCabacEncodeInit (SCabacCtx* pCbCtx, uint8_t* pBuf, uint8_t* pEnd);
|
||||
void WelsCabacEncodeDecision (SCabacCtx* pCbCtx, int32_t iCtx, uint32_t uiBin);
|
||||
void WelsCabacEncodeBypassOne (SCabacCtx* pCbCtx, uint32_t uiBin);
|
||||
void WelsCabacEncodeTerminate (SCabacCtx* pCbCtx, uint32_t uiBin);
|
||||
void WelsCabacEncodeUeBypass (SCabacCtx* pCbCtx, int32_t iExpBits, uint32_t uiVal);
|
||||
void WelsCabacEncodeFlush (SCabacCtx* pCbCtx);
|
||||
uint8_t* WelsCabacEncodeGetPtr (SCabacCtx* pCbCtx);
|
||||
int32_t WriteBlockResidualCabac (void* pEncCtx, int16_t* pCoffLevel, int32_t iEndIdx,
|
||||
int32_t iCalRunLevelFlag,
|
||||
int32_t iResidualProperty, int8_t iNC, SBitStringAux* pBs);
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -48,30 +48,30 @@
|
||||
namespace WelsEnc {
|
||||
|
||||
|
||||
|
||||
enum EResidualProperty {
|
||||
LUMA_DC = 0,
|
||||
LUMA_AC = 1,
|
||||
LUMA_4x4 = 2,
|
||||
CHROMA_DC = 3,
|
||||
CHROMA_AC = 4
|
||||
enum ECtxBlockCat {
|
||||
LUMA_DC = 0,
|
||||
LUMA_AC = 1,
|
||||
LUMA_4x4 = 2,
|
||||
CHROMA_DC = 3,
|
||||
CHROMA_AC = 4
|
||||
};
|
||||
|
||||
|
||||
#define LUMA_DC_AC 0x04
|
||||
|
||||
typedef struct TagCavlcTableItem {
|
||||
uint16_t uiBits;
|
||||
uint8_t uiLen;
|
||||
uint8_t uiSuffixLength;
|
||||
uint16_t uiBits;
|
||||
uint8_t uiLen;
|
||||
uint8_t uiSuffixLength;
|
||||
} SCavlcTableItem;
|
||||
|
||||
void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag);
|
||||
void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag,int32_t iEntropyCodingModeFlag);
|
||||
|
||||
int32_t WriteBlockResidualCavlc (SWelsFuncPtrList* pFuncList, int16_t* pCoffLevel, int32_t iEndIdx,
|
||||
int32_t iCalRunLevelFlag,
|
||||
int32_t iResidualProperty, int8_t iNC, SBitStringAux* pBs);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif//__cplusplus
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "parameter_sets.h"
|
||||
#include "svc_enc_slice_segment.h"
|
||||
#include "bit_stream.h"
|
||||
|
||||
#include "set_mb_syn_cabac.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
@@ -178,6 +178,10 @@ uint8_t uiAssumeLog2BytePerMb;
|
||||
uint32_t uiSliceFMECostDown;//TODO: for FME switch under MT, to opt after ME final?
|
||||
|
||||
uint8_t uiReservedFillByte; // reserved to meet 4 bytes alignment
|
||||
|
||||
SCabacCtx sCabacCtx;
|
||||
int32_t iCabacInitIdc;
|
||||
int32_t iMbSkipRun;
|
||||
} SSlice, *PSlice;
|
||||
|
||||
}
|
||||
|
||||
@@ -48,30 +48,30 @@ void WelsMdIntraInit (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbCache, con
|
||||
int32_t WelsMdI16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SMbCache* pMbCache, int32_t iLambda);
|
||||
int32_t WelsMdIntraChroma (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SMbCache* pMbCache, int32_t iLambda);
|
||||
|
||||
int32_t WelsMdI4x4 (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
int32_t WelsMdI4x4Fast (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
int32_t WelsMdI4x4 (sWelsEncCtx* pEnc, SWelsMD* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
int32_t WelsMdI4x4Fast (sWelsEncCtx* pEnc, SWelsMD* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
|
||||
int32_t WelsMdIntraFinePartition (void* pEncCtx, void* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
int32_t WelsMdIntraFinePartitionVaa (void* pEncCtx, void* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
int32_t WelsMdIntraFinePartition (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
int32_t WelsMdIntraFinePartitionVaa (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
|
||||
void WelsMdIntraMb (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
|
||||
void WelsMdBackgroundMbEnc (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCache, SSlice* pSlice, bool bSkipMbFlag);
|
||||
bool WelsMdPSkipEnc (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
void WelsMdBackgroundMbEnc (sWelsEncCtx* pEnc, SWelsMD* pMd, SMB* pCurMb, SMbCache* pMbCache, SSlice* pSlice, bool bSkipMbFlag);
|
||||
bool WelsMdPSkipEnc (sWelsEncCtx* pEnc, SWelsMD* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb);
|
||||
|
||||
int32_t WelsMdP16x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWelsMd, SSlice* pSlice);
|
||||
int32_t WelsMdP8x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWelsMd, SSlice* pSlice);
|
||||
int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWelsMd, SSlice* pSlice);
|
||||
/*static*/ void WelsMdInterInit (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, const int32_t kiSliceFirstMbXY);
|
||||
/*static*/ void WelsMdInterFinePartition (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
||||
/*static*/ void WelsMdInterFinePartitionVaa (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
||||
/*static*/ void WelsMdInterFinePartitionVaaOnScreen (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb,
|
||||
/*static*/ void WelsMdInterFinePartition (sWelsEncCtx* pEnc, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
||||
/*static*/ void WelsMdInterFinePartitionVaa (sWelsEncCtx* pEnc, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb, int32_t bestCost);
|
||||
/*static*/ void WelsMdInterFinePartitionVaaOnScreen (sWelsEncCtx* pEnc, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb,
|
||||
int32_t bestCost);
|
||||
void WelsMdInterMbRefinement (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
bool WelsMdFirstIntraMode (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
//bool svc_md_first_intra_mode_constrained(void* pEnc, void* pMd, SMB* pCurMb, SMbCache *pMbCache);
|
||||
void WelsMdInterMb (void* pEncCtx, void* pWelsMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pUnused);
|
||||
bool WelsMdFirstIntraMode (sWelsEncCtx* pEnc, SWelsMD* pMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
//bool svc_md_first_intra_mode_constrained(sWelsEncCtx* pEnc, SWelsMD* pMd, SMB* pCurMb, SMbCache *pMbCache);
|
||||
void WelsMdInterMb (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pUnused);
|
||||
|
||||
//both used in BL and EL
|
||||
//void wels_md_inter_init ( SWelsMD* pMd, const uint8_t ref_idx, const bool is_highest_dlayer_flag );
|
||||
|
||||
@@ -171,7 +171,6 @@ pBs->pBufPtr += 4 - pBs->iLeftBits / 8;
|
||||
pBs->iLeftBits = 32;
|
||||
pBs->uiCurBits = 0; // for future writing safe, 5/19/2010
|
||||
}
|
||||
|
||||
/*
|
||||
* Write unsigned exp golomb codes
|
||||
*/
|
||||
@@ -246,5 +245,15 @@ static inline int32_t BsGetBitsPos (SBitStringAux* pBs) {
|
||||
return (int32_t) (((pBs->pBufPtr - pBs->pBuf) << 3) + 32 - pBs->iLeftBits);
|
||||
}
|
||||
|
||||
static inline void BsAlign( SBitStringAux* pBs )
|
||||
{
|
||||
if( pBs->iLeftBits&7 )
|
||||
{
|
||||
pBs->uiCurBits <<= pBs->iLeftBits&7;
|
||||
pBs->uiCurBits |= (1 << (pBs->iLeftBits&7)) - 1;
|
||||
pBs->iLeftBits &= ~7;
|
||||
}
|
||||
BsFlush(pBs );
|
||||
}
|
||||
}
|
||||
#endif//WELS_EXPONENTIAL_GOLOMB_ENTROPY_CODING_H__
|
||||
|
||||
@@ -68,8 +68,12 @@ SMVUnitXY sP16x16Mv;
|
||||
|
||||
uint8_t uiLumaQp; // uiLumaQp: pPps->iInitialQp + sSliceHeader->delta_qp + mb->dquant.
|
||||
uint8_t uiChromaQp;
|
||||
uint8_t uiSliceIdc; // AVC: pFirstMbInSlice?; SVC: (pFirstMbInSlice << 7) | ((uiDependencyId << 4) | uiQualityId);
|
||||
uint8_t reserved_filling_bytes[1]; // filling bytes reserved to make structure aligned with 4 bytes, higher cache hit on less structure size by 2 cache lines( 2 * 64 bytes) once hit
|
||||
uint16_t uiSliceIdc; // 2^16=65536 > MaxFS(36864) of level 5.1; AVC: pFirstMbInSlice?; SVC: (pFirstMbInSlice << 7) | ((uiDependencyId << 4) | uiQualityId);
|
||||
uint32_t uiChromPredMode;
|
||||
int32_t iLumaDQp;
|
||||
SMVUnitXY sMvd[4];
|
||||
int32_t iCbpDc;
|
||||
//uint8_t reserved_filling_bytes[1]; // not deleting this line for further changes of this structure. filling bytes reserved to make structure aligned with 4 bytes, higher cache hit on less structure size by 2 cache lines( 2 * 64 bytes) once hit
|
||||
} SMB, *PMb;
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#include "memory_align.h"
|
||||
|
||||
#include "codec_app_def.h"
|
||||
#include "set_mb_syn_cabac.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
|
||||
@@ -78,7 +80,7 @@ int16_t iMbWidth; /* width of picture size in mb */
|
||||
int16_t iMbHeight; /* height of picture size in mb */
|
||||
int16_t iSliceNumInFrame; /* count number of slices in frame; */
|
||||
int32_t iMbNumInFrame; /* count number of MBs in frame */
|
||||
uint8_t* pOverallMbMap; /* overall MB map in frame, store virtual slice idc; */
|
||||
uint16_t* pOverallMbMap; /* overall MB map in frame, store virtual slice idc; */
|
||||
int16_t* pFirstMbInSlice; /* first MB address top-left based in every slice respectively; */
|
||||
int32_t* pCountMbNumInSlice; /* count number of MBs in every slice respectively; */
|
||||
uint32_t uiSliceSizeConstraint;/*in byte*/
|
||||
@@ -90,10 +92,11 @@ typedef struct TagDynamicSlicingStack {
|
||||
int32_t iStartPos;
|
||||
int32_t iCurrentPos;
|
||||
|
||||
uint8_t* pBsStackBufPtr; // current writing position
|
||||
uint8_t* pBsStackBufPtr; // current writing position
|
||||
uint32_t uiBsStackCurBits;
|
||||
int32_t iBsStackLeftBits;
|
||||
|
||||
SCabacCtx sStoredCabac;
|
||||
int32_t iMbSkipRunStack;
|
||||
uint8_t uiLastMbQp;
|
||||
} SDynamicSlicingStack;
|
||||
@@ -137,7 +140,7 @@ void UninitSlicePEncCtx (SSliceCtx* pSliceCtx, CMemoryAlign* pMa);
|
||||
*
|
||||
* \return uiSliceIdc - successful; (uint8_t)(-1) - failed;
|
||||
*/
|
||||
uint8_t WelsMbToSliceIdc (SSliceCtx* pSliceCtx, const int16_t kiMbXY);
|
||||
uint16_t WelsMbToSliceIdc (SSliceCtx* pSliceCtx, const int16_t kiMbXY);
|
||||
|
||||
/*!
|
||||
* \brief Get first mb in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO)
|
||||
@@ -193,8 +196,8 @@ bool CheckFixedSliceNumMultiSliceSetting (const int32_t kiMbNumInFrame, SSliceA
|
||||
bool CheckRasterMultiSliceSetting (const int32_t kiMbNumInFrame, SSliceArgument* pSliceArg);
|
||||
bool CheckRowMbMultiSliceSetting (const int32_t kiMbWidth, SSliceArgument* pSliceArg);
|
||||
|
||||
void GomValidCheckSliceNum (const int32_t kiMbWidth, const int32_t kiMbHeight, uint32_t* pSliceNum);
|
||||
void GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight, SSliceArgument* pSliceArg);
|
||||
bool GomValidCheckSliceNum (const int32_t kiMbWidth, const int32_t kiMbHeight, uint32_t* pSliceNum);
|
||||
bool GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight, SSliceArgument* pSliceArg);
|
||||
//end of checking valid para
|
||||
|
||||
int32_t DynamicAdjustSlicePEncCtxAll (SSliceCtx* pSliceCtx,
|
||||
|
||||
@@ -61,16 +61,16 @@ SCROLLED
|
||||
// NOILP ILFMD ENTRANCE
|
||||
void WelsMdSpatialelInterMbIlfmdNoilp (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb,
|
||||
const Mb_Type kuiRefMbType);
|
||||
void WelsMdInterMbEnhancelayer (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache);
|
||||
void WelsMdInterMbEnhancelayer (sWelsEncCtx* pEnc, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache);
|
||||
SMB* GetRefMb (SDqLayer* pCurLayer, SMB* pCurMb);
|
||||
void SetMvBaseEnhancelayer (SWelsMD* pMd, SMB* pCurMb, const SMB* kpRefMb);
|
||||
|
||||
//////////////
|
||||
// MD from background detection
|
||||
//////////////
|
||||
bool WelsMdInterJudgeBGDPskip (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||
bool WelsMdInterJudgeBGDPskip (sWelsEncCtx* pEnc, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||
bool* bKeepSkip);
|
||||
bool WelsMdInterJudgeBGDPskipFalse (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||
bool WelsMdInterJudgeBGDPskipFalse (sWelsEncCtx* pEnc, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||
bool* bKeepSkip);
|
||||
|
||||
void WelsMdInterUpdateBGDInfo (SDqLayer* pCurLayer, SMB* pCurMb, const bool kbCollocatedPredFlag,
|
||||
@@ -87,8 +87,8 @@ typedef bool (*pJudgeSkipFun) (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbC
|
||||
void SetBlockStaticIdcToMd (void* pVaa, void* pMd, SMB* pCurMb, void* pDqLay);
|
||||
void WelsInitSCDPskipFunc (SWelsFuncPtrList* pFuncList, const bool bScrollingDetection);
|
||||
|
||||
void SetScrollingMvToMd (void* pVaa, void* pWelsMd);
|
||||
void SetScrollingMvToMdNull (void* pVaa, void* pWelsMd);
|
||||
void SetScrollingMvToMd (SVAAFrameInfo* pVaa, SWelsMD* pWelsMd);
|
||||
void SetScrollingMvToMdNull (SVAAFrameInfo* pVaa, SWelsMD* pWelsMd);
|
||||
}
|
||||
#endif //SVC_MODE_DECISION_H
|
||||
|
||||
|
||||
@@ -144,9 +144,9 @@ void WelsInitMeFunc (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScre
|
||||
*
|
||||
* \return NONE
|
||||
*/
|
||||
void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
|
||||
void WelsMotionEstimateSearchStatic (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
|
||||
void WelsMotionEstimateSearchScrolled (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
|
||||
void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, SDqLayer* pLplayer, SWelsME* pLpme, SSlice* pLpslice);
|
||||
void WelsMotionEstimateSearchStatic (SWelsFuncPtrList* pFuncList, SDqLayer* pLplayer, SWelsME* pLpme, SSlice* pLpslice);
|
||||
void WelsMotionEstimateSearchScrolled (SWelsFuncPtrList* pFuncList, SDqLayer* pLplayer, SWelsME* pLpme, SSlice* pLpslice);
|
||||
/*!
|
||||
* \brief BL mb motion estimate initial point testing
|
||||
*
|
||||
@@ -188,13 +188,13 @@ void WelsDiamondSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlic
|
||||
bool WelsMeSadCostSelect (int32_t* pSadCost, const uint16_t* kpMvdCost, int32_t* pBestCost, const int32_t kiDx,
|
||||
const int32_t kiDy, int32_t* pIx, int32_t* pIy);
|
||||
|
||||
void CalculateSatdCost (PSampleSadSatdCostFunc pSatd, void* vpMe, const int32_t kiEncStride, const int32_t kiRefStride);
|
||||
void NotCalculateSatdCost (PSampleSadSatdCostFunc pSatd, void* vpMe, const int32_t kiEncStride,
|
||||
void CalculateSatdCost (PSampleSadSatdCostFunc pSatd, SWelsME* pMe, const int32_t kiEncStride, const int32_t kiRefStride);
|
||||
void NotCalculateSatdCost (PSampleSadSatdCostFunc pSatd, SWelsME* pMe, const int32_t kiEncStride,
|
||||
const int32_t kiRefStride);
|
||||
bool CheckDirectionalMv (PSampleSadSatdCostFunc pSad, void* vpMe,
|
||||
bool CheckDirectionalMv (PSampleSadSatdCostFunc pSad, SWelsME* pMe,
|
||||
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
|
||||
int32_t& iBestSadCost);
|
||||
bool CheckDirectionalMvFalse (PSampleSadSatdCostFunc pSad, void* vpMe,
|
||||
bool CheckDirectionalMvFalse (PSampleSadSatdCostFunc pSad, SWelsME* pMe,
|
||||
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
|
||||
int32_t& iBestSadCost);
|
||||
|
||||
@@ -342,12 +342,9 @@ pMvMax->iMvX = WELS_MIN (((kiMbWidth - kiMbX) << 4) - INTPEL_NEEDED_MARGIN, kiMa
|
||||
pMvMax->iMvY = WELS_MIN (((kiMbHeight - kiMbY) << 4) - INTPEL_NEEDED_MARGIN, kiMaxMvRange);
|
||||
}
|
||||
|
||||
inline bool CheckMvInRange (const int16_t kiCurrentMv, const int16_t kiMinMv, const int16_t kiMaxMv) {
|
||||
return ((kiCurrentMv >= kiMinMv) && (kiCurrentMv < kiMaxMv));
|
||||
}
|
||||
inline bool CheckMvInRange (const SMVUnitXY ksCurrentMv, const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv) {
|
||||
return (CheckMvInRange (ksCurrentMv.iMvX, ksMinMv.iMvX, ksMaxMv.iMvX)
|
||||
&& CheckMvInRange (ksCurrentMv.iMvY, ksMinMv.iMvY, ksMaxMv.iMvY));
|
||||
return (CheckInRangeCloseOpen (ksCurrentMv.iMvX, ksMinMv.iMvX, ksMaxMv.iMvX)
|
||||
&& CheckInRangeCloseOpen (ksCurrentMv.iMvY, ksMinMv.iMvY, ksMaxMv.iMvY));
|
||||
}
|
||||
//FME switch related
|
||||
inline bool CalcFMESwitchFlag (const uint8_t uiFMEGoodFrameCount, const int32_t iHighFreMbPrecentage,
|
||||
|
||||
68
codec/encoder/core/inc/svc_set_mb_syn.h
Normal file
68
codec/encoder/core/inc/svc_set_mb_syn.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*!
|
||||
* \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 svc_set_mb_syn.h
|
||||
*
|
||||
* \brief Seting all syntax elements of mb and encoding residual with cavlc and cabac
|
||||
*
|
||||
* \date 2009.8.12 Created
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SVC_SET_MB_SYN_H_
|
||||
#define SVC_SET_MB_SYN_H_
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "wels_common_basis.h"
|
||||
#include "encoder_context.h"
|
||||
#include "md.h"
|
||||
#include "slice.h"
|
||||
#include "set_mb_syn_cavlc.h"
|
||||
#include "set_mb_syn_cabac.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
|
||||
|
||||
int32_t WelsWriteMbResidual (SWelsFuncPtrList* pFuncList, SMbCache* sMbCacheInfo, SMB* pCurMb, SBitStringAux* pBs);
|
||||
|
||||
void WelsSpatialWriteSubMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
|
||||
void WelsSpatialWriteMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
void WelsInitSliceCabac(sWelsEncCtx* pEncCtx,SSlice* pSlice);
|
||||
void WelsCabacInit(void *pCtx);
|
||||
void WelsWriteSliceEndSyn(SSlice *pSlice,bool bEntropyCodingModeFlag);
|
||||
//for Base Layer CAVLC writing
|
||||
int32_t WelsSpatialWriteMbSyn (sWelsEncCtx* Ctx, SSlice* pSlice, SMB* pCurMb);
|
||||
int32_t WelsSpatialWriteMbSynCabac (sWelsEncCtx* pCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
}
|
||||
#endif
|
||||
@@ -37,7 +37,6 @@
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SVC_SET_MB_SYN_CAVLC_H_
|
||||
#define SVC_SET_MB_SYN_CAVLC_H_
|
||||
|
||||
@@ -45,19 +44,24 @@
|
||||
#include "wels_common_basis.h"
|
||||
#include "encoder_context.h"
|
||||
#include "md.h"
|
||||
|
||||
#include "slice.h"
|
||||
#include "set_mb_syn_cavlc.h"
|
||||
#include "set_mb_syn_cabac.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
|
||||
|
||||
int32_t WelsWriteMbResidual (SWelsFuncPtrList* pFuncList, SMbCache* sMbCacheInfo, SMB* pCurMb, SBitStringAux* pBs);
|
||||
|
||||
void WelsSpatialWriteSubMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
|
||||
void WelsSpatialWriteMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
|
||||
void WelsInitSliceCabac(sWelsEncCtx* pEncCtx,SSlice* pSlice);
|
||||
void WelsWriteSliceEndSyn(SSlice *pSlice,bool bEntropyCodingModeFlag);
|
||||
//for Base Layer CAVLC writing
|
||||
int32_t WelsSpatialWriteMbSyn (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
int32_t WelsSpatialWriteMbSyn (void* Ctx, SSlice* pSlice, SMB* pCurMb);
|
||||
int32_t WelsSpatialWriteMbSynCabac (void* pCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,40 +47,44 @@ namespace WelsEnc {
|
||||
|
||||
|
||||
struct SMVUnitXY { // each 4 Bytes
|
||||
int16_t iMvX;
|
||||
int16_t iMvY;
|
||||
int16_t iMvX;
|
||||
int16_t iMvY;
|
||||
public:
|
||||
SMVUnitXY& sDeltaMv (const SMVUnitXY& _v0, const SMVUnitXY& _v1) {
|
||||
iMvX = _v0.iMvX - _v1.iMvX;
|
||||
iMvY = _v0.iMvY - _v1.iMvY;
|
||||
return (*this);
|
||||
}
|
||||
SMVUnitXY& sDeltaMv (const SMVUnitXY& _v0, const SMVUnitXY& _v1) {
|
||||
iMvX = _v0.iMvX - _v1.iMvX;
|
||||
iMvY = _v0.iMvY - _v1.iMvY;
|
||||
return (*this);
|
||||
};
|
||||
SMVUnitXY& sAssginMv (const SMVUnitXY& _v0) {
|
||||
iMvX = _v0.iMvX;
|
||||
iMvY = _v0.iMvY;
|
||||
return (*this);
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct TagMVComponentUnit { // each LIST_0/LIST_1
|
||||
SMVUnitXY sMotionVectorCache[5 * 6 - 1]; // Luma only: 5 x 6 - 1 = 29 D-Words
|
||||
int8_t iRefIndexCache[5 * 6]; // Luma only: 5 x 6 = 30 bytes
|
||||
SMVUnitXY sMotionVectorCache[5 * 6 - 1]; // Luma only: 5 x 6 - 1 = 29 D-Words
|
||||
int8_t iRefIndexCache[5 * 6]; // Luma only: 5 x 6 = 30 bytes
|
||||
} SMVComponentUnit, *PMVComponentUnit;
|
||||
|
||||
|
||||
typedef struct TagParaSetOffsetVariable {
|
||||
int32_t iParaSetIdDelta[MAX_DQ_LAYER_NUM/*+1*/]; //mark delta between SPS_ID_in_bs and sps_id_in_encoder, can be minus, for each dq-layer
|
||||
int32_t iParaSetIdDelta[MAX_DQ_LAYER_NUM/*+1*/]; //mark delta between SPS_ID_in_bs and sps_id_in_encoder, can be minus, for each dq-layer
|
||||
//need not extra +1 due no MGS and FMO case so far
|
||||
bool bUsedParaSetIdInBs[MAX_PPS_COUNT]; //mark the used SPS_ID with 1
|
||||
uint32_t uiNextParaSetIdToUseInBs; //mark the next SPS_ID_in_bs, for all layers
|
||||
bool bUsedParaSetIdInBs[MAX_PPS_COUNT]; //mark the used SPS_ID with 1
|
||||
uint32_t uiNextParaSetIdToUseInBs; //mark the next SPS_ID_in_bs, for all layers
|
||||
} SParaSetOffsetVariable;
|
||||
|
||||
typedef struct TagParaSetOffset {
|
||||
//in PS0 design, "sParaSetOffsetVariable" record the previous paras before current IDR, AND NEED to be stacked and recover across IDR
|
||||
SParaSetOffsetVariable
|
||||
sParaSetOffsetVariable[PARA_SET_TYPE]; //PARA_SET_TYPE=3; paraset_type = 0: AVC_SPS; =1: Subset_SPS; =2: PPS
|
||||
SParaSetOffsetVariable
|
||||
sParaSetOffsetVariable[PARA_SET_TYPE]; //PARA_SET_TYPE=3; paraset_type = 0: AVC_SPS; =1: Subset_SPS; =2: PPS
|
||||
//in PSO design, "bPpsIdMappingIntoSubsetsps" uses the current para of current IDR period
|
||||
bool
|
||||
bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far
|
||||
uint16_t
|
||||
uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR!! Can we just NOT put this into the SParaSetOffset structure?!!
|
||||
bool
|
||||
bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far
|
||||
|
||||
#if _DEBUG
|
||||
bool bEnableSpsPpsIdAddition;
|
||||
bool bEnableSpsPpsIdAddition;
|
||||
#endif
|
||||
} SParaSetOffset;
|
||||
|
||||
@@ -88,32 +92,32 @@ bool bEnableSpsPpsIdAddition;
|
||||
|
||||
/* Position Offset structure */
|
||||
typedef struct TagCropOffset {
|
||||
int16_t iCropLeft;
|
||||
int16_t iCropRight;
|
||||
int16_t iCropTop;
|
||||
int16_t iCropBottom;
|
||||
int16_t iCropLeft;
|
||||
int16_t iCropRight;
|
||||
int16_t iCropTop;
|
||||
int16_t iCropBottom;
|
||||
} SCropOffset;
|
||||
|
||||
|
||||
/* Transform Type */
|
||||
|
||||
enum ETransType {
|
||||
T_4x4 = 0,
|
||||
T_8x8 = 1,
|
||||
T_16x16 = 2,
|
||||
T_PCM = 3
|
||||
T_4x4 = 0,
|
||||
T_8x8 = 1,
|
||||
T_16x16 = 2,
|
||||
T_PCM = 3
|
||||
};
|
||||
|
||||
enum EMbPosition {
|
||||
LEFT_MB_POS = 0x01, // A
|
||||
TOP_MB_POS = 0x02, // B
|
||||
TOPRIGHT_MB_POS = 0x04, // C
|
||||
TOPLEFT_MB_POS = 0x08, // D,
|
||||
RIGHT_MB_POS = 0x10, // add followed four case to reuse when intra up-sample
|
||||
BOTTOM_MB_POS = 0x20, //
|
||||
BOTTOMRIGHT_MB_POS = 0x40, //
|
||||
BOTTOMLEFT_MB_POS = 0x80, //
|
||||
MB_POS_A = 0x100
|
||||
LEFT_MB_POS = 0x01, // A
|
||||
TOP_MB_POS = 0x02, // B
|
||||
TOPRIGHT_MB_POS = 0x04, // C
|
||||
TOPLEFT_MB_POS = 0x08, // D,
|
||||
RIGHT_MB_POS = 0x10, // add followed four case to reuse when intra up-sample
|
||||
BOTTOM_MB_POS = 0x20, //
|
||||
BOTTOMRIGHT_MB_POS = 0x40, //
|
||||
BOTTOMLEFT_MB_POS = 0x80, //
|
||||
MB_POS_A = 0x100
|
||||
};
|
||||
#define MB_ON_PIC_BOUNDRY (RIGHT_MB_POS|BOTTOM_MB_POS|LEFT_MB_POS|TOP_MB_POS)
|
||||
|
||||
@@ -180,13 +184,13 @@ typedef uint32_t Mb_Type;
|
||||
|
||||
|
||||
enum {
|
||||
Intra4x4 = 0,
|
||||
Intra16x16 = 1,
|
||||
Inter16x16 = 2,
|
||||
Inter16x8 = 3,
|
||||
Inter8x16 = 4,
|
||||
Inter8x8 = 5,
|
||||
PSkip = 6
|
||||
Intra4x4 = 0,
|
||||
Intra16x16 = 1,
|
||||
Inter16x16 = 2,
|
||||
Inter16x8 = 3,
|
||||
Inter8x16 = 4,
|
||||
Inter8x8 = 5,
|
||||
PSkip = 6
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -47,9 +47,12 @@
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
typedef struct TagWelsEncCtx sWelsEncCtx;
|
||||
typedef struct TagWelsFuncPointerList SWelsFuncPtrList;
|
||||
typedef struct TagVAAFrameInfo SVAAFrameInfo;
|
||||
|
||||
typedef struct TagWelsME SWelsME;
|
||||
typedef struct TagWelsMD SWelsMD;
|
||||
|
||||
typedef void (*PSetMemoryZero) (void* pDst, int32_t iSize);
|
||||
typedef void (*PDctFunc) (int16_t* pDct, uint8_t* pSample1, int32_t iStride1, uint8_t* pSample2, int32_t iStride2);
|
||||
@@ -115,26 +118,26 @@ typedef struct tagDeblockingFunc {
|
||||
|
||||
typedef void (*PSetNoneZeroCountZeroFunc) (int8_t* pNonZeroCount);
|
||||
|
||||
typedef int32_t (*PIntraFineMdFunc) (void* pEncCtx, void* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
typedef void (*PInterFineMdFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb, int32_t bestCost);
|
||||
typedef bool (*PInterMdFirstIntraModeFunc) (void* pEncCtx, void* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
typedef int32_t (*PIntraFineMdFunc) (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
typedef void (*PInterFineMdFunc) (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* slice, SMB* pCurMb, int32_t bestCost);
|
||||
typedef bool (*PInterMdFirstIntraModeFunc) (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||
|
||||
typedef void (*PFillInterNeighborCacheFunc) (SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth, int8_t* pVaaBgMbFlag);
|
||||
typedef void (*PAccumulateSadFunc) (uint32_t* pSumDiff, int32_t* pGomForegroundBlockNum, int32_t* iSad8x8,
|
||||
int8_t* pVaaBgMbFlag);//for RC
|
||||
typedef bool (*PDynamicSlicingStepBackFunc) (void* pEncCtx, void* pSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
|
||||
typedef bool (*PDynamicSlicingStepBackFunc) (sWelsEncCtx* pEncCtx, SSlice* pSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
|
||||
SDynamicSlicingStack* pDynamicSlicingStack); // 2010.8.17
|
||||
|
||||
typedef bool (*PInterMdBackgroundDecisionFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb,
|
||||
typedef bool (*PInterMdBackgroundDecisionFunc) (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* slice, SMB* pCurMb,
|
||||
SMbCache* pMbCache, bool* pKeepPskip);
|
||||
typedef void (*PInterMdBackgroundInfoUpdateFunc) (SDqLayer* pCurLayer, SMB* pCurMb, const bool bFlag,
|
||||
const int32_t kiRefPictureType);
|
||||
|
||||
typedef bool (*PInterMdScrollingPSkipDecisionFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb,
|
||||
typedef bool (*PInterMdScrollingPSkipDecisionFunc) (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* slice, SMB* pCurMb,
|
||||
SMbCache* pMbCache);
|
||||
typedef void (*PSetScrollingMv) (void* pVaa, void* pMd);
|
||||
typedef void (*PSetScrollingMv) (SVAAFrameInfo* pVaa, SWelsMD* pMd);
|
||||
|
||||
typedef void (*PInterMdFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb, SMbCache* pMbCache);
|
||||
typedef void (*PInterMdFunc) (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* slice, SMB* pCurMb, SMbCache* pMbCache);
|
||||
|
||||
typedef int32_t (*PSampleSadSatdCostFunc) (uint8_t*, int32_t, uint8_t*, int32_t);
|
||||
typedef void (*PSample4SadCostFunc) (uint8_t*, int32_t, uint8_t*, int32_t, int32_t*);
|
||||
@@ -145,13 +148,13 @@ typedef int32_t (*PIntraPred8x8Combined3Func) (uint8_t*, int32_t, uint8_t*, int3
|
||||
uint8_t*, uint8_t*);
|
||||
|
||||
typedef uint32_t (*PSampleSadHor8Func) (uint8_t*, int32_t, uint8_t*, int32_t, uint16_t*, int32_t*);
|
||||
typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, void* pCurDqLayer, void* pMe,
|
||||
void* pSlice);
|
||||
typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, SDqLayer* pCurDqLayer, SWelsME* pMe,
|
||||
SSlice* pSlice);
|
||||
typedef void (*PSearchMethodFunc) (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice, const int32_t kiEncStride,
|
||||
const int32_t kiRefStride);
|
||||
typedef void (*PCalculateSatdFunc) (PSampleSadSatdCostFunc pSatd, void* vpMe, const int32_t kiEncStride,
|
||||
typedef void (*PCalculateSatdFunc) (PSampleSadSatdCostFunc pSatd, SWelsME* pMe, const int32_t kiEncStride,
|
||||
const int32_t kiRefStride);
|
||||
typedef bool (*PCheckDirectionalMv) (PSampleSadSatdCostFunc pSad, void* vpMe,
|
||||
typedef bool (*PCheckDirectionalMv) (PSampleSadSatdCostFunc pSad, SWelsME* pMe,
|
||||
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
|
||||
int32_t& iBestSadCost);
|
||||
typedef void (*PLineFullSearchFunc) (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
|
||||
@@ -160,9 +163,10 @@ typedef void (*PLineFullSearchFunc) (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
|
||||
const int16_t kiMinMv, const int16_t kiMaxMv,
|
||||
const bool bVerticalSearch);
|
||||
typedef void (*PInitializeHashforFeatureFunc) (uint32_t* pTimesOfFeatureValue, uint16_t* pBuf, const int32_t kiListSize,
|
||||
uint16_t** pLocationOfFeature, uint16_t** pFeatureValuePointerList);
|
||||
typedef void (*PFillQpelLocationByFeatureValueFunc) (uint16_t* pFeatureOfBlock, const int32_t kiWidth, const int32_t kiHeight,
|
||||
uint16_t** pFeatureValuePointerList);
|
||||
uint16_t** pLocationOfFeature, uint16_t** pFeatureValuePointerList);
|
||||
typedef void (*PFillQpelLocationByFeatureValueFunc) (uint16_t* pFeatureOfBlock, const int32_t kiWidth,
|
||||
const int32_t kiHeight,
|
||||
uint16_t** pFeatureValuePointerList);
|
||||
typedef void (*PCalculateBlockFeatureOfFrame) (uint8_t* pRef, const int32_t kiWidth, const int32_t kiHeight,
|
||||
const int32_t kiRefStride,
|
||||
uint16_t* pFeatureOfBlock, uint32_t pTimesOfFeatureValue[]);
|
||||
@@ -192,14 +196,17 @@ typedef int32_t (*PGetVarianceFromIntraVaaFunc) (uint8_t* pSampelY, const int32_
|
||||
typedef uint8_t (*PGetMbSignFromInterVaaFunc) (int32_t* pSad8x8);
|
||||
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 bool (*PBuildRefListFunc) (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRefIdx);
|
||||
typedef void (*PMarkPicFunc) (sWelsEncCtx* pCtx);
|
||||
typedef bool (*PUpdateRefListFunc) (sWelsEncCtx* pCtx);
|
||||
typedef void (*PEndofUpdateRefListFunc) (sWelsEncCtx* pCtx);
|
||||
typedef void (*PAfterBuildRefListFunc) (sWelsEncCtx* pCtx);
|
||||
|
||||
typedef int32_t (*PCavlcParamCalFunc) (int16_t* pCoff, uint8_t* pRun, int16_t* pLevel, int32_t* pTotalCoeffs,
|
||||
int32_t iEndIdx);
|
||||
typedef int32_t (*PWelsSpatialWriteMbSyn) (sWelsEncCtx* pCtx, SSlice* pSlice, SMB* pCurMb);
|
||||
typedef void (*PStashMBStatus) (SDynamicSlicingStack* pDss, SSlice* pSlice, int32_t iMbSkipRun);
|
||||
typedef int32_t (*PStashPopMBStatus) (SDynamicSlicingStack* pDss, SSlice* pSlice);
|
||||
|
||||
struct TagWelsFuncPointerList {
|
||||
SExpandPicFunc sExpandPicFunc;
|
||||
@@ -297,6 +304,9 @@ struct TagWelsFuncPointerList {
|
||||
PAfterBuildRefListFunc pAfterBuildRefList;
|
||||
|
||||
PCavlcParamCalFunc pfCavlcParamCal;
|
||||
PWelsSpatialWriteMbSyn pfWelsSpatialWriteMbSyn;
|
||||
PStashMBStatus pfStashMBStatus;
|
||||
PStashPopMBStatus pfStashPopMBStatus;
|
||||
};
|
||||
|
||||
} //end of namespace WelsEnc {
|
||||
|
||||
@@ -77,7 +77,7 @@ typedef struct {
|
||||
unsigned char* pBestBlockStaticIdc;
|
||||
} SRefInfoParam;
|
||||
|
||||
typedef struct {
|
||||
typedef struct TagVAAFrameInfo {
|
||||
SVAACalcResult sVaaCalcInfo;
|
||||
SAdaptiveQuantizationParam sAdaptiveQuantParam;
|
||||
SComplexityAnalysisParam sComplexityAnalysisParam;
|
||||
@@ -106,7 +106,8 @@ typedef struct {
|
||||
typedef struct SVAAFrameInfoExt_t: public SVAAFrameInfo {
|
||||
SComplexityAnalysisScreenParam sComplexityScreenParam;
|
||||
SScrollDetectionParam sScrollDetectInfo;
|
||||
SRefInfoParam sVaaStrBestRefCandidate[MAX_REF_PIC_COUNT]; //TOP3_BEST_REF_NO_TID
|
||||
SRefInfoParam sVaaStrBestRefCandidate[MAX_REF_PIC_COUNT];
|
||||
SRefInfoParam sVaaLtrBestRefCandidate[MAX_REF_PIC_COUNT];
|
||||
int32_t iNumOfAvailableRef;
|
||||
|
||||
int32_t iVaaBestRefFrameNum;
|
||||
@@ -127,7 +128,7 @@ class CWelsPreProcess {
|
||||
int32_t AnalyzeSpatialPic (sWelsEncCtx* pEncCtx, const int32_t kiDIdx);
|
||||
int32_t UpdateSpatialPictures (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam, const int8_t iCurTid,
|
||||
const int32_t d_idx);
|
||||
int32_t GetRefFrameInfo (int32_t iRefIdx, SPicture*& pRefOri);
|
||||
int32_t GetRefFrameInfo (int32_t iRefIdx, bool bCurrentFrameIsSceneLtr, 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);
|
||||
|
||||
@@ -73,7 +73,19 @@ static inline int32_t WelsCheckLevelLimitation (const SWelsSPS* kpSps, const SLe
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int32_t WelsAdjustLevel (SSpatialLayerConfig* pSpatialLayer) {
|
||||
int32_t iLevel = (int32_t)pSpatialLayer->uiLevelIdc;
|
||||
int32_t iMaxBitrate = pSpatialLayer->iMaxSpatialBitrate;
|
||||
while (iLevel <= LEVEL_5_2) {
|
||||
int32_t iLevelMaxBitrate = g_ksLevelLimits[pSpatialLayer->uiLevelIdc - 1].uiMaxBR * CpbBrNalFactor;
|
||||
if (iMaxBitrate < iLevelMaxBitrate) {
|
||||
pSpatialLayer->uiLevelIdc = (ELevelIdc)iLevel;
|
||||
return 0;
|
||||
}
|
||||
iLevel++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int32_t WelsCheckRefFrameLimitation (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam) {
|
||||
int32_t i = 0;
|
||||
int32_t iRefFrame = 1;
|
||||
@@ -86,8 +98,11 @@ int32_t WelsCheckRefFrameLimitation (SLogContext* pLogCtx, SWelsSvcCodingParam*
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "change level to level5.0");
|
||||
}
|
||||
iRefFrame = g_ksLevelLimits[pSpatialLayer->uiLevelIdc - 1].uiMaxDPBMbs / uiPicInMBs;
|
||||
if (iRefFrame < pParam->iMaxNumRefFrame)
|
||||
if (iRefFrame < pParam->iMaxNumRefFrame) {
|
||||
pParam->iMaxNumRefFrame = iRefFrame;
|
||||
if (pParam->iMaxNumRefFrame < pParam->iNumRefFrame)
|
||||
pParam->iNumRefFrame = pParam->iMaxNumRefFrame;
|
||||
}
|
||||
if (pParam->iMaxNumRefFrame < 1) {
|
||||
pParam->iMaxNumRefFrame = 1;
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "error Level setting (%d)", pSpatialLayer->uiLevelIdc);
|
||||
@@ -97,14 +112,14 @@ int32_t WelsCheckRefFrameLimitation (SLogContext* pLogCtx, SWelsSvcCodingParam*
|
||||
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
static inline int32_t WelsGetLevelIdc (const SWelsSPS* kpSps, float fFrameRate, int32_t iTargetBitRate) {
|
||||
static inline ELevelIdc WelsGetLevelIdc (const SWelsSPS* kpSps, float fFrameRate, int32_t iTargetBitRate) {
|
||||
int32_t iOrder;
|
||||
for (iOrder = 0; iOrder < LEVEL_NUMBER; iOrder++) {
|
||||
if (WelsCheckLevelLimitation (kpSps, & (g_ksLevelLimits[iOrder]), fFrameRate, iTargetBitRate)) {
|
||||
return (int32_t) (g_ksLevelLimits[iOrder].uiLevelIdc);
|
||||
return (g_ksLevelLimits[iOrder].uiLevelIdc);
|
||||
}
|
||||
}
|
||||
return 51; //final decision: select the biggest level
|
||||
return LEVEL_5_1; //final decision: select the biggest level
|
||||
}
|
||||
|
||||
|
||||
@@ -266,7 +281,7 @@ int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaS
|
||||
}
|
||||
#endif
|
||||
|
||||
BsWriteOneBit (pLocalBitStringAux, false/*pPps->entropy_coding_mode_flag*/);
|
||||
BsWriteOneBit (pLocalBitStringAux, pPps->bEntropyCodingModeFlag);
|
||||
BsWriteOneBit (pLocalBitStringAux, false/*pPps->bPicOrderPresentFlag*/);
|
||||
|
||||
#ifdef DISABLE_FMO_FEATURE
|
||||
@@ -347,9 +362,10 @@ static inline bool WelsGetPaddingOffset (int32_t iActualWidth, int32_t iActualHe
|
||||
}
|
||||
int32_t WelsInitSps (SWelsSPS* pSps, SSpatialLayerConfig* pLayerParam, SSpatialLayerInternal* pLayerParamInternal,
|
||||
const uint32_t kuiIntraPeriod, const int32_t kiNumRefFrame,
|
||||
const uint32_t kuiSpsId, const bool kbEnableFrameCropping, bool bEnableRc) {
|
||||
const uint32_t kuiSpsId, const bool kbEnableFrameCropping, bool bEnableRc,
|
||||
const int32_t kiDlayerCount) {
|
||||
memset (pSps, 0, sizeof (SWelsSPS));
|
||||
|
||||
ELevelIdc uiLevel = LEVEL_5_2;
|
||||
pSps->uiSpsId = kuiSpsId;
|
||||
pSps->iMbWidth = (pLayerParam->iVideoWidth + 15) >> 4;
|
||||
pSps->iMbHeight = (pLayerParam->iVideoHeight + 15) >> 4;
|
||||
@@ -371,18 +387,34 @@ int32_t WelsInitSps (SWelsSPS* pSps, SSpatialLayerConfig* pLayerParam, SSpatialL
|
||||
pSps->uiProfileIdc = pLayerParam->uiProfileIdc ? pLayerParam->uiProfileIdc : PRO_BASELINE;
|
||||
|
||||
if (bEnableRc) //fixed QP condition
|
||||
pSps->iLevelIdc = WelsGetLevelIdc (pSps, pLayerParamInternal->fOutputFrameRate, pLayerParam->iSpatialBitrate);
|
||||
uiLevel = WelsGetLevelIdc (pSps, pLayerParamInternal->fOutputFrameRate, pLayerParam->iSpatialBitrate);
|
||||
else
|
||||
pSps->iLevelIdc = WelsGetLevelIdc (pSps, pLayerParamInternal->fOutputFrameRate,
|
||||
0); // Set tar_br = 0 to remove the bitrate constraint; a better way is to set actual tar_br as 0
|
||||
uiLevel = WelsGetLevelIdc (pSps, pLayerParamInternal->fOutputFrameRate,
|
||||
0); // Set tar_br = 0 to remove the bitrate constraint; a better way is to set actual tar_br as 0
|
||||
|
||||
|
||||
if (pLayerParam->uiProfileIdc == PRO_BASELINE) {
|
||||
pSps->bConstraintSet0Flag = true;
|
||||
}
|
||||
if (pLayerParam->uiProfileIdc <= PRO_MAIN) {
|
||||
pSps->bConstraintSet1Flag = true;
|
||||
}
|
||||
if (kiDlayerCount > 1) {
|
||||
pSps->bConstraintSet2Flag = true;
|
||||
}
|
||||
|
||||
//update level
|
||||
//for Scalable Baseline, Scalable High, and Scalable High Intra profiles.If level_idc is equal to 9, the indicated level is level 1b.
|
||||
//for the Baseline, Constrained Baseline, Main, and Extended profiles,If level_idc is equal to 11 and constraint_set3_flag is equal to 1, the indicated level is level 1b.
|
||||
if ((pSps->iLevelIdc == 9) &&
|
||||
if ((uiLevel == LEVEL_1_B) &&
|
||||
((pSps->uiProfileIdc == PRO_BASELINE) || (pSps->uiProfileIdc == PRO_MAIN) || (pSps->uiProfileIdc == PRO_EXTENDED))) {
|
||||
pSps->iLevelIdc = 11;
|
||||
uiLevel = LEVEL_1_1;
|
||||
pSps->bConstraintSet3Flag = true;
|
||||
}
|
||||
if (pLayerParam->uiLevelIdc < uiLevel) {
|
||||
pLayerParam->uiLevelIdc = uiLevel;
|
||||
}
|
||||
pSps->iLevelIdc = g_kuiLevelMaps[pLayerParam->uiLevelIdc - 1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -396,7 +428,7 @@ int32_t WelsInitSubsetSps (SSubsetSps* pSubsetSps, SSpatialLayerConfig* pLayerPa
|
||||
memset (pSubsetSps, 0, sizeof (SSubsetSps));
|
||||
|
||||
WelsInitSps (pSps, pLayerParam, pLayerParamInternal, kuiIntraPeriod, kiNumRefFrame, kuiSpsId, kbEnableFrameCropping,
|
||||
bEnableRc);
|
||||
bEnableRc, 1);
|
||||
|
||||
pSps->uiProfileIdc = (pLayerParam->uiProfileIdc >= PRO_SCALABLE_BASELINE) ? pLayerParam->uiProfileIdc :
|
||||
PRO_SCALABLE_BASELINE;
|
||||
@@ -414,7 +446,8 @@ int32_t WelsInitPps (SWelsPPS* pPps,
|
||||
SSubsetSps* pSubsetSps,
|
||||
const uint32_t kuiPpsId,
|
||||
const bool kbDeblockingFilterPresentFlag,
|
||||
const bool kbUsingSubsetSps) {
|
||||
const bool kbUsingSubsetSps,
|
||||
const bool kbEntropyCodingModeFlag) {
|
||||
SWelsSPS* pUsedSps = NULL;
|
||||
if (pPps == NULL || (pSps == NULL && pSubsetSps == NULL))
|
||||
return 1;
|
||||
@@ -433,6 +466,7 @@ int32_t WelsInitPps (SWelsPPS* pPps,
|
||||
/* fill picture parameter set syntax */
|
||||
pPps->iPpsId = kuiPpsId;
|
||||
pPps->iSpsId = pUsedSps->uiSpsId;
|
||||
pPps->bEntropyCodingModeFlag = kbEntropyCodingModeFlag;
|
||||
#if !defined(DISABLE_FMO_FEATURE)
|
||||
pPps->uiNumSliceGroups = 1; //param->qos_param.sliceGroupCount;
|
||||
if (pPps->uiNumSliceGroups > 1) {
|
||||
|
||||
@@ -152,8 +152,9 @@ void WelsInitBGDFunc (SWelsFuncPtrList* pFuncList, const bool kbEnableBackground
|
||||
* \param pEncCtx sWelsEncCtx*
|
||||
* \return successful - 0; otherwise none 0 for failed
|
||||
*/
|
||||
int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* pParam, uint32_t uiCpuFlag) {
|
||||
int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam, uint32_t uiCpuFlag) {
|
||||
int32_t iReturn = ENC_RETURN_SUCCESS;
|
||||
SWelsFuncPtrList* pFuncList = pEncCtx->pFuncList;
|
||||
bool bScreenContent = (SCREEN_CONTENT_REAL_TIME == pParam->iUsageType);
|
||||
|
||||
/* Functionality utilization of CPU instructions dependency */
|
||||
@@ -209,7 +210,7 @@ int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam*
|
||||
/*init pixel average function*/
|
||||
/*get one column or row pixel when refinement*/
|
||||
WelsInitMcFuncs (pFuncList, uiCpuFlag);
|
||||
InitCoeffFunc (pFuncList, uiCpuFlag);
|
||||
InitCoeffFunc (pFuncList,uiCpuFlag,pParam->iEntropyCodingModeFlag);
|
||||
|
||||
WelsInitEncodingFuncs (pFuncList, uiCpuFlag);
|
||||
WelsInitReconstructionFuncs (pFuncList, uiCpuFlag);
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "crt_util_safe_x.h" // Safe CRT routines like utils for cross platforms
|
||||
#include "slice_multi_threading.h"
|
||||
#include "measure_time.h"
|
||||
#include "svc_set_mb_syn.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
@@ -69,6 +70,44 @@ int32_t WelsCodeOnePicPartition (sWelsEncCtx* pCtx,
|
||||
);
|
||||
|
||||
|
||||
int32_t WelsBitRateVerification (SLogContext* pLogCtx, SSpatialLayerConfig* pLayerParam, int32_t iLayerId) {
|
||||
if (pLayerParam->iSpatialBitrate <= 0) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "Invalid bitrate settings in layer %d, bitrate= %d", iLayerId,
|
||||
pLayerParam->iSpatialBitrate);
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
if (pLayerParam->iMaxSpatialBitrate == pLayerParam->iSpatialBitrate) {
|
||||
WelsLog (pLogCtx, WELS_LOG_INFO,
|
||||
"Setting MaxSpatialBitrate (%d) the same at SpatialBitrate (%d) will make the actual bit rate lower than SpatialBitrate",
|
||||
pLayerParam->iMaxSpatialBitrate, pLayerParam->iSpatialBitrate);
|
||||
}
|
||||
int32_t iLevelMaxBitrate = g_ksLevelLimits[pLayerParam->uiLevelIdc - 1].uiMaxBR * CpbBrNalFactor;
|
||||
if (pLayerParam->iMaxSpatialBitrate == UNSPECIFIED_BIT_RATE) {
|
||||
pLayerParam->iMaxSpatialBitrate = iLevelMaxBitrate;
|
||||
WelsLog (pLogCtx, WELS_LOG_INFO, "Current MaxSpatialBitrate is zero,Get this value from level limitation(%d)",
|
||||
pLayerParam->iMaxSpatialBitrate);
|
||||
}
|
||||
if (pLayerParam->iMaxSpatialBitrate > iLevelMaxBitrate) {
|
||||
ELevelIdc iCurLevel = pLayerParam->uiLevelIdc;
|
||||
if (WelsAdjustLevel (pLayerParam)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"MaxSpatialBitrate (%d) is larger that the limitation LEVEL_5_2, the setting will be invalid",
|
||||
pLayerParam->iMaxSpatialBitrate);
|
||||
}
|
||||
WelsLog (pLogCtx, WELS_LOG_INFO,
|
||||
"Level is changed from (%d) to (%d) according to the maxbitrate",
|
||||
iCurLevel, pLayerParam->uiLevelIdc);
|
||||
}
|
||||
if (pLayerParam->iMaxSpatialBitrate < pLayerParam->iSpatialBitrate) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
"MaxSpatialBitrate (%d) should be larger than SpatialBitrate (%d), considering it as error setting",
|
||||
pLayerParam->iMaxSpatialBitrate, pLayerParam->iSpatialBitrate);
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief validate checking in parameter configuration
|
||||
* \pParam pParam SWelsSvcCodingParam*
|
||||
@@ -149,17 +188,9 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||
for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {
|
||||
SSpatialLayerConfig* pSpatialLayer = &pCfg->sSpatialLayers[i];
|
||||
iTotalBitrate += pSpatialLayer->iSpatialBitrate;
|
||||
if (pSpatialLayer->iSpatialBitrate <= 0) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "Invalid bitrate settings in layer %d, bitrate= %d", i,
|
||||
pSpatialLayer->iSpatialBitrate);
|
||||
|
||||
if (WelsBitRateVerification (pLogCtx, pSpatialLayer, i) != ENC_RETURN_SUCCESS)
|
||||
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,
|
||||
@@ -227,6 +258,12 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa
|
||||
pCodingParam->uiIntraPeriod, pCodingParam->uiGopSize);
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
if (pCodingParam->iLoopFilterDisableIdc < 0 || pCodingParam->iLoopFilterDisableIdc > 6) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
"ParamValidationExt(), iLoopFilterDisableIdc(%d) must be between 0 and 6",
|
||||
pCodingParam->iLoopFilterDisableIdc);
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
|
||||
|
||||
//about iMultipleThreadIdc, bDeblockingParallelFlag, iLoopFilterDisableIdc, & uiSliceMode
|
||||
@@ -306,11 +343,20 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa
|
||||
break;
|
||||
}
|
||||
if (pCodingParam->iRCMode != RC_OFF_MODE) { // multiple slices verify with gom
|
||||
//check uiSliceNum
|
||||
GomValidCheckSliceNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);
|
||||
//check uiSliceNum and set uiSliceMbNum with current uiSliceNum
|
||||
if (!GomValidCheckSliceNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"ParamValidationExt(), unsupported setting with Resolution and uiSliceNum combination under RC on! So uiSliceNum is changed to %d!",
|
||||
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);
|
||||
}
|
||||
if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum <= 1 ||
|
||||
!GomValidCheckSliceMbNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.sSliceArgument)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
"ParamValidationExt(), unsupported setting with Resolution and uiSliceNum (%d) combination under RC on! Consider setting single slice with this resolution!",
|
||||
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum);
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
assert (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum > 1);
|
||||
//set uiSliceMbNum with current uiSliceNum
|
||||
GomValidCheckSliceMbNum (iMbWidth, iMbHeight, &pSpatialLayer->sSliceCfg.sSliceArgument);
|
||||
} else if (!CheckFixedSliceNumMultiSliceSetting (iMbNumInFrame,
|
||||
&pSpatialLayer->sSliceCfg.sSliceArgument)) { // verify interleave mode settings
|
||||
//check uiSliceMbNum with current uiSliceNum
|
||||
@@ -460,8 +506,7 @@ void WelsEncoderApplyFrameRate (SWelsSvcCodingParam* pParam) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int iLayer) {
|
||||
int32_t WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int iLayer) {
|
||||
//TODO (Sijia): this is a temporary solution which keep the ratio between layers
|
||||
//but it is also possible to fulfill the bitrate of lower layer first
|
||||
|
||||
@@ -479,8 +524,28 @@ void WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam,
|
||||
pLayerParam = & (pParam->sSpatialLayers[i]);
|
||||
fRatio = pLayerParam->iSpatialBitrate / (static_cast<float> (iOrigTotalBitrate));
|
||||
pLayerParam->iSpatialBitrate = static_cast<int32_t> (pParam->iTargetBitrate * fRatio);
|
||||
|
||||
if (WelsBitRateVerification (pLogCtx, pLayerParam, i) != ENC_RETURN_SUCCESS)
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
}
|
||||
} else {
|
||||
return WelsBitRateVerification (pLogCtx, & (pParam->sSpatialLayers[iLayer]), iLayer);
|
||||
}
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
int32_t WelsEncoderApplyBitVaryRang (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iRang) {
|
||||
SSpatialLayerConfig* pLayerParam;
|
||||
const int32_t iNumLayers = pParam->iSpatialLayerNum;
|
||||
for (int32_t i = 0; i < iNumLayers; i++) {
|
||||
pLayerParam = & (pParam->sSpatialLayers[i]);
|
||||
pLayerParam->iMaxSpatialBitrate = WELS_MIN ((int) (pLayerParam->iSpatialBitrate * (1 + iRang / 100.0)),
|
||||
pLayerParam->iMaxSpatialBitrate);
|
||||
if (WelsBitRateVerification (pLogCtx, pLayerParam, i) != ENC_RETURN_SUCCESS)
|
||||
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||
WelsLog (pLogCtx, WELS_LOG_INFO,
|
||||
"WelsEncoderApplyBitVaryRang:UpdateMaxBitrate layerId= %d,iMaxSpatialBitrate = %d", i, pLayerParam->iMaxSpatialBitrate);
|
||||
}
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -587,7 +652,7 @@ static void InitMbInfo (sWelsEncCtx* pEnc, SMB* pList, SDqLayer* pLayer, con
|
||||
bool bLeftTop;
|
||||
bool bRightTop;
|
||||
int32_t iLeftXY, iTopXY, iLeftTopXY, iRightTopXY;
|
||||
uint8_t uiSliceIdc;
|
||||
uint16_t uiSliceIdc;
|
||||
|
||||
pList[iIdx].iMbX = pEnc->pStrideTab->pMbIndexX[kiDlayerId][iIdx];
|
||||
pList[iIdx].iMbY = pEnc->pStrideTab->pMbIndexY[kiDlayerId][iIdx];
|
||||
@@ -732,6 +797,35 @@ void FreeMbCache (SMbCache* pMbCache, CMemoryAlign* pMa) {
|
||||
}
|
||||
}
|
||||
|
||||
int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||
const int32_t iDlayerCount, const int32_t kiSpsId,
|
||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) {
|
||||
int32_t iRet = 0;
|
||||
|
||||
if (!kbUseSubsetSps) {
|
||||
pSps = & (pCtx->pSpsArray[kiSpsId]);
|
||||
} else {
|
||||
pSubsetSps = & (pCtx->pSubsetArray[kiSpsId]);
|
||||
pSps = &pSubsetSps->pSps;
|
||||
}
|
||||
|
||||
SWelsSvcCodingParam* pParam = pCtx->pSvcParam;
|
||||
SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
|
||||
// Need port pSps/pPps initialization due to spatial scalability changed
|
||||
if (!kbUseSubsetSps) {
|
||||
iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
|
||||
@@ -921,33 +1015,13 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
|
||||
SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
|
||||
|
||||
pDqIdc->uiSpatialId = iDlayerIndex;
|
||||
|
||||
WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
|
||||
iDlayerCount, iSpsId, pSps, pSubsetSps);
|
||||
|
||||
pPps = & (*ppCtx)->pPPSArray[iPpsId];
|
||||
if (!bUseSubsetSps) {
|
||||
pSps = & (*ppCtx)->pSpsArray[iSpsId];
|
||||
} else {
|
||||
pSubsetSps = & (*ppCtx)->pSubsetArray[iSpsId];
|
||||
pSps = &pSubsetSps->pSps;
|
||||
}
|
||||
|
||||
// Need port pSps/pPps initialization due to spatial scalability changed
|
||||
if (!bUseSubsetSps) {
|
||||
WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
iSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE);
|
||||
|
||||
if (iDlayerCount > 1) {
|
||||
pSps->bConstraintSet0Flag = true;
|
||||
pSps->bConstraintSet1Flag = true;
|
||||
pSps->bConstraintSet2Flag = true;
|
||||
}
|
||||
} else {
|
||||
WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||
pParam->iMaxNumRefFrame,
|
||||
iSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE);
|
||||
}
|
||||
|
||||
// initialize pPps
|
||||
WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps);
|
||||
WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
|
||||
|
||||
// Not using FMO in SVC coding so far, come back if need FMO
|
||||
{
|
||||
@@ -1276,7 +1350,6 @@ void GetMvMvdRange (SWelsSvcCodingParam* pParam, int32_t& iMvRange, int32_t& iMv
|
||||
if (pParam->sSpatialLayers[iLayer].uiLevelIdc < iMinLevelIdc)
|
||||
iMinLevelIdc = pParam->sSpatialLayers[iLayer].uiLevelIdc;
|
||||
}
|
||||
|
||||
iMinMv = (g_ksLevelLimits[iMinLevelIdc - 1].iMinVmv) >> 2;
|
||||
iMaxMv = (g_ksLevelLimits[iMinLevelIdc - 1].iMaxVmv) >> 2;
|
||||
|
||||
@@ -1302,11 +1375,6 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
||||
int32_t iResult = 0;
|
||||
float fCompressRatioThr = .5f;
|
||||
const int32_t kiNumDependencyLayers = pParam->iSpatialLayerNum;
|
||||
int32_t iMvdRange = 0;
|
||||
GetMvMvdRange (pParam, (*ppCtx)->iMvRange, iMvdRange);
|
||||
const uint32_t kuiMvdInterTableSize = (iMvdRange << 2); //intepel*4=qpel
|
||||
const uint32_t kuiMvdInterTableStride = 1 + (kuiMvdInterTableSize << 1);//qpel_mv_range*2=(+/-);
|
||||
const uint32_t kuiMvdCacheAlignedSize = kuiMvdInterTableStride * sizeof (uint16_t);
|
||||
int32_t iVclLayersBsSizeCount = 0;
|
||||
int32_t iNonVclLayersBsSizeCount = 0;
|
||||
int32_t iTargetSpatialBsSize = 0;
|
||||
@@ -1511,6 +1579,12 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t iMvdRange = 0;
|
||||
GetMvMvdRange (pParam, (*ppCtx)->iMvRange, iMvdRange);
|
||||
const uint32_t kuiMvdInterTableSize = (iMvdRange << 2); //intepel*4=qpel
|
||||
const uint32_t kuiMvdInterTableStride = 1 + (kuiMvdInterTableSize << 1);//qpel_mv_range*2=(+/-);
|
||||
const uint32_t kuiMvdCacheAlignedSize = kuiMvdInterTableStride * sizeof (uint16_t);
|
||||
|
||||
(*ppCtx)->iMvdCostTableSize = kuiMvdInterTableSize;
|
||||
(*ppCtx)->iMvdCostTableStride = kuiMvdInterTableStride;
|
||||
(*ppCtx)->pMvdCostTable = (uint16_t*)pMa->WelsMallocz (52 * kuiMvdCacheAlignedSize, "pMvdCostTable");
|
||||
@@ -1857,11 +1931,19 @@ int32_t InitSliceSettings (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPar
|
||||
break;
|
||||
}
|
||||
if (pCodingParam->iRCMode != RC_OFF_MODE) { // multiple slices verify with gom
|
||||
//check uiSliceNum
|
||||
GomValidCheckSliceNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.sSliceArgument.uiSliceNum);
|
||||
assert (pDlp->sSliceCfg.sSliceArgument.uiSliceNum > 1);
|
||||
//set uiSliceMbNum with current uiSliceNum
|
||||
GomValidCheckSliceMbNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.sSliceArgument);
|
||||
//check uiSliceNum and set uiSliceMbNum with current uiSliceNum
|
||||
if (!GomValidCheckSliceNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.sSliceArgument.uiSliceNum)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"ParamValidationExt(), unsupported setting with Resolution and uiSliceNum combination under RC on! So uiSliceNum is changed to %d!",
|
||||
pDlp->sSliceCfg.sSliceArgument.uiSliceNum);
|
||||
}
|
||||
if (pDlp->sSliceCfg.sSliceArgument.uiSliceNum <= 1 ||
|
||||
!GomValidCheckSliceMbNum (kiMbWidth, kiMbHeight, &pDlp->sSliceCfg.sSliceArgument)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
"ParamValidationExt(), unsupported setting with Resolution and uiSliceNum (%d) combination under RC on! Consider setting single slice with this resolution!",
|
||||
pDlp->sSliceCfg.sSliceArgument.uiSliceNum);
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
} else if (!CheckFixedSliceNumMultiSliceSetting (kiMbNumInFrame,
|
||||
&pDlp->sSliceCfg.sSliceArgument)) { // verify interleave mode settings
|
||||
//check uiSliceMbNum with current uiSliceNum
|
||||
@@ -1893,7 +1975,7 @@ int32_t InitSliceSettings (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPar
|
||||
2; // Disable loop filter on slice boundaries since that's not allowed with multithreading
|
||||
*pMaxSliceCount = iMaxSliceCount;
|
||||
|
||||
return 0;
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2053,7 +2135,7 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
||||
FreeMemorySvc (&pCtx);
|
||||
return 1;
|
||||
}
|
||||
InitFunctionPointers (pCtx->pFuncList, pCtx->pSvcParam, uiCpuFeatureFlags);
|
||||
InitFunctionPointers (pCtx, pCtx->pSvcParam, uiCpuFeatureFlags);
|
||||
|
||||
pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum;
|
||||
pCtx->iMaxSliceCount = iSliceNum;
|
||||
@@ -2064,9 +2146,16 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
||||
return iRet;
|
||||
}
|
||||
|
||||
if (pCodingParam->iMultipleThreadIdc > 1)
|
||||
if (pCodingParam->iMultipleThreadIdc > 1) {
|
||||
iRet = CreateSliceThreads (pCtx);
|
||||
|
||||
if (iRet != 0) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), CreateSliceThreads failed return %d.", iRet);
|
||||
FreeMemorySvc (&pCtx);
|
||||
return iRet;
|
||||
}
|
||||
}
|
||||
if (pCodingParam->iEntropyCodingModeFlag)
|
||||
WelsCabacInit (pCtx);
|
||||
WelsRcInitModule (pCtx, pCtx->pSvcParam->iRCMode);
|
||||
|
||||
pCtx->pVpp = new CWelsPreProcess (pCtx);
|
||||
@@ -2198,20 +2287,18 @@ void WelsUninitEncoderExt (sWelsEncCtx** ppCtx) {
|
||||
const int32_t iThreadCount = (*ppCtx)->pSvcParam->iCountThreadsNum;
|
||||
int32_t iThreadIdx = 0;
|
||||
|
||||
if ((*ppCtx)->pSliceThreading->pExitEncodeEvent != NULL) {
|
||||
while (iThreadIdx < iThreadCount) {
|
||||
int res = 0;
|
||||
if ((*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx]) {
|
||||
WelsEventSignal (& (*ppCtx)->pSliceThreading->pExitEncodeEvent[iThreadIdx]);
|
||||
WelsEventSignal (& (*ppCtx)->pSliceThreading->pThreadMasterEvent[iThreadIdx]);
|
||||
res = WelsThreadJoin ((*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx]); // waiting thread exit
|
||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_INFO, "WelsUninitEncoderExt(), pthread_join(pThreadHandles%d) return %d..",
|
||||
iThreadIdx,
|
||||
res);
|
||||
(*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx] = 0;
|
||||
}
|
||||
++ iThreadIdx;
|
||||
while (iThreadIdx < iThreadCount) {
|
||||
int res = 0;
|
||||
if ((*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx]) {
|
||||
WelsEventSignal (& (*ppCtx)->pSliceThreading->pExitEncodeEvent[iThreadIdx]);
|
||||
WelsEventSignal (& (*ppCtx)->pSliceThreading->pThreadMasterEvent[iThreadIdx]);
|
||||
res = WelsThreadJoin ((*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx]); // waiting thread exit
|
||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_INFO, "WelsUninitEncoderExt(), pthread_join(pThreadHandles%d) return %d..",
|
||||
iThreadIdx,
|
||||
res);
|
||||
(*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx] = 0;
|
||||
}
|
||||
++ iThreadIdx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2248,7 +2335,7 @@ void DynslcUpdateMbNeighbourInfoListForAllSlices (SSliceCtx* pSliceCtx, SMB* pMb
|
||||
bool bTop;
|
||||
bool bLeftTop;
|
||||
bool bRightTop;
|
||||
int32_t uiSliceIdc;
|
||||
uint16_t uiSliceIdc;
|
||||
int32_t iLeftXY, iTopXY, iLeftTopXY, iRightTopXY;
|
||||
|
||||
uiSliceIdc = WelsMbToSliceIdc (pSliceCtx, kiMbXY);
|
||||
@@ -2323,7 +2410,8 @@ void UpdateSlicepEncCtxWithPartition (SSliceCtx* pSliceCtx, int32_t iPartitionNu
|
||||
}
|
||||
pSliceCtx->pFirstMbInSlice[i] = iFirstMbIdx;
|
||||
|
||||
memset (pSliceCtx->pOverallMbMap + iFirstMbIdx, (uint8_t)i, pSliceCtx->pCountMbNumInSlice[i]*sizeof (uint8_t));
|
||||
WelsSetMemMultiplebytes_c (pSliceCtx->pOverallMbMap + iFirstMbIdx, i,
|
||||
pSliceCtx->pCountMbNumInSlice[i], sizeof (uint16_t));
|
||||
|
||||
// for next partition(or pSlice)
|
||||
iFirstMbIdx += pSliceCtx->pCountMbNumInSlice[i];
|
||||
@@ -2711,7 +2799,7 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
|
||||
* \brief write all parameter sets introduced in SVC extension
|
||||
* \return writing results, success or error
|
||||
*/
|
||||
int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pNumNal) {
|
||||
int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pNumNal, int32_t* pTotalLength) {
|
||||
int32_t iSize = 0;
|
||||
int32_t iNal = 0;
|
||||
int32_t iIdx = 0;
|
||||
@@ -2723,6 +2811,7 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
||||
if (NULL == pCtx || NULL == pNalLen || NULL == pNumNal)
|
||||
return ENC_RETURN_UNEXPECTED;
|
||||
|
||||
*pTotalLength = 0;
|
||||
/* write all SPS */
|
||||
iIdx = 0;
|
||||
while (iIdx < pCtx->iSpsNum) {
|
||||
@@ -2809,6 +2898,7 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
||||
}
|
||||
|
||||
*pNumNal = iCountNal;
|
||||
*pTotalLength = iSize;
|
||||
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
@@ -2919,13 +3009,14 @@ int32_t WelsEncoderEncodeParameterSets (sWelsEncCtx* pCtx, void* pDst) {
|
||||
SFrameBSInfo* pFbi = (SFrameBSInfo*)pDst;
|
||||
SLayerBSInfo* pLayerBsInfo = &pFbi->sLayerInfo[0];
|
||||
int32_t iCountNal = 0;
|
||||
int32_t iTotalLength = 0;
|
||||
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs;
|
||||
pLayerBsInfo->pNalLengthInByte = pCtx->pOut->pNalLen;
|
||||
InitBits (&pCtx->pOut->sBsWrite, pCtx->pOut->pBsBuffer, pCtx->pOut->uiSize);
|
||||
|
||||
pCtx->iPosBsBuffer = 0;
|
||||
int32_t iReturn = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal);
|
||||
int32_t iReturn = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iTotalLength);
|
||||
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
|
||||
|
||||
pLayerBsInfo->uiSpatialId = 0;
|
||||
@@ -2959,29 +3050,6 @@ int32_t GetSubSequenceId (sWelsEncCtx* pCtx, EVideoFrameType eFrameType) {
|
||||
return iSubSeqId;
|
||||
}
|
||||
|
||||
//loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
|
||||
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)) {
|
||||
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, eFrameType, uiTimeStamp);
|
||||
if (true == pCtx->pWelsSvcRc[pCtx->uiDependencyId].bSkipFlag) {
|
||||
bSkipMustFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bSkipMustFlag;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief core svc encoding process
|
||||
*
|
||||
@@ -3032,30 +3100,37 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pFbi->uiTimeStamp = pSrcPic->uiTimeStamp;
|
||||
// perform csc/denoise/downsample/padding, generate spatial layers
|
||||
iSpatialNum = pCtx->pVpp->BuildSpatialPicList (pCtx, pSrcPic);
|
||||
|
||||
if (pCtx->pSvcParam->bEnableFrameSkip) {
|
||||
UpdateMaxBrCheckWindowStatus (pCtx, iSpatialNum, pSrcPic->uiTimeStamp);
|
||||
}
|
||||
|
||||
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);
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
eFrameType = DecideFrameType (pCtx, iSpatialNum);
|
||||
if (eFrameType == videoFrameTypeSkip) {
|
||||
UpdateBufferWhenFrameSkipped (pCtx, iSpatialNum);
|
||||
pFbi->eFrameType = eFrameType;
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %8" PRId64", skip one frame",
|
||||
(int64_t)pSrcPic->uiTimeStamp);
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
//loop each layer to check if have skip frame when RC and frame skip enable
|
||||
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);
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
|
||||
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
pCtx->iContinualSkipFrames = 0;
|
||||
InitFrameCoding (pCtx, eFrameType);
|
||||
|
||||
iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[pSpatialIndexMap->iDid], pCtx->iCodingIndex,
|
||||
@@ -3066,11 +3141,12 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pLayerBsInfo->pNalLengthInByte = pCtx->pOut->pNalLen;
|
||||
|
||||
if (eFrameType == videoFrameTypeIDR) {
|
||||
++ pCtx->sPSOVector.uiIdrPicId;
|
||||
++ pCtx->uiIdrPicId;
|
||||
//if ( pSvcParam->bEnableSSEI )
|
||||
|
||||
// write parameter sets bitstream here
|
||||
pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal);
|
||||
int32_t iNonVclSize = 0;
|
||||
pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iNonVclSize);
|
||||
WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
|
||||
|
||||
pLayerBsInfo->uiSpatialId = 0;
|
||||
@@ -3083,6 +3159,8 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
|
||||
++ iLayerNum;
|
||||
|
||||
iFrameSize += iNonVclSize;
|
||||
}
|
||||
|
||||
pCtx->pCurDqLayer = pCtx->ppDqLayerList[pSpatialIndexMap->iDid];
|
||||
@@ -3561,7 +3639,8 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
|
||||
|
||||
#if GOM_TRACE_FLAG
|
||||
WelsLog (pLogCtx, WELS_LOG_INFO, "[RC] encoding_qp%d Padding: %d", pCtx->uiDependencyId,
|
||||
WelsLog (pLogCtx, WELS_LOG_INFO, "[RC] dependency ID = %d,encoding_qp = %d Padding: %d", pCtx->uiDependencyId,
|
||||
pCtx->iGlobalQp,
|
||||
pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingSize);
|
||||
#endif
|
||||
if (iPaddingNalSize <= 0)
|
||||
@@ -3581,6 +3660,8 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
|
||||
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + 1;
|
||||
++ iLayerNum;
|
||||
|
||||
iFrameSize += iPaddingNalSize;
|
||||
}
|
||||
|
||||
if ((pParam->sSliceCfg.uiSliceMode == SM_FIXEDSLCNUM_SLICE || pParam->sSliceCfg.uiSliceMode == SM_AUTO_SLICE)
|
||||
@@ -3644,9 +3725,17 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
pCtx->eLastNalPriority = eNalRefIdc;
|
||||
pFbi->iLayerNum = iLayerNum;
|
||||
pFbi->iSubSeqId = GetSubSequenceId (pCtx, eFrameType);
|
||||
|
||||
WelsLog (pLogCtx, WELS_LOG_DEBUG, "WelsEncoderEncodeExt() OutputInfo iLayerNum = %d,iSubSeqId = %d,iFrameSize = %d",
|
||||
iLayerNum,
|
||||
pFbi->iSubSeqId, iFrameSize);
|
||||
for (int32_t i = 0; i < iLayerNum; i++)
|
||||
WelsLog (pLogCtx, WELS_LOG_DEBUG, "WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d", i,
|
||||
pFbi->sLayerInfo[i].uiLayerType, pFbi->sLayerInfo[i].iNalCount);
|
||||
WelsEmms();
|
||||
|
||||
pFbi->eFrameType = eFrameType;
|
||||
pFbi->iFrameSizeInBytes = iFrameSize;
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3743,7 +3832,7 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));
|
||||
memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
uiTmpIdrPicId = (*ppCtx)->sPSOVector.uiIdrPicId;
|
||||
uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;
|
||||
|
||||
SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;
|
||||
|
||||
@@ -3761,7 +3850,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
||||
//for FLEXIBLE_PARASET_ID
|
||||
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
|
||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||
(*ppCtx)->sPSOVector.uiIdrPicId = uiTmpIdrPicId;
|
||||
//for LTR
|
||||
(*ppCtx)->uiIdrPicId = uiTmpIdrPicId;
|
||||
//for sEncoderStatistics
|
||||
(*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;
|
||||
} else {
|
||||
@@ -3900,15 +3990,19 @@ int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
|
||||
iMaxSliceNum *= SLICE_NUM_EXPAND_COEF;
|
||||
|
||||
SWelsNalRaw* pNalList = (SWelsNalRaw*)pMA->WelsMalloc (iCountNals * sizeof (SWelsNalRaw), "pOut->sNalList");
|
||||
if (NULL == pNalList)
|
||||
if (NULL == pNalList) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::DynSliceRealloc: pNalList is NULL");
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
memcpy (pNalList, pCtx->pOut->sNalList, sizeof (SWelsNalRaw) * pCtx->pOut->iCountNals);
|
||||
pMA->WelsFree (pCtx->pOut->sNalList, "pOut->sNalList");
|
||||
pCtx->pOut->sNalList = pNalList;
|
||||
|
||||
int32_t* pNalLen = (int32_t*)pMA->WelsMalloc (iCountNals * sizeof (int32_t), "pOut->pNalLen");
|
||||
if (NULL == pNalLen)
|
||||
if (NULL == pNalLen) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::DynSliceRealloc: pNalLen is NULL");
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
memcpy (pNalLen, pCtx->pOut->pNalLen, sizeof (int32_t) * pCtx->pOut->iCountNals);
|
||||
pMA->WelsFree (pCtx->pOut->pNalLen, "pOut->pNalLen");
|
||||
pCtx->pOut->pNalLen = pNalLen;
|
||||
@@ -3924,8 +4018,10 @@ int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
|
||||
}
|
||||
|
||||
SSlice* pSlice = (SSlice*)pMA->WelsMallocz (sizeof (SSlice) * iMaxSliceNum, "Slice");
|
||||
if (NULL == pSlice)
|
||||
if (NULL == pSlice) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::DynSliceRealloc: pSlice is NULL");
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
memcpy (pSlice, pCurLayer->sLayerInfo.pSliceInLayer, sizeof (SSlice) * iMaxSliceNumOld);
|
||||
int32_t uiSliceIdx;
|
||||
uiSliceIdx = iMaxSliceNumOld;
|
||||
@@ -3939,8 +4035,12 @@ int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
|
||||
pSliceIdx->pSliceBsa = &pCtx->pSliceBs[uiSliceIdx].sBsWrite;
|
||||
else
|
||||
pSliceIdx->pSliceBsa = &pCtx->pOut->sBsWrite;
|
||||
if (AllocMbCacheAligned (&pSliceIdx->sMbCacheInfo, pMA))
|
||||
if (AllocMbCacheAligned (&pSliceIdx->sMbCacheInfo, pMA)) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
|
||||
"CWelsH264SVCEncoder::DynSliceRealloc: realloc MbCache not successful at slice_idx=%d (max-slice=%d)",
|
||||
uiSliceIdx, iMaxSliceNum);
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
|
||||
pSliceIdx->bSliceHeaderExtFlag = pBaseSlice->bSliceHeaderExtFlag;
|
||||
pSHExt->sSliceHeader.iPpsId = pBaseSHExt->sSliceHeader.iPpsId;
|
||||
@@ -3959,8 +4059,10 @@ int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
|
||||
pCurLayer->sLayerInfo.pSliceInLayer = pSlice;
|
||||
|
||||
int16_t* pFirstMbInSlice = (int16_t*)pMA->WelsMalloc (iMaxSliceNum * sizeof (int16_t), "pSliceSeg->pFirstMbInSlice");
|
||||
if (NULL == pFirstMbInSlice)
|
||||
if (NULL == pFirstMbInSlice) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::DynSliceRealloc: pFirstMbInSlice is NULL");
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
memset (pFirstMbInSlice, 0, sizeof (int16_t) * iMaxSliceNum);
|
||||
memcpy (pFirstMbInSlice, pCurLayer->pSliceEncCtx->pFirstMbInSlice, sizeof (int16_t) * iMaxSliceNumOld);
|
||||
pMA->WelsFree (pCurLayer->pSliceEncCtx->pFirstMbInSlice, "pSliceSeg->pFirstMbInSlice");
|
||||
@@ -3968,8 +4070,11 @@ int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
|
||||
|
||||
int32_t* pCountMbNumInSlice = (int32_t*)pMA->WelsMalloc (iMaxSliceNum * sizeof (int32_t),
|
||||
"pSliceSeg->pCountMbNumInSlice");
|
||||
if (NULL == pCountMbNumInSlice)
|
||||
if (NULL == pCountMbNumInSlice) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
|
||||
"CWelsH264SVCEncoder::DynSliceRealloc: realloc pCountMbNumInSlice not successful");
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
memcpy (pCountMbNumInSlice, pCurLayer->pSliceEncCtx->pCountMbNumInSlice, sizeof (int32_t) * iMaxSliceNumOld);
|
||||
uiSliceIdx = iMaxSliceNumOld;
|
||||
while (uiSliceIdx < iMaxSliceNum) {
|
||||
@@ -3980,8 +4085,11 @@ int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
|
||||
pCurLayer->pSliceEncCtx->pCountMbNumInSlice = pCountMbNumInSlice;
|
||||
|
||||
SRCSlicing* pSlcingOverRc = (SRCSlicing*)pMA->WelsMalloc (iMaxSliceNum * sizeof (SRCSlicing), "SlicingOverRC");
|
||||
if (NULL == pSlcingOverRc)
|
||||
if (NULL == pSlcingOverRc) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
|
||||
"CWelsH264SVCEncoder::DynSliceRealloc: realloc pSlcingOverRc not successful");
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
memcpy (pSlcingOverRc, pCtx->pWelsSvcRc->pSlicingOverRc, sizeof (SRCSlicing) * iMaxSliceNumOld);
|
||||
uiSliceIdx = iMaxSliceNumOld;
|
||||
SRCSlicing* pSORC = &pSlcingOverRc[uiSliceIdx];
|
||||
@@ -4045,9 +4153,16 @@ int32_t WelsCodeOnePicPartition (sWelsEncCtx* pCtx,
|
||||
|
||||
if (iSliceIdx >= (pSliceCtx->iMaxSliceNumConstraint - kiSliceIdxStep)) { // insufficient memory in pSliceInLayer[]
|
||||
if (pCtx->iActiveThreadsNum == 1) {
|
||||
if (DynSliceRealloc (pCtx, pFrameBSInfo, pLayerBsInfo)) //only single thread support re-alloc now
|
||||
//only single thread support re-alloc now
|
||||
if (DynSliceRealloc (pCtx, pFrameBSInfo, pLayerBsInfo)) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
|
||||
"CWelsH264SVCEncoder::WelsCodeOnePicPartition: DynSliceRealloc not successful");
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
} else if (iSliceIdx >= pSliceCtx->iMaxSliceNumConstraint) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
|
||||
"CWelsH264SVCEncoder::WelsCodeOnePicPartition: iSliceIdx(%d) over iMaxSliceNumConstraint(%d)", iSliceIdx,
|
||||
pSliceCtx->iMaxSliceNumConstraint);
|
||||
return ENC_RETURN_MEMALLOCERR;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,6 +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)) {
|
||||
//this is our strategy to Unref all non-sceneLTR when the the current frame is sceneLTR
|
||||
pRef->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, i);
|
||||
i--;
|
||||
@@ -310,16 +311,16 @@ static inline void LTRMarkProcessScreen (sWelsEncCtx* pCtx) {
|
||||
int32_t iLtrIdx = pCtx->pDecPic->iLongTermPicNum;
|
||||
pCtx->pVaa->uiMarkLongTermPicIdx = pCtx->pDecPic->iLongTermPicNum;
|
||||
|
||||
assert (CheckInRangeCloseOpen (iLtrIdx, 0, MAX_REF_PIC_COUNT));
|
||||
if (pLongRefList[iLtrIdx] != NULL) {
|
||||
pLongRefList[iLtrIdx]->SetUnref();
|
||||
DeleteLTRFromLongList (pCtx, iLtrIdx);
|
||||
} else {
|
||||
pRefList->uiLongRefCount++;
|
||||
}
|
||||
pLongRefList[iLtrIdx] = pCtx->pDecPic;
|
||||
pRefList->uiLongRefCount++;
|
||||
}
|
||||
|
||||
static void PrefetchNextBuffer (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
static void PrefetchNextBuffer (sWelsEncCtx* pCtx) {
|
||||
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
|
||||
const int32_t kiNumRef = pCtx->pSvcParam->iNumRefFrame;
|
||||
int32_t i;
|
||||
@@ -343,8 +344,7 @@ static void PrefetchNextBuffer (void* pEncCtx) {
|
||||
/*
|
||||
* update reference picture list
|
||||
*/
|
||||
bool WelsUpdateRefList (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
bool WelsUpdateRefList (sWelsEncCtx* pCtx) {
|
||||
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
@@ -442,8 +442,7 @@ bool CheckCurMarkFrameNumUsed (sWelsEncCtx* pCtx) {
|
||||
|
||||
return true;
|
||||
}
|
||||
void WelsMarkPic (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
void WelsMarkPic (sWelsEncCtx* pCtx) {
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
const int32_t kiCountSliceNum = GetCurrentSliceNum (pCtx->pCurDqLayer->pSliceEncCtx);
|
||||
int32_t iGoPFrameNumInterval = ((pCtx->pSvcParam->uiGopSize >> 1) > 1) ? (pCtx->pSvcParam->uiGopSize >> 1) : (1);
|
||||
@@ -496,7 +495,7 @@ int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRec
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
|
||||
if (pCtx->pSvcParam->bEnableLongTermReference) {
|
||||
if (pRequest->uiFeedbackType == LTR_RECOVERY_REQUEST && pRequest->uiIDRPicId == pCtx->sPSOVector.uiIdrPicId) {
|
||||
if (pRequest->uiFeedbackType == LTR_RECOVERY_REQUEST && pRequest->uiIDRPicId == pCtx->uiIdrPicId) {
|
||||
if (pRequest->iLastCorrectFrameNum == -1) {
|
||||
pCtx->bEncCurFrmAsIdrFlag = true;
|
||||
return true;
|
||||
@@ -531,7 +530,7 @@ void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarki
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
assert (pLTRMarkingFeedback);
|
||||
if (pCtx->pSvcParam->bEnableLongTermReference) {
|
||||
if (pLTRMarkingFeedback->uiIDRPicId == pCtx->sPSOVector.uiIdrPicId
|
||||
if (pLTRMarkingFeedback->uiIDRPicId == pCtx->uiIdrPicId
|
||||
&& (pLTRMarkingFeedback->uiFeedbackType == LTR_MARKING_SUCCESS
|
||||
|| pLTRMarkingFeedback->uiFeedbackType == LTR_MARKING_FAILED)) { // avoid error pData
|
||||
pLtr->uiLtrMarkState = pLTRMarkingFeedback->uiFeedbackType;
|
||||
@@ -539,13 +538,13 @@ void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarki
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||
"Receive valid LTR marking feedback, feedback_type = %d , uiIdrPicId = %d , LTR_frame_num = %d , cur_idr_pic_id = %d",
|
||||
pLTRMarkingFeedback->uiFeedbackType, pLTRMarkingFeedback->uiIDRPicId, pLTRMarkingFeedback->iLTRFrameNum ,
|
||||
pCtx->sPSOVector.uiIdrPicId);
|
||||
pCtx->uiIdrPicId);
|
||||
|
||||
} else {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||
"Receive LTR marking feedback, feedback_type = %d , uiIdrPicId = %d , LTR_frame_num = %d , cur_idr_pic_id = %d",
|
||||
pLTRMarkingFeedback->uiFeedbackType, pLTRMarkingFeedback->uiIDRPicId, pLTRMarkingFeedback->iLTRFrameNum ,
|
||||
pCtx->sPSOVector.uiIdrPicId);
|
||||
pCtx->uiIdrPicId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,8 +552,7 @@ void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarki
|
||||
/*
|
||||
* build reference picture list
|
||||
*/
|
||||
bool WelsBuildRefList (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
bool WelsBuildRefList (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRefIdx) {
|
||||
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
const int32_t kiNumRef = pCtx->pSvcParam->iNumRefFrame;
|
||||
@@ -605,8 +603,7 @@ 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;
|
||||
static void UpdateBlockStatic (sWelsEncCtx* pCtx) {
|
||||
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++) {
|
||||
@@ -692,8 +689,7 @@ static inline void UpdateOriginalPicInfo (SPicture* pOrigPic, SPicture* pReconPi
|
||||
pOrigPic->iFrameAverageQp = pReconPic->iFrameAverageQp;
|
||||
}
|
||||
|
||||
static void UpdateSrcPicListLosslessScreenRefSelectionWithLtr (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
static void UpdateSrcPicListLosslessScreenRefSelectionWithLtr (sWelsEncCtx* pCtx) {
|
||||
int32_t iDIdx = pCtx->uiDependencyId;
|
||||
//update info in src list
|
||||
UpdateOriginalPicInfo (pCtx->pEncPic, pCtx->pDecPic);
|
||||
@@ -702,8 +698,7 @@ static void UpdateSrcPicListLosslessScreenRefSelectionWithLtr (void* pEncCtx) {
|
||||
pCtx->ppRefPicListExt[iDIdx]->pLongRefList);
|
||||
}
|
||||
|
||||
static void UpdateSrcPicList (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
static void UpdateSrcPicList (sWelsEncCtx* pCtx) {
|
||||
int32_t iDIdx = pCtx->uiDependencyId;
|
||||
//update info in src list
|
||||
UpdateOriginalPicInfo (pCtx->pEncPic, pCtx->pDecPic);
|
||||
@@ -712,8 +707,7 @@ static void UpdateSrcPicList (void* pEncCtx) {
|
||||
pCtx->ppRefPicListExt[iDIdx]->uiShortRefCount);
|
||||
}
|
||||
|
||||
bool WelsUpdateRefListScreen (void* pEncCtx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
bool WelsUpdateRefListScreen (sWelsEncCtx* pCtx) {
|
||||
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
SSpatialLayerInternal* pParamD = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
|
||||
@@ -761,8 +755,7 @@ bool WelsUpdateRefListScreen (void* pEncCtx) {
|
||||
pCtx->pFuncList->pEndofUpdateRefList (pCtx);
|
||||
return true;
|
||||
}
|
||||
bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx) {
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRefIdx) {
|
||||
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
|
||||
SWelsSvcCodingParam* pParam = pCtx->pSvcParam;
|
||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||
@@ -773,7 +766,7 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
|
||||
int iLtrRefIdx = 0;
|
||||
SPicture* pRefOri = NULL;
|
||||
for (int idx = 0; idx < pVaaExt->iNumOfAvailableRef; idx++) {
|
||||
iLtrRefIdx = pCtx->pVpp->GetRefFrameInfo (idx, pRefOri);
|
||||
iLtrRefIdx = pCtx->pVpp->GetRefFrameInfo (idx, pCtx->bCurFrameMarkedAsSceneLtr, pRefOri);
|
||||
if (iLtrRefIdx >= 0 && iLtrRefIdx <= pParam->iLTRRefNum) {
|
||||
SPicture* pRefPic = pRefList->pLongRefList[iLtrRefIdx];
|
||||
if (pRefPic != NULL && pRefPic->bUsedAsRef && pRefPic->bIsLongRef) {
|
||||
@@ -805,6 +798,29 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
|
||||
}
|
||||
}
|
||||
} // end of (int idx = 0; idx < pVaaExt->iNumOfAvailableRef; idx++)
|
||||
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"WelsBuildRefListScreen(), CurrentFramePoc=%d, isLTR=%d", iPOC, pCtx->bCurFrameMarkedAsSceneLtr);
|
||||
for (int j = 0; j < iNumRef; j++) {
|
||||
SPicture* pARefPicture = pRefList->pLongRefList[j];
|
||||
if (pARefPicture != NULL) {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
|
||||
"WelsBuildRefListScreen()\tRefLot[%d]: iPoc=%d, iPictureType=%d, bUsedAsRef=%d, bIsLongRef=%d, bIsSceneLTR=%d, uiTemporalId=%d, iFrameNum=%d, iMarkFrameNum=%d, iLongTermPicNum=%d, uiRecieveConfirmed=%d",
|
||||
j,
|
||||
pARefPicture->iFramePoc,
|
||||
pARefPicture->iPictureType,
|
||||
pARefPicture->bUsedAsRef,
|
||||
pARefPicture->bIsLongRef,
|
||||
pARefPicture->bIsSceneLTR,
|
||||
pARefPicture->uiTemporalId,
|
||||
pARefPicture->iFrameNum,
|
||||
pARefPicture->iMarkFrameNum,
|
||||
pARefPicture->iLongTermPicNum,
|
||||
pARefPicture->uiRecieveConfirmed);
|
||||
} else {
|
||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "WelsBuildRefListScreen()\tRefLot[%d]: NULL", j);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// dealing with IDR
|
||||
WelsResetRefList (pCtx); //for IDR, SHOULD reset pRef list.
|
||||
@@ -817,9 +833,13 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
|
||||
|
||||
return (pCtx->iNumRef0 > 0 || pCtx->eSliceType == I_SLICE) ? (true) : (false);
|
||||
}
|
||||
void WelsMarkPicScreen (void* pEncCtx) {
|
||||
|
||||
static inline bool IsValidFrameNum (const int32_t kiFrameNum) {
|
||||
return (kiFrameNum < (1 << 30)); // TODO: use the original judge first, may be improved
|
||||
}
|
||||
|
||||
void WelsMarkPicScreen (sWelsEncCtx* pCtx) {
|
||||
#define STR_ROOM 1
|
||||
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
|
||||
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
|
||||
int32_t iMaxTid = WELS_LOG2 (pCtx->pSvcParam->uiGopSize);
|
||||
int32_t iMaxActualLtrIdx = -1;
|
||||
@@ -853,7 +873,6 @@ void WelsMarkPicScreen (void* pEncCtx) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int32_t iMinSTRframe_num = 1 << 30; // is big enough
|
||||
int32_t iRefNum_t[MAX_TEMPORAL_LAYER_NUM] = {0};
|
||||
for (i = 0 ; i < pRefList->uiLongRefCount ; ++i) {
|
||||
if (ppLongRefList[i]->bUsedAsRef && ppLongRefList[i]->bIsLongRef && (!ppLongRefList[i]->bIsSceneLTR)) {
|
||||
@@ -867,11 +886,20 @@ void WelsMarkPicScreen (void* pEncCtx) {
|
||||
iMaxMultiRefTid = i;
|
||||
}
|
||||
}
|
||||
int32_t iLongestDeltaFrameNum = -1;
|
||||
int32_t iMaxFrameNum = (1 << pCtx->pSps->uiLog2MaxFrameNum);
|
||||
|
||||
for (i = 0 ; i < pRefList->uiLongRefCount ; ++i) {
|
||||
if (ppLongRefList[i]->bUsedAsRef && ppLongRefList[i]->bIsLongRef && (!ppLongRefList[i]->bIsSceneLTR)
|
||||
&& iMaxMultiRefTid == ppLongRefList[i]->uiTemporalId) {
|
||||
if (ppLongRefList[i]->iFrameNum < iMinSTRframe_num) {
|
||||
assert (IsValidFrameNum (ppLongRefList[i]->iFrameNum)); // pLtr->iCurLtrIdx must have a value
|
||||
int32_t iDeltaFrameNum = (pCtx->iFrameNum >= ppLongRefList[i]->iFrameNum)
|
||||
? (pCtx->iFrameNum - ppLongRefList[i]->iFrameNum)
|
||||
: (pCtx->iFrameNum + iMaxFrameNum - ppLongRefList[i]->iFrameNum);
|
||||
|
||||
if (iDeltaFrameNum > iLongestDeltaFrameNum) {
|
||||
pLtr->iCurLtrIdx = ppLongRefList[i]->iLongTermPicNum;
|
||||
iLongestDeltaFrameNum = iDeltaFrameNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -904,7 +932,7 @@ void WelsMarkPicScreen (void* pEncCtx) {
|
||||
return;
|
||||
}
|
||||
|
||||
void DoNothing (void* pointer) {
|
||||
void DoNothing (sWelsEncCtx* pointer) {
|
||||
}
|
||||
|
||||
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bWithLtr, const bool bScreenContent) {
|
||||
|
||||
240
codec/encoder/core/src/set_mb_syn_cabac.cpp
Normal file
240
codec/encoder/core/src/set_mb_syn_cabac.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/*!
|
||||
* \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 set_mb_syn_cabac.cpp
|
||||
*
|
||||
* \brief cabac coding engine
|
||||
*
|
||||
* \date 10/11/2014 Created
|
||||
*
|
||||
*************************************************************************************
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "typedefs.h"
|
||||
#include "macros.h"
|
||||
#include "wels_common_defs.h"
|
||||
#include "set_mb_syn_cabac.h"
|
||||
#include "encoder.h"
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
|
||||
void WelsCabacInit (void* pCtx) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
for (int32_t iModel = 0; iModel < 4; iModel++) {
|
||||
for (int32_t iQp = 0; iQp <= WELS_QP_MAX; iQp++)
|
||||
for (int32_t iIdx = 0; iIdx < WELS_CONTEXT_COUNT; iIdx++) {
|
||||
int32_t m = g_kiCabacGlobalContextIdx[iIdx][iModel][0];
|
||||
int32_t n = g_kiCabacGlobalContextIdx[iIdx][iModel][1];
|
||||
int32_t iPreCtxState = WELS_CLIP3 ((((m * iQp) >> 4) + n), 1, 126);
|
||||
uint8_t uiValMps = 0;
|
||||
uint8_t uiStateIdx = 0;
|
||||
if (iPreCtxState <= 63) {
|
||||
uiStateIdx = 63 - iPreCtxState;
|
||||
uiValMps = 0;
|
||||
} else {
|
||||
uiStateIdx = iPreCtxState - 64;
|
||||
uiValMps = 1;
|
||||
}
|
||||
pEncCtx->sWelsCabacContexts[iModel][iQp][iIdx].m_uiState = uiStateIdx;
|
||||
pEncCtx->sWelsCabacContexts[iModel][iQp][iIdx].m_uiValMps = uiValMps;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WelsCabacContextInit (void* pCtx, SCabacCtx* pCbCtx, int32_t iModel) {
|
||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||
int32_t iIdx = pEncCtx->eSliceType == WelsCommon::I_SLICE ? 0 : iModel + 1;
|
||||
int32_t iQp = pEncCtx->iGlobalQp;
|
||||
memcpy (pCbCtx->m_sStateCtx, pEncCtx->sWelsCabacContexts[iIdx][iQp],
|
||||
WELS_CONTEXT_COUNT * sizeof (SStateCtx));
|
||||
}
|
||||
|
||||
void WelsCabacEncodeInit (SCabacCtx* pCbCtx, uint8_t* pBuf, uint8_t* pEnd) {
|
||||
pCbCtx->m_uiLow = 0;
|
||||
pCbCtx->m_uiRange = 510;
|
||||
pCbCtx->m_iBitsOutstanding = 0;
|
||||
pCbCtx->m_uData = 0;
|
||||
pCbCtx->m_uiBitsUsed = 0;
|
||||
pCbCtx->m_iFirstFlag = 1;
|
||||
pCbCtx->m_pBufStart = pBuf;
|
||||
pCbCtx->m_pBufEnd = pEnd;
|
||||
pCbCtx->m_pBufCur = pBuf;
|
||||
pCbCtx->m_uiBinCountsInNalUnits = 0;
|
||||
}
|
||||
|
||||
void WelsCabacPutBit (SCabacCtx* pCbCtx, uint32_t iValue) {
|
||||
if (pCbCtx->m_iFirstFlag != 0) {
|
||||
pCbCtx->m_iFirstFlag = 0;
|
||||
} else {
|
||||
pCbCtx->m_uData = (pCbCtx->m_uData << 1) | iValue;
|
||||
pCbCtx->m_uiBitsUsed++;
|
||||
}
|
||||
if (pCbCtx->m_iBitsOutstanding == 0) {
|
||||
while (pCbCtx->m_uiBitsUsed >= 8) {
|
||||
pCbCtx->m_uiBitsUsed -= 8;
|
||||
uint32_t uiByte = pCbCtx->m_uData >> (pCbCtx->m_uiBitsUsed);
|
||||
if (pCbCtx->m_uiBitsUsed == 0)
|
||||
pCbCtx->m_uData = 0;
|
||||
else
|
||||
pCbCtx->m_uData &= (uint32_t) ((0xFFFFFFFF) >> (32 - pCbCtx->m_uiBitsUsed));
|
||||
*pCbCtx->m_pBufCur ++ = uiByte;
|
||||
}
|
||||
} else {
|
||||
|
||||
while (pCbCtx->m_iBitsOutstanding > 0) {
|
||||
pCbCtx->m_uData = (pCbCtx->m_uData << 1) | (1 - iValue);
|
||||
pCbCtx->m_iBitsOutstanding--;
|
||||
pCbCtx->m_uiBitsUsed++;
|
||||
while (pCbCtx->m_uiBitsUsed >= 8) {
|
||||
pCbCtx->m_uiBitsUsed -= 8;
|
||||
uint32_t uiByte = pCbCtx->m_uData >> (pCbCtx->m_uiBitsUsed);
|
||||
if (pCbCtx->m_uiBitsUsed == 0)
|
||||
pCbCtx->m_uData = 0;
|
||||
else
|
||||
pCbCtx->m_uData &= (uint32_t) ((0xFFFFFFFF) >> (32 - pCbCtx->m_uiBitsUsed));
|
||||
*pCbCtx->m_pBufCur ++ = uiByte;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void WelsCabacEncodeRenorm (SCabacCtx* pCbCtx) {
|
||||
while (pCbCtx->m_uiRange < 256) {
|
||||
if (pCbCtx->m_uiLow < 256) {
|
||||
WelsCabacPutBit (pCbCtx, 0);
|
||||
} else {
|
||||
if (pCbCtx->m_uiLow >= 512) {
|
||||
pCbCtx->m_uiLow -= 512;
|
||||
WelsCabacPutBit (pCbCtx, 1);
|
||||
} else {
|
||||
pCbCtx->m_uiLow -= 256;
|
||||
pCbCtx->m_iBitsOutstanding++;
|
||||
}
|
||||
}
|
||||
pCbCtx->m_uiRange <<= 1;
|
||||
pCbCtx->m_uiLow <<= 1;
|
||||
}
|
||||
}
|
||||
void WelsCabacEncodeDecision (SCabacCtx* pCbCtx, int32_t iCtx, uint32_t uiBin) {
|
||||
uint8_t uiState = pCbCtx->m_sStateCtx[iCtx].m_uiState;
|
||||
uint8_t uiValMps = pCbCtx->m_sStateCtx[iCtx].m_uiValMps;
|
||||
uint32_t uiRangeLps = g_kuiCabacRangeLps[uiState][ (pCbCtx->m_uiRange >> 6) & 3];
|
||||
|
||||
pCbCtx->m_uiRange -= uiRangeLps;
|
||||
if (uiBin != uiValMps) { //LPS
|
||||
pCbCtx->m_uiLow += pCbCtx->m_uiRange;
|
||||
pCbCtx->m_uiRange = uiRangeLps;
|
||||
if (uiState == 0)
|
||||
uiValMps = 1 - uiValMps;
|
||||
pCbCtx->m_sStateCtx[iCtx].m_uiState = g_kuiStateTransTable[uiState][0];
|
||||
pCbCtx->m_sStateCtx[iCtx].m_uiValMps = uiValMps;
|
||||
} else {
|
||||
pCbCtx->m_sStateCtx[iCtx].m_uiState = g_kuiStateTransTable[uiState][1];
|
||||
}
|
||||
WelsCabacEncodeRenorm (pCbCtx);
|
||||
pCbCtx->m_uiBinCountsInNalUnits++;
|
||||
}
|
||||
|
||||
void WelsCabacEncodeBypassOne (SCabacCtx* pCbCtx, uint32_t uiBin) {
|
||||
pCbCtx->m_uiLow <<= 1;
|
||||
if (uiBin) {
|
||||
pCbCtx->m_uiLow += pCbCtx->m_uiRange;
|
||||
}
|
||||
if (pCbCtx->m_uiLow >= 1024) {
|
||||
WelsCabacPutBit (pCbCtx, 1);
|
||||
pCbCtx->m_uiLow -= 1024;
|
||||
} else {
|
||||
if (pCbCtx->m_uiLow < 512)
|
||||
WelsCabacPutBit (pCbCtx, 0);
|
||||
else {
|
||||
pCbCtx->m_uiLow -= 512;
|
||||
pCbCtx->m_iBitsOutstanding++;
|
||||
}
|
||||
}
|
||||
pCbCtx->m_uiBinCountsInNalUnits++;
|
||||
}
|
||||
void WelsCabacEncodeTerminate (SCabacCtx* pCbCtx, uint32_t uiBin) {
|
||||
pCbCtx->m_uiRange -= 2;
|
||||
if (uiBin) {
|
||||
pCbCtx->m_uiLow += pCbCtx->m_uiRange;
|
||||
pCbCtx->m_uiRange = 2;
|
||||
WelsCabacEncodeRenorm (pCbCtx);
|
||||
WelsCabacPutBit (pCbCtx, ((pCbCtx->m_uiLow >> 9) & 1));
|
||||
int32_t iLastTwoBits = (((pCbCtx->m_uiLow >> 7) & 3) | 1);
|
||||
pCbCtx->m_uData = (pCbCtx->m_uData << 2) | iLastTwoBits;
|
||||
pCbCtx->m_uiBitsUsed += 2;
|
||||
} else {
|
||||
WelsCabacEncodeRenorm (pCbCtx);
|
||||
}
|
||||
pCbCtx->m_uiBinCountsInNalUnits++;
|
||||
}
|
||||
void WelsCabacEncodeUeBypass (SCabacCtx* pCbCtx, int32_t iExpBits, uint32_t uiVal) {
|
||||
int32_t iSufS = uiVal;
|
||||
int32_t iStopLoop = 0;
|
||||
int32_t k = iExpBits;
|
||||
do {
|
||||
if (iSufS >= (1 << k)) {
|
||||
WelsCabacEncodeBypassOne (pCbCtx, 1);
|
||||
iSufS = iSufS - (1 << k);
|
||||
k++;
|
||||
} else {
|
||||
WelsCabacEncodeBypassOne (pCbCtx, 0);
|
||||
while (k--)
|
||||
WelsCabacEncodeBypassOne (pCbCtx, (iSufS >> k) & 1);
|
||||
iStopLoop = 1;
|
||||
}
|
||||
} while (!iStopLoop);
|
||||
}
|
||||
|
||||
void WelsCabacEncodeFlush (SCabacCtx* pCbCtx) {
|
||||
WelsCabacEncodeTerminate (pCbCtx, 1);
|
||||
while (pCbCtx->m_uiBitsUsed > 0) {
|
||||
if (pCbCtx->m_uiBitsUsed > 8) {
|
||||
pCbCtx->m_uiBitsUsed -= 8;
|
||||
uint32_t uiByte = pCbCtx->m_uData >> (pCbCtx->m_uiBitsUsed);
|
||||
pCbCtx->m_uData &= (uint32_t) ((0xFFFFFFFF) >> (32 - pCbCtx->m_uiBitsUsed));
|
||||
*pCbCtx->m_pBufCur ++ = uiByte;
|
||||
} else {
|
||||
if (pCbCtx->m_uiBitsUsed == 8) {
|
||||
*pCbCtx->m_pBufCur ++ = pCbCtx->m_uData & 0xff;
|
||||
} else {
|
||||
*pCbCtx->m_pBufCur ++ = (pCbCtx->m_uData << (8 - pCbCtx->m_uiBitsUsed));
|
||||
}
|
||||
pCbCtx->m_uiBitsUsed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint8_t* WelsCabacEncodeGetPtr (SCabacCtx* pCbCtx) {
|
||||
return pCbCtx->m_pBufCur;
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
*************************************************************************************
|
||||
*/
|
||||
|
||||
#include "set_mb_syn_cavlc.h"
|
||||
#include "svc_set_mb_syn.h"
|
||||
#include "vlc_encoder.h"
|
||||
#include "cpu_core.h"
|
||||
#include "wels_const.h"
|
||||
@@ -199,8 +199,47 @@ int32_t WriteBlockResidualCavlc (SWelsFuncPtrList* pFuncList, int16_t* pCoffLev
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
void StashMBStatusCavlc (SDynamicSlicingStack* pDss, SSlice* pSlice, int32_t iMbSkipRun) {
|
||||
SBitStringAux* pBs = pSlice->pSliceBsa;
|
||||
pDss->pBsStackBufPtr = pBs->pBufPtr;
|
||||
pDss->uiBsStackCurBits = pBs->uiCurBits;
|
||||
pDss->iBsStackLeftBits = pBs->iLeftBits;
|
||||
pDss->uiLastMbQp = pSlice->uiLastMbQp;
|
||||
pDss->iMbSkipRunStack = iMbSkipRun;
|
||||
}
|
||||
int32_t StashPopMBStatusCavlc (SDynamicSlicingStack* pDss, SSlice* pSlice) {
|
||||
SBitStringAux* pBs = pSlice->pSliceBsa;
|
||||
pBs->pBufPtr = pDss->pBsStackBufPtr;
|
||||
pBs->uiCurBits = pDss->uiBsStackCurBits;
|
||||
pBs->iLeftBits = pDss->iBsStackLeftBits;
|
||||
pSlice->uiLastMbQp = pDss->uiLastMbQp;
|
||||
return pDss->iMbSkipRunStack;
|
||||
}
|
||||
void StashMBStatusCabac (SDynamicSlicingStack* pDss, SSlice* pSlice, int32_t iMbSkipRun) {
|
||||
SCabacCtx* pCtx = &pSlice->sCabacCtx;
|
||||
memcpy (&pDss->sStoredCabac, pCtx, sizeof (SCabacCtx));
|
||||
pDss->uiLastMbQp = pSlice->uiLastMbQp;
|
||||
pDss->iMbSkipRunStack = iMbSkipRun;
|
||||
}
|
||||
int32_t StashPopMBStatusCabac (SDynamicSlicingStack* pDss, SSlice* pSlice) {
|
||||
SCabacCtx* pCtx = &pSlice->sCabacCtx;
|
||||
memcpy (pCtx, &pDss->sStoredCabac, sizeof (SCabacCtx));
|
||||
pSlice->uiLastMbQp = pDss->uiLastMbQp;
|
||||
return pDss->iMbSkipRunStack;
|
||||
}
|
||||
|
||||
void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag) {
|
||||
void WelsWriteSliceEndSyn (SSlice* pSlice, bool bEntropyCodingModeFlag) {
|
||||
SBitStringAux* pBs = pSlice->pSliceBsa;
|
||||
if (bEntropyCodingModeFlag) {
|
||||
WelsCabacEncodeFlush (&pSlice->sCabacCtx);
|
||||
pBs->pBufPtr = WelsCabacEncodeGetPtr (&pSlice->sCabacCtx);
|
||||
|
||||
} else {
|
||||
BsRbspTrailingBits (pBs);
|
||||
BsFlush (pBs);
|
||||
}
|
||||
}
|
||||
void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag,int32_t iEntropyCodingModeFlag) {
|
||||
pFuncList->pfCavlcParamCal = CavlcParamCal_c;
|
||||
|
||||
#if defined(X86_ASM)
|
||||
@@ -208,6 +247,17 @@ void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag) {
|
||||
// pFuncList->pfCavlcParamCal = CavlcParamCal_sse2;
|
||||
}
|
||||
#endif
|
||||
if (iEntropyCodingModeFlag) {
|
||||
pFuncList->pfStashMBStatus = StashMBStatusCabac;
|
||||
pFuncList->pfStashPopMBStatus = StashPopMBStatusCabac;
|
||||
pFuncList->pfWelsSpatialWriteMbSyn = WelsSpatialWriteMbSynCabac;
|
||||
} else {
|
||||
pFuncList->pfStashMBStatus = StashMBStatusCavlc;
|
||||
pFuncList->pfStashPopMBStatus = StashPopMBStatusCavlc;
|
||||
pFuncList->pfWelsSpatialWriteMbSyn = WelsSpatialWriteMbSyn;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace WelsEnc
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user