Compare commits

...

669 Commits

Author SHA1 Message Date
sijchen
4adf9cd6dd Merge pull request #1877 from ruil2/vui_base1.4
fix vui writting
2015-03-25 15:43:00 +08:00
ruil2
343c7f2923 fix vui writting 2015-03-25 14:31:37 +08:00
sijchen
bdb850d29e Merge pull request #1873 from huili2/fix_1145964_v14
fix order of null pointer protection
2015-03-25 11:17:11 +08:00
huili2
d3ff712c15 fix order of null pointer protection 2015-03-24 18:55:13 -07:00
sijchen
52cb8c1135 Merge pull request #1866 from ruil2/flag_change
Flag change
2015-03-18 16:55:22 +08:00
ruil2
440689458a update tables and update ut for different return value 2015-03-18 16:15:40 +08:00
ruil2
dc8471894b update bGapsInFrameNumValueAllowedFlag according to parameters setting 2015-03-18 16:15:25 +08:00
ruil2
3cbcc043f9 Merge pull request #1855 from sijchen/fix_rc14
[Encoder] fix a variable usage in RC
2015-03-16 17:20:54 +08:00
Sijia Chen
f0732c2c76 fix an uninitialization in RC when slice-increasing 2015-03-16 16:11:52 +08:00
Sijia Chen
f3005bbe37 fix the usage of a rc variable 2015-03-16 16:11:33 +08:00
sijchen
56fc515b02 Merge pull request #1851 from ruil2/vui-update
update vui parameters
2015-03-16 09:15:38 +08:00
ruil2
51a38ab17a update vui parameters 2015-03-13 19:08:08 +08:00
sijchen
e8db09fb56 Merge pull request #1848 from ruil2/vui-1.4
add VUI for base layer
2015-03-13 16:56:25 +08:00
ruil2
366b012d68 add VUI for base layer 2015-03-13 16:54:24 +08:00
huili2
26aeb3494c Merge pull request #1839 from dongzha/v.14
disable some HP tools in V1.4
2015-03-06 13:41:01 +08:00
dong zhang
0bc453423c disable some HP tools in V1.4 2015-03-06 11:22:39 +08:00
sijchen
3a75956fb2 Merge pull request #1838 from sijchen/upd_doc
update RELEASES file
2015-03-05 17:25:12 +08:00
Sijia Chen
d086f28a30 re-order the items in RELEASES 2015-03-05 17:10:17 +08:00
sijchen
18b202df0a Merge pull request #1837 from mstorsjo/initialize-func-pointers
Set pfMeCost to NULL when it isn't initialized
2015-03-05 17:05:07 +08:00
Sijia Chen
46de229fee update RELEASES file 2015-03-05 16:41:48 +08:00
Martin Storsjö
0ef69e55e2 Set pfMeCost to NULL when it isn't initialized
This avoids using uninitialized data in the check for bSatdInMdFlag.
2015-03-05 10:29:40 +02:00
ruil2
5921e5e7d3 Merge pull request #1836 from sijchen/imp_ut4
[UT] add more condition to improve the coverage of DecoderCrashTest
2015-03-05 15:47:24 +08:00
Sijia Chen
2c44dbae5c [UT] add more condition to improve the coverage of DecoderCrashTest
https://rbcommons.com/s/OpenH264/r/1132/
2015-03-05 13:22:48 +08:00
huili2
4048b9791a Merge pull request #1834 from sijchen/check_param
complete parameter checking related to loop-filter-idc
2015-03-05 09:39:46 +08:00
huili2
3022d4f655 Merge pull request #1832 from sijchen/imp_mc
[Encoder] replace conditional judgements with faster operations
2015-03-05 09:39:31 +08:00
sijchen
b304687197 Merge pull request #1833 from huili2/parseonly_au_incomplete_input_final
allow slice-level data come in for parse only
2015-03-05 09:24:30 +08:00
huili2
06b8e1abb7 allow slice-level data come in for parse only 2015-03-04 00:57:43 -08:00
dongzha
5b12578960 Merge pull request #1829 from syureyi/wp_p
Decoder WP support
2015-03-04 14:58:40 +08:00
zhuiling
9ef0c74fdd Decoder WP suppor
missed some part

fix clip value

update according to wayne's suggestion
2015-03-04 09:49:32 +08:00
Sijia Chen
94d1976a4e complete parameter checking related to loop-filter-idc 2015-03-03 18:31:37 +08:00
sijchen
5a1aedb622 Merge pull request #1827 from dongzha/cleanlog
modify decoder log
2015-03-03 11:01:46 +08:00
dong zhang
153dd0d3f5 format the files 2015-03-03 09:14:27 +08:00
Sijia Chen
63926a3d10 put a flag calculation in higher-level to save calculation in MB level 2015-03-02 17:36:55 +08:00
Sijia Chen
303bf77e42 replace conditional judgements with function pointer for acceleration 2015-03-02 17:11:11 +08:00
dong zhang
d28970d625 modify decoder log 2015-03-02 16:55:37 +08:00
huili2
2da0ce6451 Merge pull request #1826 from HaiboZhu/Add_Length_Input_Support
Add Bs Lenght File Input in Console
2015-03-02 14:05:00 +08:00
Haibo Zhu
afbb499c77 Add Bs Lenght File Input in Console 2015-03-01 18:22:40 -08:00
sijchen
7c9597c36d Merge pull request #1825 from ethanhugg/gmpapi-version-38
Change gmp-api version to Firefox38
2015-03-02 09:40:33 +08:00
zhilwang
bf3cc1ed63 Merge pull request #1823 from mstorsjo/downsample-min
Don't downsample to anything smaller than 4x4 pixels
2015-03-01 16:45:03 -08:00
Ethan Hugg
cea83438bf Change gmp-api version to Firefox38 2015-02-28 08:50:23 -08:00
Martin Storsjö
e8cdbd2ea7 Don't downsample to anything smaller than 4x4 pixels
This makes for a chroma plane of 2x2. The SIMD versionf of generic
downscalers assume that the width and height is at least 2, since
it does an unconditional loop for the body of the image, and a
separate step for the last pixel and last row. The SIMD versions
assume that (width-1) and (height-1) are larger than zero.

This fixes spurious crashes in EncodeDecodeTestAPI.SetOptionEncParamExt.
2015-02-28 14:58:53 +02:00
Ethan Hugg
67664f4dc0 Merge pull request #1821 from mstorsjo/remove-srand
Remove a stray srand
2015-02-27 11:16:41 -08:00
Martin Storsjö
c301db696e Remove a stray srand
The individual tests shouldn't reseed the random number generator
(other than for local debugging).

Hardcoding a specific random seed here leads to this test (and
all subsequent tests) not testing things randomly as intended, but
always testing the same parameters.
2015-02-27 12:06:44 +02:00
sijchen
2294b786cf Merge pull request #1774 from huili2/dec_flowchart_ec
modify decoder flowchart for non vcl AU check
2015-02-27 17:44:03 +08:00
Ethan Hugg
9ea4d5bd73 Merge pull request #1816 from mstorsjo/downscale-min-limit
Avoid trying to downscale layers to dimensions below 2
2015-02-23 13:53:58 -08:00
Ethan Hugg
497b38e341 Merge pull request #1815 from mstorsjo/test-param-strings
Store a const char* instead of a std::string in gtest parameter arrays
2015-02-23 13:52:19 -08:00
Martin Storsjö
861f54887d Avoid trying to downscale layers to dimensions below 2
When calculating what resolution to actually downscale to,
it can end up smaller than what the caller set. When scaling
down to resolutions close to the limit of allowed values,
this can end up setting values lower than the limit.

Previously, e.g. a downscale from 2266x8 to 566x2 will end
up as 566x1 after this calculation. When scaling to a
566x1, the chroma plane gets a height of 0, which doesn't
make sense, and which breaks e.g. the SSE2 scaler. Therefore,
make sure none of the dimensions end up set below 2.
2015-02-19 14:53:02 +02:00
Martin Storsjö
7208ed14b1 Store a const char* instead of a std::string in gtest parameter arrays
This avoids valgrind warnings about using unintialized data.
2015-02-19 14:52:11 +02:00
ruil2
e29ceca392 Merge pull request #1813 from sijchen/savc61
[Encoder] complete logic of simulcastavc with sps_pps_listing
2015-02-13 16:31:18 +08:00
Sijia Chen
15723e1204 add comments for write para set functions 2015-02-13 15:48:17 +08:00
HaiboZhu
1641ce9ee5 Merge pull request #1812 from huili2/cropping_error
return error for cropping data error
2015-02-12 11:27:48 +08:00
Sijia Chen
f9080ac090 complete logic of simulcastavc with sps_pps_listing 2015-02-11 17:31:17 +08:00
huili2
a73c1e6814 Merge pull request #1810 from dongzha/addUTLargeSize
add a UT for large picture
2015-02-11 17:28:08 +08:00
dong zhang
7d6d86b63a add a UT for large picture 2015-02-11 16:31:00 +08:00
huili2
4e9e5f5c36 Merge pull request #1794 from syureyi/monochroma
to support monochroma
2015-02-11 16:10:07 +08:00
huili2
5683393f38 return error for cropping data error 2015-02-10 22:31:24 -08:00
ruil2
ab3b55ae9c Merge pull request #1809 from sijchen/savc51
[Encoder] fix a nal generation for simulcast avc
2015-02-11 14:08:08 +08:00
Sijia Chen
943981abc4 fix a nal generation for simulcast avc and add nal-type check for simulcast avc UT 2015-02-09 13:50:31 +08:00
sijchen
bea361a1f0 Merge pull request #1805 from syureyi/fix_android_demo
Maintain android demo of encoder, fix a typo error
2015-02-09 11:05:17 +08:00
Ethan Hugg
9391c1586d Merge pull request #1808 from mstorsjo/update-readme
Update the readme about android 64 bit support
2015-02-08 11:21:23 -08:00
Martin Storsjö
58d9efb582 Update the readme about android 64 bit support 2015-02-08 21:17:29 +02:00
sijchen
9008b15d94 Merge pull request #1799 from mstorsjo/copy-spatial-downsample
Allow forcing copying in downscale
2015-02-06 14:22:18 +08:00
ruil2
8fc2af760f Merge pull request #1804 from sijchen/fix_over3
[Encoder] fix potential overflow under large bit rate
2015-02-06 14:22:01 +08:00
ruil2
296ab4d490 Merge pull request #1802 from sijchen/savc50
[Encoder] fix for in-middle changing simulcast avc setting
2015-02-06 14:21:47 +08:00
Sijia Chen
431bcee310 1, update the max-nal-size setting in UT and param check since we are using a larger input check
2, fix potential overflow (will change bs but little impact on bs)
2015-02-06 13:24:20 +08:00
ruil2
7d055cae94 Merge pull request #1786 from sijchen/fix_over
improve error logging in UT
2015-02-06 12:17:56 +08:00
ruil2
8246225eed Merge pull request #1791 from sijchen/fix_nal1
[Encoder] add a para check for max_nal_size
2015-02-06 12:17:40 +08:00
sijchen
3f19534dd6 Merge pull request #1790 from mstorsjo/simplify-vcproj
Remove the intermediate SW folder in the decoder vcproj files
2015-02-06 09:49:49 +08:00
Martin Storsjö
0a2cd1e59a Allow forcing copying in downscale
Normally, the DownsamplePadding skips scaling if the target
size is the same as the source size, assuming that the caller
will use the source data pointer in that case. This is true
for the base layer (the first call to DownsamplePadding in
SingleLayerPreprocess), but when downsampling the other layers,
there is no special handling for the case when the target
is the same size as the source.

Previously, the encoding of such spatial layers will use
completely uninitialized data, encoding complete garbage.

Instead force DownsamplePadding to make a copy if no scaling
is required, for the dependency layers. The base layer still
avoids a copy unless scaling of that layer is required.

Whether it actually makes sense to have lower spatial layers
the same size as the original one is a different question
though - currently the code allows it, and
EncodeDecodeTestAPI.SetOptionEncParamExt will try to use it.
2015-02-05 13:10:39 +02:00
Sijia Chen
bc1b28b5dd fix for in-middle changing simulcast avc setting 2015-02-05 16:34:28 +08:00
sijchen
09518da545 Merge pull request #1795 from mstorsjo/avoid-variable-shadowing
Avoid declaring a new variable shadowing an existing one in the same function
2015-02-04 17:57:38 +08:00
Martin Storsjö
6c1aa29431 Avoid declaring a new variable shadowing an existing one in the same function
All the following loops below assume that int iIdx already is declared.
2015-02-04 11:25:09 +02:00
sijchen
dc067286b3 Merge pull request #1792 from dongzha/AddUTMaxNalLen
add UT for set MaxNalUnitLen
2015-02-04 15:56:51 +08:00
zhuiling
0a8a4f2284 to support monochroma
add mbtype judge logic
2015-02-04 15:00:54 +08:00
dong zhang
d3b2be5ec2 add UT for set MaxNalUnitLen
ignore the cases: 2 MBs in one picture, and the multithreads case, enable them when code is ready
2015-02-04 14:39:11 +08:00
HaiboZhu
442230a91d Merge pull request #1789 from huili2/bugfix_checkspsactive
bug fix for multi-layer active sps check
2015-02-04 09:13:18 +08:00
Sijia Chen
2211324e2b add a para check for max_nal_size 2015-02-03 15:14:36 +08:00
Martin Storsjö
87b73257cb Remove the intermediate SW folder in the decoder vcproj files
This makes the folder structure in these project files match all
the other ones.
2015-02-03 09:09:58 +02:00
sijchen
fba745f04e Merge pull request #1788 from mstorsjo/share-wels-const
Share parts of wels_const.h
2015-02-03 15:06:44 +08:00
huili2
1734133012 bug fix for multi-layer active sps check 2015-02-02 22:31:50 -08:00
Martin Storsjö
e4a278620b Remove dependencies on the decoder internals in unit test for the common library 2015-02-02 12:44:04 +02:00
Martin Storsjö
4f237b51ef Move parts of wels_const.h into a shared header 2015-02-02 12:41:11 +02:00
Martin Storsjö
713beb7df7 Fix typos in header include guards 2015-02-02 12:41:11 +02:00
sijchen
5fdd01ec0c Merge pull request #1787 from mstorsjo/remove-stray-semicolon
Remove accidental double semicolons
2015-02-02 18:15:02 +08:00
sijchen
e7a7a35611 Merge pull request #1779 from mstorsjo/share-memalign
Move the memory allocation/deallocation routines to the common library
2015-02-02 18:14:55 +08:00
Martin Storsjö
a3063531c4 Remove accidental double semicolons 2015-02-02 09:20:35 +02:00
zhuiling
ee515e8b35 fix it 2015-02-02 10:17:19 +08:00
zhilwang
fb5c60b6fc Merge pull request #1782 from mstorsjo/avoid-yasm-warnings
Move DEFAULT REL into the x86_64 cases
2015-02-01 17:38:59 -08:00
zhilwang
7629543e3e Merge pull request #1784 from mstorsjo/force-arm-mode
Force armv7/neon within the arm assembly header file
2015-02-01 17:36:36 -08:00
sijchen
79b38f55ff Merge pull request #1783 from mstorsjo/simplify-includes
Simplify include paths for unittest sub libraries
2015-02-02 09:30:27 +08:00
sijchen
16ca41cada Merge pull request #1780 from mstorsjo/speedup-tests
Set m_iPicResSize in PrepareOneSrcFrame
2015-02-02 09:29:50 +08:00
sijchen
0f1737e035 Merge pull request #1778 from mstorsjo/fix-version-generation
Don't overwrite the git-tracked version.h
2015-02-02 09:23:05 +08:00
Martin Storsjö
5a78735802 Force armv7/neon within the arm assembly header file
This avoids having to add extra compiler flags to be able to build
them.
2015-02-02 00:53:39 +02:00
Martin Storsjö
8d539600bb Simplify unittest include paths
Move the "test" directory to CODEC_UNITTEST_INCLUDES instead of
duplicating it in every definition.
2015-02-02 00:51:02 +02:00
Martin Storsjö
84b3216d7c Remove redundant unittest include paths
The local directory doesn't need to be added to the include path.
2015-02-02 00:50:54 +02:00
Martin Storsjö
3243a78959 Move DEFAULT REL into the x86_64 cases
This fixes warnings when building for x86_32 using yasm, which says
the "DEFAULT REL" is ignored for non-64-bit targets.
2015-02-02 00:49:37 +02:00
Ethan Hugg
195df08bb9 Merge pull request #1746 from kinetiknz/gmp-fixes
Various fixes for the GeckoMediaPlugin wrapper
2015-01-30 09:25:35 -08:00
Martin Storsjö
4394d22b70 Set m_iPicResSize in PrepareOneSrcFrame
If the calling test hasn't set m_iPicResSize, it is set to the
maximum frame size, which takes much longer to initialize than the
current actual frame size.

This reduces the runtime of EncoderInterfaceTest.SkipFrameCheck
in valgrind from 229 seconds to 8 seconds, and the total runtime
of all the test cases in EncoderInterfaceTest from 405 seconds
to 89 seconds.
2015-01-30 16:02:40 +02:00
Martin Storsjö
2356eb1ff6 Move the memory allocation/deallocation routines to the common library
They are still used slightly differently in the encoder and decoder;
the decoder uses plain functions while the encoder uses one object
keeping track of the number of allocated bytes, and keeping track
of the requested alignment.
2015-01-30 11:30:59 +02:00
Martin Storsjö
078d96bef7 Don't overwrite the git-tracked version.h
When generating a new version of the header, that includes the
actual git hash, don't overwrite the file that is tracked by git.
Instead create a new file, and include this only if the build system
indicates that it exists (by setting a define). This allows the
untouched source tree to be built from within an IDE even if make
has not been run.

This reduces the hassle with a file that needs to be ignored in the
git configuration.

The downside is that the generated file isn't used if building
from within an IDE, if the header has been updated by calling make
before (since the IDE configuration doesn't know whether the user
actually has run make). Since users of the IDE might not build via
make in the command line at all (in the same source checkout at least),
this should not be an issue in practice. The previous way things worked,
the version hash (generated by make) when used in an IDE could actually
be outdated and misleading.
2015-01-30 10:55:16 +02:00
Martin Storsjö
869870e670 Rename the decoder WelsMalloc to WelsMallocz
This function actually zero-initializes the allocated memory, thus
make this clear in the function name.

This makes the function name match the same behaviour in the encoder.
2015-01-30 10:37:48 +02:00
Sijia Chen
3c085aec79 improve error logging in UT 2015-01-30 15:43:20 +08:00
sijchen
9b442b3d44 Merge pull request #1776 from mstorsjo/mc-test-fix
Avoid writing outside of the target rect in MCHalfPelFilterAnchor
2015-01-30 10:38:40 +08:00
sijchen
e48cf9f471 Merge pull request #1769 from ruil2/status
add screen content type setting
2015-01-30 10:25:19 +08:00
sijchen
28469ab3dc Merge pull request #1775 from sijchen/upd_ver
update the version info to sync with recent change of API
2015-01-30 10:24:56 +08:00
Martin Storsjö
76b0f8c17a Avoid writing outside of the target rect in MCHalfPelFilterAnchor
This simplifies comparison between the output of MCHalfPelFilterAnchor
and the actual MC function implementations.
2015-01-29 08:51:02 +02:00
Matthew Gregan
02365371e8 Initialize SVideoProperty struct completely. 2015-01-29 19:01:47 +13:00
Matthew Gregan
9ea6603071 Pass AVCC extra data to the decoder (in AnnexB format) in InitDecode. 2015-01-29 18:58:44 +13:00
Matthew Gregan
30d7352d03 Call InputExhausted when input has not produced a frame, call Error when
the decoder did not produce valid output, call DrainComplete in Drain
and FlushComplete in Flush.  Without these, the caller of the GMP may
end up waiting forever on a requested operation to complete.
2015-01-29 18:58:44 +13:00
Sijia Chen
a4f09f4d76 update the version info to sync with recent change of API 2015-01-29 11:14:08 +08:00
dongzha
4f4adcec49 Merge pull request #1772 from mstorsjo/mc-unify
Move the MC implementation to the common library
2015-01-29 09:28:57 +08:00
dongzha
59b3b428a2 Merge pull request #1768 from mstorsjo/msvc-ignore
Add a .gitignore file for test/build/win32
2015-01-29 09:28:02 +08:00
huili2
8a84d14617 Merge pull request #1770 from mstorsjo/remove-moved-file
Remove leftover references to expand_pic in the welsdec xcode project
2015-01-29 09:22:28 +08:00
huili2
7ab0386436 Merge pull request #1771 from mstorsjo/mc-enc-ut
Improve and fix a few details in the encoder MC test
2015-01-29 09:18:46 +08:00
Martin Storsjö
605f2fb858 Remove the now unnecessary mc_test_common.h 2015-01-28 23:59:41 +02:00
Martin Storsjö
f03edd79c2 Merge all MC unit tests into one file
Since both encoder and decoder use the same MC implementation now,
one set of tests is enough.
2015-01-28 23:59:37 +02:00
Martin Storsjö
9a0663620a Move the MC routines to the common library
Use the decoder versions of the functions (which are capable
of handling widths 4/8/16 for luma, not only 16 as in the
encoder). By using the more generic versions, there may be a small
performance loss since the functions need to check the width
in every call. Actual measurements show that the actual change is
very small (and the shared routines turn out to actually be faster
than the existing ones in ARM NEON setups).
2015-01-28 15:32:46 +02:00
Martin Storsjö
1a7d0ab831 Hook up McChromaWidthEq8_ssse3 into use in the decoder as well 2015-01-28 15:20:43 +02:00
Martin Storsjö
909a508749 Use the right stride in a memset in the EncMcHalfpel test 2015-01-28 15:19:19 +02:00
Martin Storsjö
5d67df4adb Remove leftover references to expand_pic in the welsdec xcode project
These files are part of the common library (and the common xcode
project) now instead.
2015-01-28 15:13:50 +02:00
Martin Storsjö
151dfe04d5 Extend the tested area in the encoder MC test 2015-01-28 15:11:17 +02:00
Martin Storsjö
9a9fc4c489 Change pfSampleAveraging to be a single function with internal width handling
This makes it match the behaviour of pMcLumaFunc and pMcChromaFunc.
2015-01-28 13:59:58 +02:00
Martin Storsjö
1127aa7761 Simplify the MC unit tests now that the naming is made consistent 2015-01-28 13:59:58 +02:00
Martin Storsjö
8b6bf0499f Rename the encoder MC chroma/luma functions to match the naming in the decoder 2015-01-28 13:59:58 +02:00
Martin Storsjö
bb21b62cbd Simplify the MC unit tests now that the luma functions have a similar signature 2015-01-28 13:59:58 +02:00
Martin Storsjö
1cf68cad13 Move the qpel function table into the luma function itself
This unifies the luma MC interface to match the decoder side.
2015-01-28 13:59:58 +02:00
sijchen
a8262dd9e6 Merge pull request #1767 from mstorsjo/fix-msvc-warnings
Use float literals instead of double literals when setting float values
2015-01-28 16:48:23 +08:00
sijchen
c245cd2d68 Merge pull request #1766 from mstorsjo/make-clean
Remove more generated files in "make clean"
2015-01-28 16:34:53 +08:00
ruil2
095bb83e77 add screen content type setting 2015-01-28 16:25:51 +08:00
huili2
b6e28495dd modify decoder flowchart for non vcl AU check 2015-01-28 00:22:48 -08:00
Martin Storsjö
1be2cd14c0 Add a .gitignore file for test/build/win32
This file is copied from codec/build/win32.
2015-01-28 09:42:10 +02:00
sijchen
e4260f6e97 Merge pull request #1765 from mstorsjo/mccopy-neon
Handle width==2 for the neon version of McCopy
2015-01-28 15:40:02 +08:00
Martin Storsjö
b444f8d9d0 Remove more generated files in "make clean"
Make sure to remove *.exe also, if cross-building from unix to
windows (and running "make clean" without specifying mingw as
target OS).
2015-01-28 09:39:55 +02:00
Martin Storsjö
853d2922db Use float literals instead of double literals when setting float values
This fixes warnings with MSVC 2008.
2015-01-28 09:19:09 +02:00
Martin Storsjö
7354a8cbae Handle width==2 for the neon version of McCopy
Fall back on the C version of the algorithm here, just as in
McCopy_sse2.

This fixes 2 of the McCopy tests on arm/aarch64.
2015-01-28 09:01:00 +02:00
ruil2
c4c73ee5d6 Merge pull request #1764 from sijchen/fix_br3
[Encoder] fix potential overflow and save unnecessary calculation
2015-01-28 11:45:47 +08:00
ruil2
051a16e02e Merge pull request #1762 from sijchen/fix_sta
[Encoder] fix statistics: updating should be independent with log interval
2015-01-28 10:51:51 +08:00
Sijia Chen
5752888c81 1, fix a potential overflow
2,    remove some unnecessary multiplier and add input check of spatial BR
2015-01-28 10:51:27 +08:00
sijchen
a00dd56f1c Merge pull request #1763 from mstorsjo/mc-ut-simplify
Remove the forceC parameter from DEF_MCCOPYTEST
2015-01-28 10:13:46 +08:00
Martin Storsjö
e5c2f333be Remove the forceC parameter from DEF_MCCOPYTEST
Even if there actually is no SIMD optimized version of the
width==2 cases, luma function for SIMD still needs to handle
it by calling McCopyWidthEq2_c for these cases.

This simplifies the UT code a little, and makes sure that
those codepaths are tested properly.
2015-01-27 12:11:38 +02:00
sijchen
d9ee702031 Merge pull request #1759 from mstorsjo/enc-mc-ut
Add unit tests for encoder MC
2015-01-27 16:51:42 +08:00
Martin Storsjö
23b20fb14c Simplify code in HorFilterInput16bit in MC
This avoids a gcc optimizer bug (which seems to be present in some
gcc 4.6 and 4.7 versions) at the -O3 level.
2015-01-27 09:41:00 +02:00
Martin Storsjö
279e14b34e Add const to some inline functions within MC 2015-01-27 09:41:00 +02:00
Martin Storsjö
10e2f90b7e Bundle MC tests for all motion vectors in one single test
This speeds up the compile time from 21.3 to 2.6 seconds
for the MC test files.

This makes it slightly harder to see exactly which test
failed on a quick glance, but it makes the overall structure of
the unit test output more manageable and readable, by reducing
the number of tests from 1300 to 430.
2015-01-27 09:41:00 +02:00
Martin Storsjö
ca97f78ae8 Add unit tests for special cased MC functions in the encoder 2015-01-27 09:41:00 +02:00
Martin Storsjö
8084a2c797 Add unit tests for encoder MC 2015-01-27 09:41:00 +02:00
Martin Storsjö
4df4c1d757 Prepare the shared MC test code for adding an encoder MC test 2015-01-27 09:41:00 +02:00
Martin Storsjö
49af2b592d Split DecUT_MotionCompensation to a shareable header
This allows adding a version of the same test for the encoder.
2015-01-27 09:40:59 +02:00
Martin Storsjö
cf3e7b5dec Make local functions and tables in DecUT_MotionCompensation static 2015-01-27 09:40:59 +02:00
Martin Storsjö
478af8f00c Unify the pfChromaMc function signature with the decoder version
Instead of passing a struct with x/y, pass them as two separate
parameters.
2015-01-27 09:40:59 +02:00
Martin Storsjö
8ecb8b4200 Remove unused includes in DecUT_MotionCompensation 2015-01-27 09:40:59 +02:00
Martin Storsjö
420a81afe4 Unify the order of iX and iY in DecUT_MotionCompensation
They are in the order iX, iY in the rest of the file.
2015-01-27 09:40:59 +02:00
Martin Storsjö
9fc9acfd14 Avoid a duplicate local typedef 2015-01-27 09:40:59 +02:00
Martin Storsjö
7d9fc35235 Unify the encoder MC init function with the decoder
This simplifies the code a little, by passing a pointer to the sub-struct
SMcFunc instead of to the full SWelsFuncPtrList, which isn't necessary.
2015-01-27 09:40:59 +02:00
ruil2
5b27407993 Merge pull request #1757 from sijchen/sps_list4
[Encoder] add input checking and fix a bs length under new strategy
2015-01-27 10:43:20 +08:00
ruil2
1b48e6c88c Merge pull request #1756 from sijchen/savc4
[Encoder] Implementation of bSimulcastAVC and UT
2015-01-27 10:42:50 +08:00
Sijia Chen
d557578be3 fix statistics: updating should be independent with log interval 2015-01-27 10:12:51 +08:00
sijchen
f404ce2e56 Merge pull request #1758 from mstorsjo/add-missed-test
Hook up the DecUT_ParseSyntax test
2015-01-27 08:47:40 +08:00
Martin Storsjö
e64e2bb620 Avoid warnings in DecUT_ParseSyntax 2015-01-26 23:54:34 +02:00
Martin Storsjö
4192165ec9 Add DecUT_ParseSyntax to the build system
This test seems to have been added to the git tree in commit
9a602cac (which does much more than what the commit message
tells), and finally merged into git master in 2c99f581.
2015-01-26 15:59:43 +02:00
Martin Storsjö
faf62464a8 Make DecUT_ParseSyntax.cpp actually build and run successfully 2015-01-26 15:59:43 +02:00
Martin Storsjö
4ca8ad2612 Initialize pCodecInstance in the constructor
This avoids using uninitialized memory if SetCodecInstance
isn't ever called (as in DecUT_ParseSyntax).
2015-01-26 13:16:09 +02:00
Sijia Chen
deccd1eadb fix profileidc 2015-01-26 16:36:42 +08:00
ruil2
1ae06eab91 Merge pull request #1755 from sijchen/fix_lvl
[Encoder] fix level-idc related input checking and a statistics calculation
2015-01-26 15:58:03 +08:00
Sijia Chen
e2fb48d404 change the trace to warning 2015-01-26 15:42:09 +08:00
Sijia Chen
8d5ec6759d add support of SimulcastAVC functions 2015-01-26 15:25:09 +08:00
sijchen
89159ab25f Merge pull request #1754 from ruil2/status
use the new no delay decoderframe interface instead of old one
2015-01-26 15:23:49 +08:00
Sijia Chen
f13624316e fix level-idc related input checking and a statistics calculation
will change bs but tested there is little impact on RD
being reviewed at: https://rbcommons.com/s/OpenH264/r/1084/
2015-01-26 15:20:58 +08:00
Sijia Chen
45e3424364 add input checking and fix a bs length under new strategy 2015-01-26 11:12:24 +08:00
ruil2
4b52d99d97 use the new no delay decoderframe interface instead of old one 2015-01-26 09:56:11 +08:00
dongzha
de68ec6f45 Merge pull request #1751 from ruil2/status
return decoder error
2015-01-26 09:31:48 +08:00
dongzha
51f1ea3839 Merge pull request #1753 from mstorsjo/test-cpu-flags
Add checks for cpu features in tests
2015-01-26 09:29:47 +08:00
Martin Storsjö
acafbb442d Add checks for cpu features in tests
This allows running the tests on devices that don't have
all the SIMD instruction sets.
2015-01-24 22:47:23 +02:00
ruil2
6afdf36ecc return decoder error 2015-01-23 15:48:13 +08:00
sijchen
7f967f6fc4 Merge pull request #1750 from syureyi/crqp
to support different chroma qp
2015-01-23 13:30:21 +08:00
sijchen
dfd24a987d Merge pull request #1748 from dongzha/fixcrash
fix crash in SGE test
2015-01-23 09:45:54 +08:00
zhuiling
a45c661525 to support different chroma qp
fix travis ci error
2015-01-23 09:06:09 +08:00
dong zhang
6dcaf2f890 fix crash in SGE test 2015-01-22 09:10:28 +08:00
ruil2
e7fff10d91 Merge pull request #1745 from sijchen/fix_ut
[UT] fix a random failure of UT
2015-01-21 17:31:34 +08:00
ruil2
17030193e6 Merge pull request #1742 from sijchen/fix_max_br
[Encoder] improve the para checking of max-br
2015-01-21 17:31:24 +08:00
Sijia Chen
d74234d975 enhance max-br checking logic 2015-01-21 16:54:43 +08:00
Sijia Chen
6664593ef7 Merge branch 'master' of https://github.com/cisco/openh264 into fix_max_br 2015-01-21 16:35:31 +08:00
sijchen
4b231c8fe6 Merge pull request #1744 from dongzha/modifydecoderlog
modify decoder console log level to WELS_LOG_WARNING
2015-01-21 09:43:41 +08:00
ruil2
96b1183574 Merge pull request #1743 from sijchen/fix_test
[UT] add a default param function for EncodeDecoderAPI test
2015-01-21 09:19:21 +08:00
Sijia Chen
5b10c1ff8d fix random failure of UT under randon seed 1421732719 2015-01-20 15:47:05 +08:00
dong zhang
bd7fabd892 modify decoder console log level to WELS_LOG_WARNING
change the postion of setting EC method
2015-01-20 13:18:33 +08:00
Sijia Chen
8cc53b0231 astyle an unformatted file 2015-01-20 10:50:44 +08:00
Sijia Chen
489d121549 add a default param function for EncodeDecoderAPI test 2015-01-20 10:49:25 +08:00
Sijia Chen
ee40ba6392 improve the para checking of max-br 2015-01-20 10:31:13 +08:00
sijchen
8bef6bc942 Merge pull request #1738 from huili2/init_EC_modify
modify EC init position
2015-01-19 16:36:29 +08:00
sijchen
2df0185252 Merge pull request #1740 from mstorsjo/fix-tests
Fix issues in the ParameterSetStrategy tests
2015-01-19 16:36:07 +08:00
Martin Storsjö
d6f7a07b14 Undefine a define for writing debug files 2015-01-19 10:06:30 +02:00
Martin Storsjö
c1aa2a1edb Use WelsClip3 instead of WELS_CLIP3 for random values
Since WELS_CLIP3 is a macro, using it will cause the arguments
to be evalated multiple times, which means that the clip will
not work as intended. If using a rand() argument, always use
WelsClip3 instead, which is an inline function.
2015-01-19 10:02:21 +02:00
Martin Storsjö
fcae7fd300 Compare macro block widths instead of picture widths
Since cropping is disabled (prepareParam does
memset (pParam, 0, sizeof (SEncParamExt)); which clears the
cropping flag), we need to make sure that the number of
macroblocks differ, not only the number of pixels.
2015-01-19 10:01:12 +02:00
Martin Storsjö
58f1fef520 Fix a comparison in ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING3
Previously, this test picked a width at random until it found
a width that had been used before, meaning that all tests were
made with the same single width.
2015-01-19 09:58:25 +02:00
huili2
01fd220ef9 Merge pull request #1739 from sijchen/sps_list3
[Encoder] rename the SpsPpsStrategy to enum
2015-01-19 13:31:51 +08:00
sijchen
eb7b149fcc Merge pull request #1736 from mstorsjo/werror-tests
Build using -Werror in travis unit tests
2015-01-19 10:54:11 +08:00
sijchen
4930111ad3 Merge pull request #1734 from mstorsjo/fix-unused-variable-warning
Avoid a warning about a variable set but not used
2015-01-19 10:51:33 +08:00
Sijia Chen
d9502aa71d rename the strategy to enum 2015-01-19 10:49:38 +08:00
huili2
50ce93e31c modify EC init position 2015-01-18 18:07:27 -08:00
dongzha
7d1d2d658f Merge pull request #1735 from mstorsjo/msvc-test-warnings
Fix build warnings with MSVC
2015-01-19 09:37:39 +08:00
Martin Storsjö
5702e7c0ca Build using -Werror in travis unit tests
This makes all compiler warnings to be treated as errors.

This allows catching warnings that are introduced, that may only be
visible with some compilers.

This option is only added within travis unit tests, not during normal
builds, so there is no risk of unnecessarily breaking builds on
new/untested systems.
2015-01-16 14:02:01 +02:00
Martin Storsjö
c69d628a82 Avoid warnings about an unused variable in debug mode 2015-01-16 14:02:01 +02:00
Martin Storsjö
4df6f9420f Check for an already defined nullptr macro
In addition to the existing compiler version/feature checks, also
check if there is such a macro.

This avoids warnings when building with Xcode 6.0.
2015-01-16 14:02:01 +02:00
Martin Storsjö
3cf2be2590 Don't override the externally set CFLAGS variable in debug mode
This is similar to how it is done in release mode already.

The fact that this behaviour differed between release and debug
can be traced back to commit cf92e8d6.
2015-01-16 14:02:01 +02:00
Martin Storsjö
9e00bf89aa Use VerifyVersionInfo instead of GetVersionEx
The GetVersionEx function has been deprecated since Windows 8.1.
VerifyVersionInfo exists at least since Windows 2000.

This fixes warnings about use of deprecated functions in MSVC.
2015-01-16 13:38:21 +02:00
Martin Storsjö
4f33b38ac1 Move a conversion from size_t to int into one single place within BaseDecoderTest.cpp 2015-01-16 13:38:07 +02:00
Martin Storsjö
b83b19254d Add a cast when converting from uint64_t to int
This silences warnings with MSVC.
2015-01-16 13:38:07 +02:00
Martin Storsjö
96384bd578 Add casts when converting from size_t or std::streamsize to int 2015-01-16 13:38:07 +02:00
Martin Storsjö
af938a640f Add casts when converting from float to int 2015-01-16 13:38:07 +02:00
Martin Storsjö
ef82e18d74 Silence warnings about insecure CRT functions in the test suite
There is no problem in using the "insecure" CRT functions, as long as
they are used correctly - especially not within the test suite where
they are only are exposed to the test suite input data.

Within the library, these are used via the library internal wrappers
in codec/common/src/crt_util_safe_x.cpp, but we'd rather not use them
in the test suite - just use the normal standard C functions here.
2015-01-16 13:38:06 +02:00
Martin Storsjö
1646f86b37 Allow setting cflags specifically for the unit test suite 2015-01-16 13:38:06 +02:00
Martin Storsjö
a1b8ffc9df Use the right data type for a variable
There is little point in using an int32_t variable for something
that will only be used for passing in as a bool parameter to a
function.
2015-01-16 13:38:06 +02:00
Martin Storsjö
a852ac99ed Fix a cast to actually cast to the right type
The existing cast didn't make much sense. The expression itself is
already int, there's little point in casting it to int, especially
when assigning to a float.

This fixes warnings with MSVC.
2015-01-16 13:38:06 +02:00
Martin Storsjö
93cb617932 Add a comparison in ASSERT_TRUE
This makes sure the compared value actually is bool, not any other
type that can be used as condition.

This fixes warnings with MSVC.
2015-01-16 13:38:06 +02:00
Martin Storsjö
99925984b3 Consistently compare integers with integers and bools with bools
MSVC warns when comparing integers with booleans in with the gtest
assertion macros.
2015-01-16 13:37:15 +02:00
Martin Storsjö
cd55201600 Ignore armasm warnings about instructions that are deprecated in ARMv8
This disables armasm warning A4509, "This form of conditional
instruction is deprecated".

The conditional instructions (such as movcs, addcs, subscs)
have been deprecated in ARMv8, in favor of conditional branches.
This isn't something that we need to take immediate action about,
though, therefore silence the warning.
2015-01-16 13:36:35 +02:00
Martin Storsjö
a44643aeda Avoid a warning about a variable set but not used
The return values may be useful later, so instead of removing the
variable, just silence the warning.

This fixes a warning in builds with GCC.
2015-01-16 09:26:42 +02:00
ruil2
aea1017562 Merge pull request #1732 from sijchen/sps_list2
[Encoder] add new SpsPpsStrategy and UT
2015-01-16 10:53:45 +08:00
ruil2
9ba316caf4 Merge pull request #1731 from mstorsjo/warning-fixes
Fixes for some new compiler warnings
2015-01-16 09:00:46 +08:00
Martin Storsjö
d6b4b5365d Declare a float constant as float instead of as double
This avoids warnings about converting from double to float
in MSVC.
2015-01-15 12:38:42 +02:00
Martin Storsjö
75bbc286e1 Add explicit casts when converting from double to int32_t
This fixes build warnings with MSVC.
2015-01-15 12:38:39 +02:00
Martin Storsjö
c8972f1c32 Consistently use the right type for log prints
These fields were originally int64_t. Even though long long is
the same size as int64_t in all setups, some compilers treat
it as a different type than long long (in 64 bit environments,
int64_t is a long, not a long long, even if they are the same
size).

%"PRId64" is used for printing int64_t, while %lld is used
for printing long long.

This fixes build warnings with gcc.
2015-01-15 12:33:44 +02:00
Sijia Chen
98ed302990 add new SpsPpsStrategy and UT 2015-01-15 18:04:39 +08:00
sijchen
e9ec603fd7 Merge pull request #1727 from huili2/addUT_parseonly_frameincomplete
add UT for incomplete frame for parse only
2015-01-15 16:23:05 +08:00
sijchen
dbcbe180e6 Merge pull request #1729 from ruil2/rc_submit1
add rc function
2015-01-15 16:22:39 +08:00
dongzha
b603844126 Merge pull request #1730 from HaiboZhu/Debug_EC_off_Delay_mode_early_exit_process
Fix the bug that the pDec not set to NULL when early exit
2015-01-15 14:08:26 +08:00
ruil2
0250acc665 Merge pull request #1725 from ethanhugg/startcode2
gmp-openh264 should avoid writing outside the input frame buffer with start code.
2015-01-15 11:33:29 +08:00
ruil2
d7304bbaf4 Merge pull request #1728 from sijchen/fix_mbidx
[Encoder] expand the mb_idx range so as to support frame size > 32767
2015-01-15 11:33:15 +08:00
Haibo Zhu
264cf57616 Fix the bug that the pDec not set to NULL when early exit
Add more judgement for diff set EC mode under no-delay call
2015-01-14 19:22:34 -08:00
ruil2
5b5cc8434e add rc function 2015-01-15 11:14:05 +08:00
huili2
ea533e6405 add UT for incomplete frame for parse only 2015-01-14 18:00:33 -08:00
dongzha
993caea18c Merge pull request #1721 from huili2/DecodeFrameNodelay
add new API as DecodeFrameNoDelay for immediate decoding
2015-01-15 09:54:10 +08:00
dongzha
cb49f8ecbd Merge pull request #1718 from huili2/sps_avc_flag_remove
allow non-avc check when subset SPS exists
2015-01-15 09:53:15 +08:00
Ethan Hugg
fc6ea7e5a8 gmp-openh264 check buffer length before we overwrite with start code. 2015-01-14 15:28:55 -08:00
Ethan Hugg
9a55a8609e Merge pull request #1722 from sijchen/win_pdb2
add option for generating pdb in windows builds
2015-01-14 07:35:49 -08:00
Sijia Chen
560a33a373 fix to avoid link warning 2015-01-14 18:02:24 +08:00
Sijia Chen
c02d9b0865 expand the mb_idx range so as to support frame size > 32767 2015-01-14 17:59:16 +08:00
Sijia Chen
4f826f2e94 add option for generating pdb in windows builds 2015-01-14 16:31:48 +08:00
ruil2
a39c46601d Merge pull request #1720 from mstorsjo/remove-unused-format-args
Log all provided parameters in WelsEncoderApplyLTR
2015-01-14 16:19:43 +08:00
Martin Storsjö
f594d96a51 Log all provided parameters in WelsEncoderApplyLTR
This fixes warnings with gcc and clang.
2015-01-14 09:06:36 +02:00
ruil2
34661f1d86 Merge pull request #1715 from huili2/parseonly_flowchart_modify
modify parse only flowchart to use DecodeFrameConstruction()
2015-01-13 16:11:02 +08:00
ruil2
cdd072e1d4 Merge pull request #1714 from sijchen/fix_ref4
[Encoder] enhance param checking with num-ref and related logging
2015-01-13 16:10:20 +08:00
ruil2
47dd4de412 Merge pull request #1717 from sijchen/fix_ltr1
[Encoder] fix for the valgrid warning of issue#1362
2015-01-13 15:30:53 +08:00
huili2
1518b5da58 allow non-avc check when subset SPS exists 2015-01-12 22:29:18 -08:00
huili2
8e35224134 modify parse only flowchart to use DecodeFrameConstruction() 2015-01-11 23:16:24 -08:00
Sijia Chen
ea06cbe06b enhance param checking with num-ref and related logging 2015-01-12 10:39:51 +08:00
ruil2
04cb9f3477 Merge pull request #1678 from sijchen/savc1
[Encoder] interface for simulcast avc
2015-01-12 09:23:17 +08:00
ruil2
958c60d041 Merge pull request #1713 from mstorsjo/valgrind
Avoid a spurious valgrind warning in DecoderIntraPredictionTest.WelsDecoderI16x16LumaPredPlane_sse2
2015-01-12 09:22:37 +08:00
Martin Storsjö
44bce08d60 Avoid a spurious valgrind warning in DecoderIntraPredictionTest.WelsDecoderI16x16LumaPredPlane_sse2
valgrind thinks xmm2 is uninitialized - in fact it is, but
its value here doesn't really matter. Instead set it to a known value
before using it in SUMW_HORIZON.
2015-01-10 13:25:00 +02:00
Sijia Chen
a4ae5e3747 add fix for the valgrid warning of issue#1362 2015-01-09 16:17:51 +08:00
Sijia Chen
76ef30dc82 refactor 2015-01-09 15:55:03 +08:00
dongzha
a5cb0ea22c Merge pull request #1711 from huili2/parseonly_noEC
disable EC for parseonly
2015-01-09 09:23:55 +08:00
huili2
900a908929 disable EC for parseonly 2015-01-08 00:16:01 -08:00
HaiboZhu
3a91abf28c Merge pull request #1710 from huili2/parseonly_framecomplete_error_prop
prevent error propagation for parse only when frame is not complete
2015-01-08 16:09:02 +08:00
huili2
e48585236e prevent error propagation for parse only when frame is not complete 2015-01-07 22:34:55 -08:00
Ethan Hugg
d92853c88e Merge pull request #1706 from mstorsjo/add-destdir-static
Add $(DESTDIR) for the install-static rule as well
2015-01-07 13:13:23 -08:00
Martin Storsjö
fb33b359d5 Add $(DESTDIR) for the install-static rule as well
The change for adding these were merged after the commit for
adding $(DESTDIR) was done.
2015-01-07 20:24:09 +02:00
Ethan Hugg
17a87e8081 Merge pull request #1704 from lu-zero/master
build: Support DESTDIR
2015-01-07 10:20:17 -08:00
Ethan Hugg
71123f29ef Merge pull request #1702 from mstorsjo/adjust-comment
Clarify the comment about ABI issues with WelsGetCodecVersion
2015-01-07 09:07:12 -08:00
Ethan Hugg
178a18b30e Merge pull request #1703 from mstorsjo/add-cast
Add a cast to silence GCC warnings about comparison between signed and unsigned
2015-01-07 09:05:42 -08:00
Luca Barbato
735172d387 build: Support DESTDIR
Distribution rely on that to properly package software.
2015-01-07 10:44:35 +01:00
Martin Storsjö
5c3c2a569c Add a cast to silence GCC warnings about comparison between signed and unsigned 2015-01-07 09:15:48 +02:00
Martin Storsjö
aa1ec23ecd Clarify the comment about ABI issues with WelsGetCodecVersion
The incompatibility between mingw and msvc is smaller than it seemed
at first; this turned out to only be a bug in older versions.
2015-01-07 09:15:34 +02:00
huili2
62c6a1e099 Merge pull request #1705 from HaiboZhu/Debug_Delay_mode_rawdata_update_error
Fix a bug when EC disable under delay mode
2015-01-07 15:12:11 +08:00
Haibo Zhu
207082e237 Fix a bug when EC disable under delay mode (buf point not update when early exit) 2015-01-06 17:48:58 -08:00
sijchen
68ff8468af Merge pull request #1691 from mstorsjo/pkgconfig-fixes
Improve pkg-config files for use with static libraries
2015-01-07 09:45:45 +08:00
ruil2
61cd77d487 Merge pull request #1701 from huili2/parseonly_framecomplete_bugfix
bug fix for parseonly for complete frame judge
2015-01-07 09:13:16 +08:00
huili2
e8b68d2460 bug fix for parseonly for complete frame judge: reset total_mb if correct. 2015-01-05 23:07:17 -08:00
huili2
ac08cc4b2f Merge pull request #1694 from zhilwang/asm-SetNoneZero
Add asm code for NoneZeroCount and refine related code
2015-01-06 13:37:56 +08:00
sijchen
9a89ee72b0 Merge pull request #1698 from ruil2/fix_param
fix bug when some parameters change dynamically
2015-01-06 09:37:48 +08:00
ruil2
c72d3ad51a Merge pull request #1697 from huili2/parseonly_frame_complete_return
output error when frame incomplete for parse only usage
2015-01-05 17:06:56 +08:00
ruil2
ce14a0e4f9 fix bug when some parameters change dynamically 2015-01-05 17:01:35 +08:00
huili2
3244f11cfe Merge pull request #1696 from mstorsjo/add-header-const
Declare the g_strCodecVer variable as const
2015-01-05 09:42:43 +08:00
huili2
b719c3b0d5 output error when frame incomplete for parse only usage 2015-01-04 17:13:57 -08:00
Martin Storsjö
3422d3b976 Declare the g_strCodecVer variable as const
Previously, the variable itself wasn't const (which meant that
it could be set to point to another const string instead).

By declaring it as const, gcc doesn't warn about it being unused,
and we can get rid of a workaround.
2015-01-04 21:00:23 +02:00
zhiliang wang
01b74ea7c1 Add asm code for NoneZeroCount and refine related code 2015-01-04 16:39:17 +08:00
sijchen
7d5e88ffda Merge pull request #1687 from mstorsjo/update-releases
Update the RELEASES file with the 1.3.0 binaries
2015-01-04 10:21:29 +08:00
ruil2
2ef9a8aee9 Merge pull request #1692 from mstorsjo/improved-version-function
Add a new public function WelsGetCodecVersionEx
2015-01-04 09:14:29 +08:00
huili2
65e73d969a Merge pull request #1688 from mstorsjo/add-void
Add void to the parameter list of WelsGetCodecVersion
2015-01-04 09:00:26 +08:00
Martin Storsjö
50dc4757e4 Add a new public function WelsGetCodecVersionEx
This function doesn't return a struct, but fills in a struct via
a provided pointer.

The ABI of returning a struct is different between MSVC and mingw.

This allows using the same function from mingw, even though the DLL
has been built with MSVC.
2015-01-03 01:09:04 +02:00
Martin Storsjö
1a995cc991 Include private dependencies in the Libs line in pkg-config if only installing a static library
If only a static library is installed, the user of the library may
not know that only a static version of this particular library is
available (and doesn't know that --static should be added to the
pkg-config call). Therefore, one common practice is to include private
dependencies in the public Libs line if a static-only library is
installed.
2015-01-02 22:07:29 +02:00
Martin Storsjö
93621d6d9a Include -lstdc++ under Libs.private in the pkg-config file
This allows linking statically to the library, by passing --static
to pkg-config.
2015-01-02 21:54:21 +02:00
Martin Storsjö
a24bac34bd Don't install the pkg-config file as readonly
This file should be installed just as any other file, protected by
normal user permissions, not by making the file readonly.
2015-01-02 21:52:36 +02:00
Martin Storsjö
3901045318 Simplify the makefile rule for generating the pkg-config file 2015-01-02 21:52:05 +02:00
Martin Storsjö
ba314d16e7 Add void to the parameter list of WelsGetCodecVersion
When the header is used from C instead of C++, an empty parameter
list means that it can take any number of parameters, and can cause
warnings like "function declaration isn’t a prototype" with some
C compilers. Clarify this by explicitly adding void to this function.
2014-12-31 17:07:36 +02:00
Martin Storsjö
bdd02db04a Update the RELEASES file with the 1.3.0 binaries 2014-12-31 15:37:07 +02:00
huili2
e3e5208509 add new API as DecodeFrameNoDelay for immediate decoding, which will be recommended decoding method for h.264 bitstream 2014-12-30 23:43:47 -08:00
huili2
47d8a840c0 Merge pull request #1682 from huili2/parseonly_initial_no_colorformat
disable color format check for parse only
2014-12-31 13:14:47 +08:00
huili2
ad8ba85136 Merge pull request #1685 from HaiboZhu/Debug_No_Deblocking_when_TotalMB_equals_to_0
Force NO deblocking when no MB decoded in current slice
2014-12-31 13:14:17 +08:00
Haibo Zhu
81805ab23d Force NO deblocking when no MB decoded in current slice
Remove the judgment outside of the function
2014-12-30 18:25:54 -08:00
sijchen
22cabd39ca Merge pull request #1683 from HaiboZhu/Change_default_EC_mode
Change default EC mode
2014-12-30 16:17:42 +08:00
Haibo Zhu
a53dc467f6 Change default EC mode to ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE 2014-12-29 22:17:38 -08:00
HaiboZhu
d2d4ab8c67 Merge pull request #1680 from dongzha/SpeedupDecoding
speedup decoding
2014-12-29 17:17:25 +08:00
huili2
65dcd57c1b Merge pull request #1679 from HaiboZhu/Debug_Crash_1115349_AU_StartPos_Not_Reset
Reset AU start pos to 0 after construct AU
2014-12-29 16:58:26 +08:00
dong zhang
dc86cfe5d8 speedup decoding 2014-12-29 16:40:26 +08:00
huili2
b12b39a47b disable color format check for parse only 2014-12-28 23:43:09 -08:00
Haibo Zhu
7ee00b0618 Reset AU uiStartPos to 0 in ResetCurrentAccessUnit for svc
Reset uiStartPos to 0 when init and forceReset
2014-12-28 23:14:33 -08:00
Sijia Chen
6050bf89f6 add interface of simulcast avc, the actual support is coming later 2014-12-29 10:54:01 +08:00
sijchen
26ccd837f1 Merge pull request #1672 from huili2/parseonly_sizemodif
unify parseonly to have 0x0001
2014-12-26 09:58:28 +08:00
dongzha
4ebeb4bb70 Merge pull request #1673 from HaiboZhu/Debug_Crash_NoAU_SPS_Update
Add SPS/SubSPS/PPS update when AU number==0 and iOverwriteFlags==true
2014-12-26 09:30:43 +08:00
Haibo Zhu
586893ca4b Add SPS/SubSPS/PPS update when AU number==0 and iOverwriteFlags==true
Add TotalNumMbRec>0 judgement for EC
2014-12-25 15:03:47 -08:00
sijchen
b455c035f7 Merge pull request #1670 from ruil2/level
add profile and level checking in ParamValidation
2014-12-25 17:37:01 +08:00
ruil2
00a2dc290c modify trace info for LEVEL_UNKNOWN 2014-12-25 16:58:29 +08:00
sijchen
bac135ae81 Merge pull request #1665 from ruil2/frame_rate
refine frame rate
2014-12-25 16:53:52 +08:00
sijchen
1fb6b91b72 Merge pull request #1669 from ruil2/rc
add RC_TIMESTAMP_MODE mode
2014-12-25 16:35:40 +08:00
huili2
9c0bbeb4da unify parseonly to have 0x0001 2014-12-24 23:11:49 -08:00
ruil2
0babd8d7ab add profile and level checking in ParamValidation 2014-12-24 15:40:30 +08:00
ruil2
13f6ff59cc add RC_TIMESTAMP_MODE mode 2014-12-24 14:57:03 +08:00
ruil2
bd50f64152 Merge pull request #1668 from mstorsjo/fix-warnings
Fix build warnings with GCC
2014-12-24 09:09:29 +08:00
Martin Storsjö
8b7be9f3bc Initialize a local variable
This fixes warnings with GCC about a variable that may be used
uninitialized (if iResProperty was an incorrect value).
2014-12-23 23:18:20 +02:00
Martin Storsjö
8de54078d7 Use an unsigned variable for comparison with unsigned values
This avoids warnings about comparison between signed and unsigned.
2014-12-23 23:17:18 +02:00
Martin Storsjö
328094acfd Remove a write-only variable
This fixes warnings with GCC about a variable that is set but
not used.
2014-12-23 23:16:56 +02:00
ruil2
cf6450b269 refine frame rate 2014-12-23 17:30:01 +08:00
ruil2
59aee6052a Merge pull request #1667 from lyao2/ut_fix3
fix a spatial layer index error
2014-12-23 17:19:49 +08:00
lyao2
2e4fd4248a fix a spatial layer index error 2014-12-23 16:25:11 +08:00
sijchen
9cc395fc4e Merge pull request #1632 from ruil2/encoder_refine
use the same complexity computation branch for screen and camera
2014-12-23 10:51:53 +08:00
huili2
2c99f5810e Merge pull request #1659 from syureyi/scalinglist
Scalinglist
2014-12-23 10:50:49 +08:00
ruil2
1c7d3d4b47 Merge pull request #1664 from mstorsjo/type-signatures
Use the correct types instead of void pointers in function signatures in rc.h
2014-12-23 09:05:45 +08:00
Martin Storsjö
bdbda13929 Use the correct types instead of void pointers in function signatures in rc.h 2014-12-22 23:54:06 +02:00
Ethan Hugg
63375de8d7 Merge pull request #1662 from zaheerm/makefileversion
Update version in Makefile.
2014-12-22 09:59:38 -08:00
Zaheer Abbas Merali
09f6eeb940 Update version in Makefile. 2014-12-22 13:05:08 +00:00
sijchen
692614b057 Merge pull request #1660 from ruil2/frame_rate
using function pointer to make different branch for different rc
2014-12-22 15:55:46 +08:00
sijchen
ca36fe5128 Merge pull request #1661 from sijchen/docx
update the version header file to 1.3
2014-12-22 14:15:45 +08:00
Sijia Chen
eb8e25a038 update the version header file for 1.3 2014-12-22 14:13:30 +08:00
ruil2
e3bf63db59 using function pointer to make different branch for different rc 2014-12-22 12:00:39 +08:00
lingzhu
83b502b3f6 Delete \ 2014-12-22 11:12:05 +08:00
zhuling13
1699775cbb support scaling list
astyle

change bugs

fix security issue

fix the issue pps sps order

change according to wayne's suggestion

change according to wayne's
2014-12-21 19:00:28 -08:00
sijchen
9a602cac1b Merge pull request #1657 from mstorsjo/clip-bitrate
Make sure the random test bitrate is high enough
2014-12-21 18:49:26 -08:00
sijchen
c1752e2818 Merge pull request #1657 from mstorsjo/clip-bitrate
Make sure the random test bitrate is high enough
2014-12-22 10:37:43 +08:00
ruil2
397c7caa56 Merge pull request #1656 from mstorsjo/avoid-warning-unused
Avoid a warning about an unused static variable
2014-12-22 09:04:45 +08:00
Martin Storsjö
887b4f47fc Make sure the random test bitrate is high enough
This is the same fix as in 47df41 (for the ForceIntraFrame
test) applied to the ForceIntraFrameWithTemporal test.
2014-12-20 00:35:13 +02:00
Martin Storsjö
7411469e1d Avoid a warning about an unused static variable 2014-12-19 11:06:51 +02:00
sijchen
ef5f1c46b9 Merge pull request #1655 from sijchen/docx
add release note for preparation of v1.3.0
2014-12-19 14:43:59 +08:00
Sijia Chen
7d8bb6f290 add release note for preparation of v1.3.0 2014-12-19 14:10:39 +08:00
dongzha
809adc4129 Merge pull request #1654 from syureyi/newest
maintain codec demo
2014-12-19 14:05:07 +08:00
zhuiling
f0934c7bf3 maintain codec demo 2014-12-19 13:53:29 +08:00
sijchen
c3de0f99c5 Merge pull request #1653 from ruil2/framerate
remove macro definition to the header file
2014-12-19 13:27:52 +08:00
ruil2
3ae2507c99 remove macro definition to the header file 2014-12-19 10:53:06 +08:00
HaiboZhu
afd82b2cfa Merge pull request #1652 from huili2/newseq_bugfix
use picture-level new seq begin detection for output functions
2014-12-19 09:55:26 +08:00
sijchen
0dc461541a Merge pull request #1651 from mstorsjo/improve-version-header
Improve version header
2014-12-19 09:32:48 +08:00
Martin Storsjö
8bfeae27a4 Add a public function for getting the codec version
If the codec library is loaded dynamically, it may be necessary that
the loaded library actually matches the version that was used when
it was built, to avoid issues due to ABI differences. Therefore add
a public function to allow getting the version of the currently
loaded library.
2014-12-18 13:20:33 +02:00
Martin Storsjö
4fb442a983 Captizalize OpenH264 correctly in the version header 2014-12-18 13:18:30 +02:00
ruil2
91574afca4 Merge pull request #1603 from sijchen/add_ver1
add generating script and the first version of codec_ver.h
2014-12-18 17:33:29 +08:00
huili2
b8ce2eb40e use picture-level new seq begin detection for output functions 2014-12-18 01:19:33 -08:00
Sijia Chen
e6134b5972 skip the git version hash in the header 2014-12-18 16:07:37 +08:00
sijchen
5b2469c0b5 Merge pull request #1642 from mstorsjo/avoid-rebuilds
Avoid rebuilds if the version header hasn't changed
2014-12-18 15:51:07 +08:00
sijchen
4db34bdf43 Merge pull request #1634 from ruil2/trace
use WELS_LOG_ERROR as default trace level in console app
2014-12-18 10:11:38 +08:00
sijchen
b208cac1c5 Merge pull request #1638 from ruil2/default_trace
modify WELS_LOG_WARNING as the default trace level
2014-12-18 10:11:19 +08:00
huili2
916d24d99e Merge pull request #1650 from huili2/bugfix_cabac_mbqpdelta
unify spsid for pic and add check for mb_qp_delta
2014-12-18 10:01:37 +08:00
HaiboZhu
7f27198c68 Merge pull request #1648 from huili2/bugfix_cabacinitidc
add check for cabac_init_idc range in parsing
2014-12-18 09:07:17 +08:00
huili2
208400eeb4 unify spsid for pic and add check for mb_qp_delta 2014-12-17 00:31:20 -08:00
ruil2
ab480fe387 Merge pull request #1649 from sijchen/fix_trace
[Encoder] fix a potential problem of trace
2014-12-17 16:05:32 +08:00
ruil2
58e868c074 Merge pull request #1643 from mstorsjo/check-num-refs
If lowering the maximum number of ref frames, check iNumRefFrames as well
2014-12-17 15:51:52 +08:00
sijchen
8dbdb418ca Merge pull request #1641 from mstorsjo/test-min-bitrate
Make sure the random test bitrate is high enough
2014-12-17 15:50:13 +08:00
Sijia Chen
1b26bd4b88 put this file into good format 2014-12-17 14:15:10 +08:00
Sijia Chen
3c08f04993 add fix for protection of wrong reading if input is invalid 2014-12-17 14:14:23 +08:00
huili2
030d320e43 Merge pull request #1646 from dongzha/cabacfix
cabac fix
2014-12-17 11:18:23 +08:00
huili2
182ae421a1 Merge pull request #1647 from HaiboZhu/Debug_Check_Ref_Picture_Complete
Change the name and call logic of CheckRefPicturesComplete function
2014-12-17 11:18:11 +08:00
huili2
9f0ed3fc4b add check for cabac_init_idc range in parsing 2014-12-16 18:13:21 -08:00
ruil2
ac992acaa9 Merge pull request #1640 from mstorsjo/fix-tests
Fix occasional failures in some tests
2014-12-17 09:29:36 +08:00
dong zhang
490a3e5562 cabac fix 2014-12-17 09:27:41 +08:00
Haibo Zhu
590eef6059 Change the name and call logic of CheckRefPicturesComplete function. 2014-12-16 17:26:13 -08:00
ruil2
affa753d5d Merge pull request #1645 from mstorsjo/type-signatures
Use the correct types instead of void pointers in function signatures
2014-12-17 09:21:11 +08:00
Martin Storsjö
f89780ddd8 Use the correct types instead of void pointers in function signatures
This gets rid of 50 lines of code with just casts of void pointers,
making the code shorter and clearer.
2014-12-16 22:13:38 +02:00
Ethan Hugg
6f876d79a6 Merge pull request #1644 from mstorsjo/fix-script-typos
Fix a number of typos in run_SafeDelete.sh
2014-12-16 09:26:23 -08:00
Martin Storsjö
ee5896e4a1 Fix a number of typos in run_SafeDelete.sh 2014-12-16 16:28:45 +02:00
Martin Storsjö
4746ce8fd4 If lowering the maximum number of ref frames, check iNumRefFrames as well
Make sure we don't set iMaxNumRefFrames lower than iNumRefFrames.

This fixes occasional test failures in
EncodeDecodeTestAPI.SetOptionEncParamExt.
2014-12-16 13:56:50 +02:00
Martin Storsjö
f90cd367d2 Avoid rebuilds if the version header hasn't changed
When generating the version header, don't overwrite it if the
new version is identical to the old one.
2014-12-16 12:23:50 +02:00
Martin Storsjö
47df411b1a Make sure the random test bitrate is high enough
The ForceIntraFrame test will fail (giving up after 100 skipped
frames) if the bitrate is not set high enough.

Set the minimum bitrate to w*h/50, which is a very low value,
but which still should allow getting a non-skipped frame within
a few attempts.
2014-12-16 11:56:48 +02:00
lyao2
9692f6cb20 Merge pull request #1639 from ruil2/qp_trace
fix error output info
2014-12-16 17:32:00 +08:00
Martin Storsjö
f4b3724976 Increase the minimum frame size in a test with multiple spatial layers
Make sure the input frame size is large enough that the downsampled
layers also have a nonzero resolution.
2014-12-16 11:13:22 +02:00
Martin Storsjö
59fefbe7c7 Use an inline function instead of a macro for clipping which contains rand()
When using a macro, the macro parameters get evaluated
multiple times, which means that the rand() value compared
actually isn't the same that is used as return value.

This makes sure that clipping works as intended for the
random tests.
2014-12-16 11:13:22 +02:00
Martin Storsjö
a9c2e1b431 Use the common WELS_CLIP3 macro instead of a custom reimplementation 2014-12-16 11:13:22 +02:00
dongzha
a4370b8ca8 Merge pull request #1637 from dongzha/SpeedUpSkipMode
astyle and speed up decoding by removing unnessary memset
2014-12-16 16:31:10 +08:00
ruil2
0612b07a6f fix error output info 2014-12-16 16:10:52 +08:00
lyao2
6a10553dce Merge pull request #1636 from ruil2/qp_trace
astyle two files
2014-12-16 16:04:50 +08:00
ruil2
f132745882 Merge pull request #1635 from mstorsjo/binary-comparison-ignore
Add a gitignore entry for another file created by the binary comparison scripts
2014-12-16 15:40:23 +08:00
dong zhang
89f78e9211 astyle and speed up decoding by removing unnessary memset 2014-12-16 15:30:09 +08:00
ruil2
fdb938a2c2 modify WELS_LOG_WARNING as the default trace level 2014-12-16 15:29:56 +08:00
ruil2
b932547fe8 astyle two files 2014-12-16 15:16:09 +08:00
Martin Storsjö
d387ebc358 Add a gitignore entry for another file created by the binary comparison scripts 2014-12-16 09:06:10 +02:00
ruil2
026ce4030a use WELS_LOG_ERROR as default trace level in console app 2014-12-16 13:14:53 +08:00
sijchen
2c69638773 Merge pull request #1633 from lyao2/avg_qp2
add average QP in statistics
2014-12-16 11:51:18 +08:00
ruil2
812b57c704 Merge pull request #1628 from mstorsjo/fix-tests
Fix binary comparison scripts and tables
2014-12-16 10:54:41 +08:00
ruil2
173ec608ff use the same complexity computation branch for screen and camera 2014-12-16 10:42:36 +08:00
lyao2
ca2436bb5e add average QP in statistics 2014-12-16 10:32:44 +08:00
ruil2
827c7b2aef Merge pull request #1629 from mstorsjo/msvc-casts
Cast a float to integer
2014-12-16 09:09:53 +08:00
ruil2
d87663b913 Merge pull request #1630 from zaheerm/fixcomments
Fix comments to be up to date with current API.
2014-12-16 09:09:44 +08:00
Martin Storsjö
c0633a147e Readd and update the accidentally cleared SHA1 test tables
These were accidentally cleared in 5ab5fe15, when the script
for updating them was broken.
2014-12-15 23:33:16 +02:00
Zaheer Abbas Merali
91736e85e8 Fix comments to be up to date with current API. 2014-12-15 11:37:32 -08:00
Martin Storsjö
54cc3daaa7 Cast a float to integer
This fixes warnings with MSVC.
2014-12-15 17:38:22 +02:00
Martin Storsjö
8a2237751a Fix a check in the binary comparison scripts 2014-12-15 17:28:10 +02:00
Martin Storsjö
3aac5e0fae Properly update hashes 2014-12-15 17:26:23 +02:00
huili2
8fb4048241 Merge pull request #1627 from HaiboZhu/Debug_potential_out_of_memory
Reset parameter set status and clear AU list when out of memory
2014-12-15 17:39:36 +08:00
Haibo Zhu
57043d16ad (1) Reset parameter set status and clear AU list when out of memory
(2) Free un-complete malloc memory, keep the original state, special when increase memory
2014-12-15 00:53:40 -08:00
huili2
d422ee59ad Merge pull request #1626 from dongzha/testcrash1
add protection
2014-12-15 15:39:46 +08:00
dongzha
ac061fe635 add protection 2014-12-15 14:47:55 +08:00
dongzha
091e5cba0a Merge pull request #1624 from huili2/au_data_check
change au_ready status and check au number
2014-12-15 13:46:27 +08:00
dongzha
eeee1a2e95 Merge pull request #1622 from dongzha/setunuse
add set unused in dpb
2014-12-15 13:35:36 +08:00
huili2
c20e1c6795 change au_ready status and check au number 2014-12-14 20:46:14 -08:00
sijchen
509727e225 Merge pull request #1623 from ruil2/level_5
keep the consistency between sps level and parameter level
2014-12-15 11:55:30 +08:00
ruil2
5ab5fe155b keep the consistency between sps level and parameter level 2014-12-15 09:56:54 +08:00
sijchen
7dcaaf5328 Merge pull request #1618 from huili2/modify_freeze_pos
modify freeze output to proper location
2014-12-12 17:50:02 +08:00
dong zhang
ad38cfe46c add set unused in dpb 2014-12-12 16:53:13 +08:00
sijchen
cc1f3ade3a Merge pull request #1617 from ruil2/bits_update
fix a typo
2014-12-12 16:25:48 +08:00
huili2
984497cc09 modify freeze output to proper location 2014-12-11 23:42:04 -08:00
ruil2
06c251fa48 fix a typo 2014-12-12 14:29:45 +08:00
sijchen
93265d7a44 Merge pull request #1616 from dongzha/testcrash
fix two continus IDR, with same sps/pps id, but different resolution
2014-12-12 10:43:32 +08:00
dongzha
1bdf00ddf4 fix two continus IDR, with same sps/pps id, but different resolution 2014-12-12 09:38:44 +08:00
ruil2
41339f3023 Merge pull request #1615 from lyao2/ut_idr3
refine the UT case for checking IDR request
2014-12-12 09:13:29 +08:00
sijchen
0ff1eb482f Merge pull request #1612 from huili2/log_add_this_codec
add this log for codec
2014-12-11 17:01:38 +08:00
ruil2
ec99819ce8 Merge pull request #1614 from sijchen/fix_idr_id1
[Encoder] fix idr_id: idr_id should be adding regardless of the sps strategy
2014-12-11 16:41:59 +08:00
ruil2
3be8ae7a4e Merge pull request #1613 from sijchen/fix_ut2
[UT] encoder log level adjustment
2014-12-11 16:29:34 +08:00
lyao2
2e85e3c7d9 refine the UT case for checking IDR request 2014-12-11 14:32:26 +08:00
Sijia Chen
f1a7a1a966 encoder log level adjustment in UT to avoid too many output and some formatting 2014-12-11 14:31:32 +08:00
huili2
3e57fdc448 add this log for codec 2014-12-10 22:15:32 -08:00
sijchen
5ff55a6ec2 Merge pull request #1608 from ruil2/bits_update
update maxbitrate to control bitrate vary range
2014-12-11 13:46:07 +08:00
dongzha
44e4531897 Merge pull request #1609 from dongzha/NewFixEcRatioCalc
New fix ec ratio calc
2014-12-11 13:08:01 +08:00
dongzha
44bd61683a Merge pull request #1606 from huili2/log_for_memory_realloc
add log for ref pic buffer memory alloc
2014-12-11 13:07:43 +08:00
dong zhang
d20a3bdb28 fix typo bug 2014-12-11 12:28:32 +08:00
Sijia Chen
32d6193f97 fix idr_id: idr_id should be adding regardless of the sps strategy 2014-12-11 10:58:27 +08:00
ruil2
5ba9e409ba update maxbitrate to control bitrate vary range 2014-12-11 10:56:58 +08:00
dong zhang
2c468b96a9 add flag to count EC Mbs due to ref error
add UT
2014-12-11 10:49:55 +08:00
dong zhang
ecc8ae6ebb fix decodestatus uiEcRatio calc bug 2014-12-11 10:39:44 +08:00
sijchen
065c3a7769 Merge pull request #1607 from mstorsjo/encoder-init-log
Log the encoder version later in the initialization
2014-12-11 10:28:24 +08:00
Martin Storsjö
7da17b5abd Log the encoder version later in the initialization
Previously, the encoder logging was done in InitEncoder(),
which is called from the constructor. Therefore, it was impossible
to override the log level, to silence this message.
2014-12-10 14:39:08 +02:00
dongzha
af97f2d4bb Merge pull request #1605 from sijchen/fix_ut1
fix a UT function
2014-12-10 11:18:08 +08:00
sijchen
4e88de1755 Merge pull request #1600 from shihuade/UpdateSHA1
update SHA1 table which have been broken by previous update
2014-12-10 11:09:11 +08:00
Sijia Chen
87c83c0d36 fix a UT function 2014-12-10 10:49:58 +08:00
dongzha
44017193ed Merge pull request #1601 from dongzha/FixDecodeStatusFps
add a decoder status: float fActualAverageFrameSpeedInMs
2014-12-10 10:40:08 +08:00
Sijia Chen
b65410ebdb add generating script and the first version of codec_ver.h 2014-12-10 10:10:23 +08:00
dong zhang
354eee3e2b add a decoder status: float fActualAverageFrameSpeedInMs; ///< actual average_Decoding_Time, includeing freezed picture 2014-12-10 10:00:34 +08:00
huili2
155a91406c Merge pull request #1599 from HaiboZhu/Debug_Add_subSPS_check
Add subSPS pre-active check in CheckActiveSPS
2014-12-09 17:11:06 +08:00
Haibo Zhu
e47a3638af Add subSPS pre-active check in CheckActiveSPS 2014-12-09 00:06:19 -08:00
huade
944a041066 1 update SHA1 table which have been broken by previous update; 2 enhance script to support more case(multi layer etc.) 2014-12-09 15:59:07 +08:00
huili2
14eeaf2278 add log for ref pic buffer memory alloc 2014-12-08 22:35:07 -08:00
sijchen
e041bc6938 Merge pull request #1597 from mstorsjo/msvc-casts
Add casts when converting from int64_t or double to int32_t
2014-12-09 10:03:03 +08:00
Martin Storsjö
901a599b36 Add casts when converting from int64_t or double to int32_t
This fixes warnings when building with MSVC.
2014-12-08 11:48:31 +02:00
sijchen
cc5978b252 Merge pull request #1594 from lyao2/RC_maxBr_commit5
Rate control refine to fit MAX bitrate requirement
2014-12-08 11:03:43 +08:00
sijchen
c2d585761a Merge pull request #1595 from ruil2/update_2
should not set WELS_LOG_ERROR level in encoder initilization.
2014-12-08 11:01:19 +08:00
ruil2
317ac1ca85 change info level as default level 2014-12-05 17:36:03 +08:00
ruil2
56c895ffb4 1. should not set WELS_LOG_ERROR level in encoder initilization.
2.fix UT bug
2014-12-05 17:08:00 +08:00
lyao2
c01606c28a Rate control refine to fit MAX bitrate requirement 2014-12-05 12:09:08 +08:00
ruil2
ea93f3943e Merge pull request #1593 from ethanhugg/gmpapiversion
Switch to use stable branch of gmp-api
2014-12-05 09:40:05 +08:00
Ethan Hugg
a8159c89d1 Switch to use stable branch of gmp-api 2014-12-04 10:24:36 -08:00
HaiboZhu
befd5bdd56 Merge pull request #1592 from dongzha/FixGreyPic
fix grey picture when resolution is the same
2014-12-04 18:11:07 +08:00
dongzha
fc895c13ce fix grey picture when resolution is the same 2014-12-04 17:22:27 +08:00
HaiboZhu
054b8eeb3a Merge pull request #1588 from huili2/dec_stat_accumulate
accumulate dec stat
2014-12-04 15:37:10 +08:00
HaiboZhu
60b6ce1454 Merge pull request #1589 from huili2/fix_fmo_sliceskip
fix crash issue of sliceskip and inf-loop in fmo
2014-12-04 15:36:51 +08:00
huili2
928a7eac2a fix crash issue of sliceskip and inf-loop in fmo 2014-12-03 20:26:00 -08:00
sijchen
a5cabf0be4 Merge pull request #1582 from mstorsjo/lib-install-fixes
Fix/clean up building and installing shared libraries
2014-12-02 11:48:22 -08:00
ruil2
91ae2dab7a Merge pull request #1587 from mstorsjo/msvc-warnings
Don't implicitly convert int to bool
2014-12-02 15:54:35 +08:00
ruil2
dd24edc8ff Merge pull request #1585 from dongzha/issue1535New
fix issue #1535 new
2014-12-02 15:54:26 +08:00
Martin Storsjö
5d4eb63d52 Don't implicitly convert int to bool
This avoids warnings with MSVC.
2014-12-02 09:35:05 +02:00
ruil2
f4af5d2fda Merge pull request #1586 from ganyangbbl/fix_character
fix chinese character
2014-12-02 15:10:55 +08:00
ganyangbbl
6981aec743 fix chinese character 2014-12-02 14:30:31 +08:00
huili2
8b9be2b3dc accumulate dec stat 2014-12-01 19:01:06 -08:00
dong zhang
f668e1be98 fix issue 1535 2014-12-02 09:35:39 +08:00
sijchen
607d814e0f Merge pull request #1577 from ruil2/set_param
modify log info(remove unuseful log and add some new logs)
2014-12-01 11:36:24 -08:00
Martin Storsjö
3d263d1087 Set a default SHAREDLIB_DIR in the main Makefile
Only override it in the ones where the default isn't desired.
2014-12-01 15:44:27 +02:00
Martin Storsjö
9b59e50292 Simplify creating output directories for the install-shared rule 2014-12-01 15:44:27 +02:00
Martin Storsjö
a48b632aed Actually install the shared library into $(SHAREDLIB_DIR) as intended 2014-12-01 15:44:27 +02:00
Martin Storsjö
e132658346 Set SHAREDLIB_DIR for msvc as well 2014-12-01 15:44:27 +02:00
Martin Storsjö
59c30f8952 Handle generating the versionless library via make rules
This makes sure both "make libopenh264.so" and "make libopenh264.so.0"
work as intended.

Use the versionless name as dependency for the install rule,
to make sure both (if possible) are created.
2014-12-01 15:43:35 +02:00
Martin Storsjö
575b6fb570 Check the suffix instead of checking whether a file is a link
This feels more straightforward - some file systems/environments
(such as MSys) implement symlinks as plain file copies, where
distinguishing whether a file is a link might be hard.
2014-12-01 15:40:25 +02:00
Martin Storsjö
2c9b5b98c0 Actually install the versioned shared library file as well 2014-12-01 15:40:25 +02:00
Martin Storsjö
8e419e41d3 Simplify setting the shlib flags for msvc 2014-12-01 15:40:25 +02:00
Martin Storsjö
80beaed5c6 Fix the dependencies of the install-shared target
Previously calling "make install" failed unless the target
actually already was built, for platforms where the shared
libraries are versioned.
2014-12-01 15:40:25 +02:00
Martin Storsjö
8f7e10ab12 Honor the silent build flag when adding the shared library symlink 2014-12-01 15:40:25 +02:00
Martin Storsjö
a7d8142a44 Set the right SHAREDLIBSUFFIXVER for msvc 2014-12-01 15:40:25 +02:00
Martin Storsjö
397e20b0f3 Install the import library via the EXTRA_LIB mechanism on mingw as well
Prior to 3f69873c99, there already was a mechanism for installing
the import library, used for the MSVC builds. Use that for mingw
as well, instead of adding more hardcoded rules.
2014-12-01 15:40:25 +02:00
zhilwang
852ed8a2d0 Merge pull request #1578 from ruil2/rc
use existed assembly function in cabac encoder
2014-12-01 17:12:52 +08:00
ruil2
2e15351d6d Merge pull request #1567 from dongzha/FixMvCpBug
avoid using the same picture buff for prev pic and curr pic
2014-12-01 14:53:17 +08:00
ruil2
b1dccaa627 use existed assembly function in cabac encoder 2014-12-01 14:45:04 +08:00
sijchen
8c7aaa8421 Merge pull request #1568 from ruil2/cleanup
add iBitsVaryPercentage parameters to control bitrate
2014-11-30 21:39:39 -08:00
ruil2
9a08b7f97c Merge pull request #1574 from huili2/dec_stat_add_freeze
add dec status for freezing
2014-12-01 12:43:22 +08:00
ruil2
a100fb8031 modify log info(remove unuseful log and add some new logs) 2014-12-01 12:13:58 +08:00
sijchen
8e39cb3a3a Merge pull request #1575 from ruil2/set_param
add SetOption(ENCODER_OPTION_SVC_ENCODE_PARAM_BASE,&base) for encoder
2014-11-30 19:39:18 -08:00
dongzha
d58f90947c avoid using the same picture buff for prev pic and curr pic 2014-12-01 10:52:37 +08:00
ruil2
8028fe7130 add SetOption(ENCODER_OPTION_SVC_ENCODE_PARAM_BASE,&base) for encoder 2014-12-01 10:35:32 +08:00
ruil2
c592d18dfd Merge pull request #1573 from sijchen/after_review1
[Encoder] remove a too-tight checking of bit rate
2014-12-01 10:31:47 +08:00
ruil2
30820fd8b5 use iBitsVaryPercentage passed by the app instead of the macro 2014-12-01 09:16:35 +08:00
Sijia Chen
7cea82bdf8 remove a too-tight checking of bit rate 2014-11-28 16:15:49 -08:00
sijchen
e7debe7351 Merge pull request #1571 from mstorsjo/silence-intentional-errors
Silence logging in a test which intentionally can trigger errors
2014-11-28 10:28:05 -08:00
sijchen
59e782a8a5 Merge pull request #1572 from mstorsjo/loopfilter-opts
Fixes relating to the loopfilter parameter
2014-11-28 10:27:14 -08:00
Ethan Hugg
1526de3ae5 Merge pull request #1566 from nirbheek/master
Makefile: Fix shared library building on various OSes
2014-11-28 08:49:25 -08:00
Martin Storsjö
0bae0f869a Validate that iLoopFilterDisableIdc is set to a sensible value in ParamValidationExt
In WelsEncoderParamAdjust it is already clipped in the
same way, but here we should probably rather error out
than to silently clip it to the right range.
2014-11-28 13:08:52 +02:00
Martin Storsjö
24cd934ba9 Log what uiDisableDeblockingFilterIdc was set to when printing an error message 2014-11-28 13:06:12 +02:00
Martin Storsjö
90eee67eb7 Don't set invalid iLoopFilterDisableIdc in RandomParamExtCombination 2014-11-28 13:05:32 +02:00
Martin Storsjö
b9dc310857 Silence logging in a test which intentionally can trigger errors 2014-11-28 11:04:03 +02:00
huili2
504cabf106 add dec status for freezing 2014-11-28 00:05:36 -08:00
ruil2
c44d4a7f07 Merge pull request #1569 from mstorsjo/pointer-diff-cast
Add casts when converting pointer differences to integers
2014-11-27 21:54:42 +08:00
Martin Storsjö
917d41bd47 Add casts when converting pointer differences to integers
This fixes warnings when building with MSVC in 64 bit mode.
2014-11-27 11:31:13 +02:00
ruil2
7c0369da23 add iBitsVaryPercentage parameters to control bitrate 2014-11-27 15:55:48 +08:00
HaiboZhu
82b70b34fe Merge pull request #1561 from ruil2/cleanup
remove some macro definitions in header files
2014-11-27 14:22:06 +08:00
zhilwang
3a73179cab Merge pull request #1559 from HaiboZhu/EC_off_crash_no_output
Debug for (1) decoder crash when delay decoding (2) no output when EC off
2014-11-27 14:21:48 +08:00
HaiboZhu
69f6db1b90 Merge pull request #1560 from ruil2/max2
cleanup macro definition
2014-11-27 14:21:37 +08:00
HaiboZhu
c2c861f199 Merge pull request #1562 from zhilwang/asm-cabac
Add asm code for decoder cabac
2014-11-27 14:21:02 +08:00
Nirbheek Chauhan
3f69873c99 Makefile: Fix shared library building on various OSes
Versioned for OS not in (Windows, Android), and create a .dll.a implib on Windows
2014-11-27 02:04:06 +05:30
zhiliang wang
92bc88eacb Add asm code for decoder cabac 2014-11-26 16:44:12 +08:00
ruil2
80ce939d7a remove some macro definitions in header files 2014-11-26 16:15:19 +08:00
ruil2
a43fa3aec2 cleanup macro definition 2014-11-26 15:22:04 +08:00
sijchen
e1262a9ac9 Merge pull request #1558 from huili2/comment_outputlog
comment output info with FREEZE
2014-11-25 22:54:43 -08:00
sijchen
fe7faf768a Merge pull request #1555 from huili2/comment_API_parseonly
add parse only comment in API
2014-11-25 22:54:04 -08:00
Haibo Zhu
aa5e7f7927 Remove the SPS/PPS exist ahead reset logic and change the CheckSpsActive logic 2014-11-25 21:53:40 -08:00
huili2
9da19758cf Merge pull request #1556 from ruil2/max2
remove some unused code
2014-11-26 13:33:21 +08:00
huili2
f131b4540b Merge pull request #1557 from dongzha/AddDecoderTimeStampNew
add timestamp in decoder
2014-11-26 13:32:40 +08:00
dong zhang
2e5243e5fc add timestamp in decoder 2014-11-26 13:03:46 +08:00
ruil2
4a6de5bb13 remove some unused code 2014-11-26 10:26:16 +08:00
huili2
347e4893a9 add parse only comment in API 2014-11-25 18:22:23 -08:00
huili2
94dde141fa comment output info with FREEZE 2014-11-25 18:09:01 -08:00
sijchen
f48b2e55ba Merge pull request #1553 from ruil2/max2
add maxbitrate verification
2014-11-25 09:14:39 -08:00
sijchen
7be8d200d5 Merge pull request #1554 from mstorsjo/add-float-cast
Explicitly cast int64_t to float
2014-11-25 09:12:37 -08:00
Martin Storsjö
1ff9de36ce Explicitly cast int64_t to float
This fixes warnings when bulding with MSVC.
2014-11-25 14:28:20 +02:00
ruil2
22cc0a88c6 Merge pull request #1552 from mstorsjo/init-parameters
Initialize the bParseOnly field in DecoderInterfaceTest::TestInitUninit
2014-11-25 17:14:32 +08:00
ruil2
0d426b826d Merge pull request #1551 from sijchen/after_review2
add parentness
2014-11-25 17:13:54 +08:00
ruil2
d543ae89db add maxbitrate verification 2014-11-25 17:12:06 +08:00
Martin Storsjö
29da6a600a Initialize the bParseOnly field in DecoderInterfaceTest::TestInitUninit
This fixes valgrind warnings about using uninitialized data
in this test.
2014-11-25 09:59:25 +02:00
Sijia Chen
cef85118b5 add parentness 2014-11-24 22:44:06 -08:00
huili2
305a2421be Merge pull request #1549 from dongzha/ECMvCopy
add EC MV copy
2014-11-25 12:59:48 +08:00
ruil2
f1fb0d6b69 Merge pull request #1548 from sijchen/after_review
[Encoder] add one more condition for statistics printing to avoid potential timestamp problem
2014-11-25 11:20:38 +08:00
dong zhang
9425c2ab10 add EC MV copy 2014-11-25 10:45:58 +08:00
Sijia Chen
3be7e90221 add one more conditin for statistics printing to avoid timestamp problem 2014-11-24 16:11:52 -08:00
sijchen
48e79d51b5 Merge pull request #1547 from huili2/ParseDecode
parse only add and UT: passed reviewed at https://rbcommons.com/s/OpenH264/r/910/
2014-11-24 11:28:17 -08:00
sijchen
336b2d1537 Merge pull request #1542 from sijchen/review
[Encoder] refactor Sps generation: passed review at https://rbcommons.com/s/OpenH264/r/930/
2014-11-24 11:27:38 -08:00
huili2
b231e3f000 parse only add and UT 2014-11-24 00:04:36 -08:00
sijchen
53c14dccf0 Merge pull request #1545 from ruil2/add_traces
add some traces
2014-11-21 14:01:43 -08:00
ruil2
3025c58a67 add some traces 2014-11-21 13:27:10 +08:00
ruil2
a0b0866597 Merge pull request #1543 from dongzha/Fix1535
Check and Fix some issue #1535
2014-11-21 11:30:36 +08:00
ruil2
1359583c55 Merge pull request #1544 from shihuade/master
1.doxgen documentation format for comments in api/*.h 2. comments to wik...
2014-11-21 11:29:34 +08:00
huashi
7175d3c90e 1.doxgen documentation format for comments in api/*.h 2. comments to wiki tools in openh264/docs/* 2014-11-21 10:38:30 +08:00
Sijia Chen
cdd410ca66 refactor Sps generation 2014-11-20 12:55:48 -08:00
ruil2
24fb213d6e Merge pull request #1537 from sijchen/after_review
[Encoder] Two refinements related to max bit rate setting and Timestamp
2014-11-20 09:33:36 +08:00
Sijia Chen
0b2c82d92b add UNSPECIFIED value for max bit rate setting 2014-11-19 16:05:19 -08:00
Sijia Chen
810b9770fc using same type as in interface rather than int32 for uiTimestamp to avoid missing of preciseness 2014-11-19 15:45:09 -08:00
dong zhang
b18e905946 Check and Fix some issue#1535 2014-11-19 16:03:34 +08:00
ruil2
c13bfe6407 Merge pull request #1536 from sijchen/improve_br_valid
[Encoder] adjust the param validation of max bit rate
2014-11-18 18:42:03 +08:00
sijchen
0252f3f346 Merge pull request #1526 from ruil2/max_nal_size
add return value processing
2014-11-17 16:43:45 -08:00
sijchen
b05a52be7a Merge pull request #1534 from syureyi/level9
add level 9 supporting
2014-11-17 16:43:37 -08:00
Sijia Chen
7e24efc620 adjust the param validation of max bit rate 2014-11-17 16:39:42 -08:00
zhuiling
02853a9a96 add level 9 supporting 2014-11-17 16:29:33 +08:00
dongzha
cbb6e993cf Merge pull request #1533 from mstorsjo/speedup-tests
Speed up some slow tests in the unit test suite
2014-11-14 17:16:06 +08:00
dongzha
bfee07dde4 Merge pull request #1532 from huili2/new_EC_IDR_reschange
add EC method to freeze sequence when resolution changed and decoding IDR error
2014-11-14 17:14:09 +08:00
Martin Storsjö
deefdcee10 Use & 0xff instead of WELS_CLIP3(, 0, 255)
This speeds up the whole EncoderInterfaceTest to about double
the speed from before.
2014-11-14 10:41:21 +02:00
Martin Storsjö
45c322a8ae Reduce the number of rounds in DecoderCrashTest
Currently this one single test accounts for 12-20% of the total
runtime of running the unit test suite.
2014-11-14 10:41:21 +02:00
ruil2
606da1a97d Merge pull request #1531 from mstorsjo/use-right-type
Use the right data type for a variable
2014-11-14 16:30:17 +08:00
Martin Storsjö
9ec743c156 Use the right data type for a variable
Both pNalLengthInByte[] that are accumulated, and sFbi.iFrameSizeInBytes
that it is compared to, are plain 'int', not 'uint32_t'.

This fixes warnings about comparison between signed and unsigned.
2014-11-14 09:47:49 +02:00
huili2
0d16fd61b2 add EC method to freeze sequence when resolution changed and decoding IDR error 2014-11-13 19:26:10 -08:00
ruil2
703bbef128 Merge pull request #1530 from sijchen/after_review
[Encoder] add total length in encoder output and complete statistics
2014-11-14 11:20:45 +08:00
Sijia Chen
b56b8725fc add total length in encoder output and complete most of the statistis calculation 2014-11-13 13:56:58 -08:00
ruil2
aed7b2316c Merge pull request #1528 from mstorsjo/fix-warnings
Cast to the right data type to avoid comparison warnings in gcc
2014-11-13 17:17:41 +08:00
Martin Storsjö
2453676960 Cast to the right data type to avoid comparison warnings in gcc 2014-11-13 10:48:45 +02:00
HaiboZhu
7a2e536e44 Merge pull request #1525 from dongzha/FixbuginMVClip
fix mv clip at right boarder
2014-11-13 14:01:45 +08:00
ruil2
66165a65d5 add return value processing 2014-11-13 13:26:14 +08:00
sijchen
b3922b1d3a Merge pull request #1519 from ruil2/max_nal_size
add maxnalsize control for gmp wrapper
2014-11-12 20:44:24 -08:00
dong zhang
e4f114e006 fix mv clip at right boarder 2014-11-13 10:48:35 +08:00
dongzha
429ccb38a8 Merge pull request #1524 from huili2/parse_err_return_bug_fix
fix bug of parse error return for VCL data
2014-11-12 13:18:08 +08:00
ruil2
9ba0a1d977 Merge pull request #1522 from sijchen/after_review
[Encoder] fix a calculation of fAverageFrameRate
2014-11-12 12:29:13 +08:00
huili2
2527cf5d0b fix bug of parse error return for VCL data 2014-11-11 19:23:58 -08:00
Sijia Chen
cd5928d397 fix a calculation of fAverageFrameRate 2014-11-11 16:12:38 -08:00
sijchen
f42c9fae42 Merge pull request #1518 from huili2/ec_UT_0_bugfix
EC UT fail bug fix
2014-11-11 14:52:28 -08:00
sijchen
a37f1abe5e Merge pull request #1517 from ruil2/cabac_qp
fix cabac encoding bug -- don't get the correct previous mb qp
2014-11-11 14:52:04 -08:00
ruil2
128546b992 add maxnalsize control for gmp wrapper 2014-11-11 14:18:02 +08:00
ruil2
560fcf17fd rename parameters 2014-11-11 12:21:01 +08:00
huili2
fd45e7ff15 EC UT fail bug fix 2014-11-10 17:56:26 -08:00
sijchen
9512515a41 Merge pull request #1515 from ruil2/add_nal_trace
add some traces for bitstream output
2014-11-10 15:00:08 -08:00
ruil2
24823621e1 Merge pull request #1516 from mstorsjo/remove-duplicated-field
Remove a duplicated field in SWelsSvcCodingParam
2014-11-10 15:56:51 +08:00
ruil2
c31511257b fix cabac encoding bug -- don't get the correct previous mb qp 2014-11-10 15:34:49 +08:00
ruil2
1c44c43b8a add some traces for bitstream output 2014-11-10 15:20:25 +08:00
Martin Storsjö
0aa77d2985 Remove a duplicated field in SWelsSvcCodingParam
The same field already exists in SEncParamExt. When the
initialization was deduplicated in ac404ce, this lead to
reading the now uninitialized field in SWelsSvcCodingParam,
instead of the properly initialized one in the base class.
2014-11-10 09:03:18 +02:00
sijchen
8b49f98475 Merge pull request #1507 from ruil2/init
remove repeat initialization
2014-11-09 18:07:21 -08:00
ruil2
fc811a80fb Merge pull request #1512 from mstorsjo/add-float-cast
Add a cast when converting from double to float
2014-11-09 09:36:21 +08:00
ruil2
843955bc06 Merge pull request #1511 from mstorsjo/check-fread-return-value
Check the return value of fread
2014-11-09 09:35:26 +08:00
Ethan Hugg
a7b22795bf Merge pull request #1510 from mstorsjo/unsigned-int-literals
Change integer literals to unsigned to avoid warnings about comparison between signed and unsigned
2014-11-07 09:49:00 -08:00
Ethan Hugg
3c753c42b8 Merge pull request #1509 from mstorsjo/fix-warnings-cast
Add casts to avoid warnings about comparison between signed and unsigned
2014-11-07 09:46:33 -08:00
Ethan Hugg
067fa09781 Merge pull request #1508 from mstorsjo/remove-unused-variables
Remove unused variables
2014-11-07 09:45:52 -08:00
Martin Storsjö
c8afd15681 Add a cast when converting from double to float
This fixes warnings with MSVC.
2014-11-07 11:41:59 +02:00
Martin Storsjö
80bfc43df5 Check the return value of fread
This silences warnings on linux/gcc.
2014-11-07 11:24:30 +02:00
Martin Storsjö
50e2eb5e3c Change integer literals to unsigned to avoid warnings about comparison between signed and unsigned
This fixes warnings in gcc.
2014-11-07 11:19:19 +02:00
Martin Storsjö
2b9f4f6607 Add casts to avoid warnings about comparison between signed and unsigned
This fixes warnings with gcc.
2014-11-07 11:17:44 +02:00
Martin Storsjö
08c07e4b8f Remove unused variables
This fixes warnings with clang and gcc.
2014-11-07 11:12:51 +02:00
ruil2
ac404ce69d remove repeat initialization 2014-11-07 14:58:43 +08:00
HaiboZhu
44013d4cd5 Merge pull request #1504 from syureyi/android_bugfix
android platform bug fix
2014-11-06 21:31:03 +08:00
dongzha
789603a8b1 Merge pull request #1503 from huili2/ec_crossIDR
enable cross IDR EC method
2014-11-06 17:24:17 +08:00
zhuiling
7fa6c576e3 android platform bug fix 2014-11-06 17:15:42 +08:00
dongzha
0fa667ac5f Merge pull request #1502 from dongzha/RemoveUglyCode
remove ugly MC code
2014-11-06 15:26:38 +08:00
dongzha
1a7826c6eb remove ugly MC code 2014-11-06 14:44:33 +08:00
sijchen
5cb5c28331 Merge pull request #1500 from syureyi/decoderstatics
decoder statictis adding
2014-11-06 14:25:04 +08:00
zhuling13
45ef803e4d decoder statictis adding
mem

mem

decstatictis

time change

time change

set decTime=0
2014-11-05 22:01:32 -08:00
huili2
3d21825901 Merge pull request #1497 from dongzha/FixCabacBug
fix cabac bug in deltaqp
2014-11-06 12:19:13 +08:00
dongzha
ba0351f569 fix cabac bug in deltaqp 2014-11-06 10:51:18 +08:00
sijchen
63180b9b36 Merge pull request #1494 from huili2/ec_final_crash_UT
add a simple UT for debugging decoder crash
2014-11-05 14:24:54 +08:00
ruil2
8ed4e83e93 Merge pull request #1490 from sijchen/after_review
[Encoder] Fixing for large number of slices
2014-11-04 15:12:38 +08:00
huili2
32697b046b add a simple UT for debugging decoder crash 2014-11-03 23:05:34 -08:00
sijchen
b896faa47c Merge pull request #1493 from ruil2/printf
use %lld instead of %8d for longlong type
2014-11-04 14:30:36 +08:00
huili2
103fa5bbed enable cross IDR EC method 2014-11-03 22:11:49 -08:00
ruil2
fe55d5a208 update timestamp unit as millisecond 2014-11-04 11:28:35 +08:00
ruil2
18ed25fbb3 use %lld instead of %8d for longlong type 2014-11-04 10:37:23 +08:00
sijchen
783daf3d8a Merge pull request #1485 from ruil2/cabac_refine
pass each frame timestamp to codec
2014-11-04 09:31:07 +08:00
Sijia Chen
54c677cdd7 fixing OverallMbMap for slice_idx>255 and some log improvements 2014-11-04 09:19:36 +08:00
sijchen
08baf65251 Merge pull request #1488 from mstorsjo/fix-warnings
Fix warnings with gcc and MSVC
2014-11-04 09:13:55 +08:00
sijchen
ca1c357058 Merge pull request #1486 from mstorsjo/fix-pow-params
Don't try to use pow(int,int)
2014-11-04 09:13:46 +08:00
Martin Storsjö
8ffacf0918 Add casts to avoid warnings about comparison between signed and unsigned
This fixes warnings with gcc and msvc.
2014-11-03 11:28:40 +02:00
Martin Storsjö
0e9541247a Use the right data type for some local variables
pDecEngine->uiOffset is an uint64_t as well, and *pSliceNum
is uint32_t.

This fixes warnings about comparison between signed and unsigned
in gcc and msvc.
2014-11-03 11:28:35 +02:00
Martin Storsjö
c1b48640fb Don't try to use pow(int,int)
When building for android or older MSVC versions, this makes the build
fail, when it is ambiguous which pow() overload to use, when there
is no function matching pow(int, int).
2014-11-03 11:23:10 +02:00
ruil2
c5029ef275 Merge pull request #1484 from mstorsjo/fix-chmod
Remove the executable bit from new test sequences
2014-11-03 17:10:44 +08:00
ruil2
e061bb3fc9 pass each frame timestamp to codec 2014-11-03 17:05:38 +08:00
Martin Storsjö
2951a7f3a3 Remove variables that are set but not used
This fixes build warnings with gcc.
2014-11-03 10:52:02 +02:00
Martin Storsjö
7478714ac9 Remove the executable bit from new test sequences 2014-11-03 10:10:17 +02:00
sijchen
9ac2d2ad85 Merge pull request #1483 from dongzha/EnhanceDecConsole
modify console code for Demo interfaces test (this is reviewed at: https://rbcommons.com/s/OpenH264/r/890/)
2014-11-03 15:41:42 +08:00
sijchen
dbd4330508 Merge pull request #1482 from ruil2/cabac_refine
add setoption trace
2014-11-03 15:39:45 +08:00
sijchen
938f441751 Merge pull request #1480 from dongzha/cleanCabacDecoder
add decoder cabac support and add  UT
2014-11-03 15:38:24 +08:00
dong zhang
880e0fff06 modify macro STICK_STREAM_SIZE // For Demo interfaces test with track file of integrated frames
add macro NO_DELAY_DECODING	// For Demo interfaces test with no delay decoding
2014-11-03 11:26:14 +08:00
ruil2
c19db25043 add setoption trace 2014-11-03 10:37:07 +08:00
dong zhang
cf85745752 add decoder cabac support and add UT 2014-11-03 10:03:43 +08:00
sijchen
c7b5051738 Merge pull request #1469 from shihuade/APIUTV1.5.2
refactor --for BaseEncoderTest
2014-11-03 09:31:11 +08:00
ruil2
07bf80ba39 Merge pull request #1476 from mstorsjo/sps-constraints
Set constraint set 0 and 1 flags for non-scalable as well
2014-11-03 09:29:26 +08:00
Martin Storsjö
53e2f67e80 Set constraint set 0 and 1 flags for non-scalable as well
This allows decoders to know that a baseline stream doesn't
contain any of the features that aren't in the constrained
baseline subset.

Set the flags based on what profile we target.
2014-10-31 10:48:09 +02:00
ruil2
3abd54ca73 Merge pull request #1477 from mstorsjo/avoid-msvc-warnings
Avoid warnings when building with MSVC
2014-10-31 15:36:14 +08:00
ruil2
8e49898243 Merge pull request #1478 from sijchen/after_review61
[Encoder] add validation of slice parameters instead of assert
2014-10-31 15:34:37 +08:00
sijchen
66b1610114 Merge pull request #1472 from mstorsjo/fix-test-random
Make sure the width/height is large enough in SetOptionEncParamExt
2014-10-31 13:50:10 +08:00
Sijia Chen
24192cc235 add validation of slice parameters instead of assert 2014-10-30 18:31:50 +08:00
Martin Storsjö
655f3b43b6 Add a cast when converting from int64_t to float
This avoids a warning when building with MSVC.
2014-10-30 11:07:22 +02:00
Martin Storsjö
a291470072 Avoid warnings about converting from int to bool
MSVC used to warn about this.
2014-10-30 11:06:46 +02:00
Martin Storsjö
ec0d151879 Make sure the width/height is large enough in SetOptionEncParamExt
When using 4 downsampled layers, make sure the random width/height
is large enough that the downsampled layers don't have a zero size.

Since the value never will be too small now, there's no need to
use WELS_CLIP3 any longer.
2014-10-30 08:54:18 +02:00
dongzha
3b5448cbbc Merge pull request #1475 from ruil2/cabac_refine
Cabac refine
2014-10-30 13:39:46 +08:00
ruil2
055915d720 update windows project for table change 2014-10-30 12:47:26 +08:00
ruil2
100de97b49 move cabac table to common 2014-10-30 12:42:09 +08:00
sijchen
3a1f0a3d95 Merge pull request #1471 from mstorsjo/fix-warnings
Remove unused variables and an impossible condition
2014-10-30 09:10:08 +08:00
sijchen
41ed734674 Merge pull request #1473 from mstorsjo/silence-test-warnings
Silence warning logging while running tests that can produce errors
2014-10-30 09:08:55 +08:00
sijchen
b8e0a3fa38 Merge pull request #1474 from mstorsjo/use-proper-logging
Use WelsLog instead of fprintf for normal runtime errors
2014-10-30 08:21:28 +08:00
Martin Storsjö
7ce4da8a41 Use WelsLog instead of fprintf for normal runtime errors 2014-10-29 22:45:44 +02:00
Martin Storsjö
1c2940479d Silence warning logging while running tests that can produce errors 2014-10-29 22:44:40 +02:00
Martin Storsjö
2907cb2875 Remove an impossible condition
uiIntraPeriod is unsigned, and thus can't ever be negative.

The subtraction on the line above can't ever make the value wrap
around either, since param_.uiIntraPeriod % uiGOPSize always is
smaller than or equal to param_.uiIntraPeriod. Thus, the check
never is necessary even if the value would be signed either.

This fixes warnings when building with clang.
2014-10-29 22:07:21 +02:00
Martin Storsjö
a625dc836d Remove unused variables 2014-10-29 22:07:20 +02:00
Ethan Hugg
9be23c7821 Merge pull request #1470 from mstorsjo/fix-chmod
Remove the executable bit from the API docs
2014-10-29 11:43:13 -07:00
Martin Storsjö
7f645bf2f7 Remove the executable bit from the API docs 2014-10-29 20:33:26 +02:00
huashi
54c24dfd60 refactor --for BaseEncoderTest 2014-10-29 17:53:08 +08:00
ruil2
c83ab3bca1 Merge pull request #1462 from sijchen/after_review1
updated documents from v1.2
2014-10-29 17:17:38 +08:00
ruil2
58cc29225e Merge pull request #1463 from sijchen/after_review4
[Encoder] for reference selection under screen
2014-10-29 17:17:07 +08:00
sijchen
d3a971e32c Merge pull request #1466 from shihuade/APIUTV1.5
set option for ParamExt----random cases
2014-10-29 14:41:46 +08:00
ruil2
329ccd7d6f Merge pull request #1464 from mstorsjo/unify-msvc-nasm
Revert unrelated changes to MSVC project file nasm commands
2014-10-29 09:55:20 +08:00
ruil2
f10f6a788f Merge pull request #1467 from mstorsjo/cabac-stash-fix
Don't stash the cabac state into the SBitStringAux buffer
2014-10-29 09:28:06 +08:00
Martin Storsjö
f84560474c Revert unrelated changes to MSVC project file nasm commands
The cabac encoder commit accidentally changed some of the nasm
commands in the MSVC project file, that were previously
made consistent in b17e9bb32 and 7720f2cc5.
2014-10-28 23:38:14 +02:00
Martin Storsjö
f2c1395ab6 Remove the pBuffer parameter from the entropy encoder stash functions
The parameter didn't make sense since it only pointed to the
pSliceBsa field, which isn't what should be used to stash
the cabac context.
2014-10-28 14:59:50 +02:00
Martin Storsjö
9a9f92bcfe Don't stash the cabac state into the SBitStringAux buffer
This fixes crashes on some platforms, and fixes valgrind
errors.
2014-10-28 14:59:50 +02:00
huashi
26615fffd0 set option for ParamExt----random cases 2014-10-28 20:36:33 +08:00
Sijia Chen
a2d5254bc3 update VERSION in Makefile 2014-10-28 17:57:57 +08:00
Sijia Chen
4fab8c2ee7 for reference selection under screen:
1, ref_list_mgr_svc.cpp, Ln314: fix a wrong DeleteLTRFromLongList which should not be used under screen strategy
2, ref_list_mgr_svc.cpp, Ln910: remove the frame which is furthest in distance to the current frame in ref list
3, wels_preprocess.cpp: use scene LTR ref list when the current frame is scene LTR
-, ref_list_mgr_svc.cpp, Ln811: add DEBUG trace
reviewed at: https://rbcommons.com/s/OpenH264/r/870/
2014-10-28 16:58:59 +08:00
sijchen
292d2511e2 Merge pull request #1457 from ruil2/enc_cabac
add encoder cabac support
2014-10-28 16:51:56 +08:00
Sijia Chen
4292f91ae5 add updated documents from v1.2 2014-10-28 13:55:37 +08:00
Ethan Hugg
5cefad2d3f Merge pull request #1460 from zaheerm/pkgconfig
Add .pc file generation to PHONY targets
2014-10-27 10:48:30 -07:00
Ethan Hugg
fcb84f5fb6 Merge pull request #1459 from tp-m/pkgconfig-install-fix
Fix openh264.pc file installation
2014-10-27 10:01:41 -07:00
Zaheer Abbas Merali
fe621b92bf Add .pc file generation to PHONY targets as version change in Makefile needs to cause a rebuild. 2014-10-27 10:00:13 -07:00
Tim-Philipp Müller
1ad797a81e Fix openh264.pc file installation
If there's no pkgconfig subdirectory yet in our
install prefix, create it first, otherwise we'll
end up with a file called 'pkgconfig' instead.
2014-10-27 16:22:58 +00:00
Ethan Hugg
9a72378c34 Merge pull request #1455 from zaheerm/pkgconfig
Add pkg-config file.
2014-10-27 09:01:18 -07:00
ruil2
ec901a14d6 Merge pull request #1456 from dongzha/fixRCOverFlow
fix Rc int32_t bitrate overflow
2014-10-27 13:08:54 +08:00
ruil2
abc01e6b81 add encoder cabac support 2014-10-27 13:06:33 +08:00
dong zhang
d3c8ade8d0 fix Rc int32_t bitrate overflow 2014-10-27 09:54:44 +08:00
Zaheer Abbas Merali
46d30cd33c Add pkg-config file. 2014-10-26 15:26:52 -07:00
ruil2
2dbb757d30 Merge pull request #1451 from sijchen/for_format
Fixes and change naming
2014-10-24 15:18:55 +08:00
sijchen
34cb0d60aa Merge pull request #1450 from mstorsjo/avoid-warnings
Add casts to avoid warnings about comparison between signed and unsigned
2014-10-24 14:41:51 +08:00
Sijia Chen
6a2a4efef6 fix names to keep consistent of style
improve UT to cover more cases under GetStatistics
2014-10-24 14:39:50 +08:00
Sijia Chen
ea9b80adb3 fix a wrong range clip 2014-10-24 14:12:53 +08:00
sijchen
468fce0887 Merge pull request #1448 from sijchen/for_format
roll back the file which is mis-formatted by astyle
2014-10-24 14:12:40 +08:00
Martin Storsjö
f0c6891627 Add casts to avoid warnings about comparison between signed and unsigned 2014-10-24 09:05:32 +03:00
Sijia Chen
50fd617e86 roll back the file which is mis-formatted by astyle 2014-10-24 13:04:35 +08:00
ruil2
ac290d65c7 Merge pull request #1446 from sijchen/for_format
[Encoder] fix a small range of slice idx
2014-10-24 12:50:07 +08:00
220 changed files with 26847 additions and 14903 deletions

3
.gitignore vendored
View File

@@ -44,3 +44,6 @@ testbin/test_vd_rc.264
testbin/test_vd_rc.yuv
testbin/test.264
testbin/test.yuv
# pkg-config file
*.pc

View File

@@ -22,10 +22,14 @@ V=Yes
PREFIX=/usr/local
SHARED=-shared
OBJ=o
DESTDIR=
SHAREDLIB_DIR=$(PREFIX)/lib
PROJECT_NAME=openh264
MODULE_NAME=gmpopenh264
GMP_API_BRANCH=master
GMP_API_BRANCH=Firefox38
CCASFLAGS=$(CFLAGS)
VERSION=1.4
STATIC_LDFLAGS=-lstdc++
ifeq (,$(wildcard $(SRC_PATH)gmp-api))
HAVE_GMP_API=No
@@ -44,7 +48,7 @@ ifeq ($(BUILDTYPE), Release)
CFLAGS += $(CFLAGS_OPT)
USE_ASM = Yes
else
CFLAGS = $(CFLAGS_DEBUG)
CFLAGS += $(CFLAGS_DEBUG)
USE_ASM = No
endif
@@ -53,10 +57,11 @@ CFLAGS += -fsanitize=address
LDFLAGS += -fsanitize=address
endif
SHAREDLIBVERSION=0
include $(SRC_PATH)build/platform-$(OS).mk
CFLAGS +=
CFLAGS += -DGENERATED_VERSION_HEADER
LDFLAGS +=
ifeq (Yes, $(GCOV))
@@ -101,6 +106,7 @@ GTEST_INCLUDES += \
CODEC_UNITTEST_INCLUDES += \
-I$(SRC_PATH)gtest/include \
-I$(SRC_PATH)codec/common/inc \
-I$(SRC_PATH)test
CONSOLE_COMMON_INCLUDES += \
-I$(SRC_PATH)codec/console/common/inc
@@ -115,14 +121,20 @@ H264ENC_DEPS = $(LIBPREFIX)encoder.$(LIBSUFFIX) $(LIBPREFIX)processing.$(LIBSUFF
CODEC_UNITTEST_LDFLAGS = $(LINK_LOCAL_DIR) $(call LINK_LIB,gtest) $(call LINK_LIB,decoder) $(call LINK_LIB,encoder) $(call LINK_LIB,processing) $(call LINK_LIB,common) $(CODEC_UNITTEST_LDFLAGS_SUFFIX)
CODEC_UNITTEST_DEPS = $(LIBPREFIX)gtest.$(LIBSUFFIX) $(LIBPREFIX)decoder.$(LIBSUFFIX) $(LIBPREFIX)encoder.$(LIBSUFFIX) $(LIBPREFIX)processing.$(LIBSUFFIX) $(LIBPREFIX)common.$(LIBSUFFIX)
DECODER_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(DECODER_INCLUDES) -I$(SRC_PATH)test -I$(SRC_PATH)test/decoder
ENCODER_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(ENCODER_INCLUDES) -I$(SRC_PATH)test -I$(SRC_PATH)test/encoder
PROCESSING_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(PROCESSING_INCLUDES) -I$(SRC_PATH)test -I$(SRC_PATH)test/processing
API_TEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) -I$(SRC_PATH)test -I$(SRC_PATH)test/api
COMMON_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(DECODER_INCLUDES) -I$(SRC_PATH)test -I$(SRC_PATH)test/common
DECODER_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(DECODER_INCLUDES)
ENCODER_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(ENCODER_INCLUDES)
PROCESSING_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES) $(PROCESSING_INCLUDES)
API_TEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES)
COMMON_UNITTEST_INCLUDES += $(CODEC_UNITTEST_INCLUDES)
MODULE_INCLUDES += -I$(SRC_PATH)gmp-api
.PHONY: test gtest-bootstrap clean
DECODER_UNITTEST_CFLAGS += $(CODEC_UNITTEST_CFLAGS)
ENCODER_UNITTEST_CFLAGS += $(CODEC_UNITTEST_CFLAGS)
PROCESSING_UNITTEST_CFLAGS += $(CODEC_UNITTEST_CFLAGS)
API_TEST_CFLAGS += $(CODEC_UNITTEST_CFLAGS)
COMMON_UNITTEST_CFLAGS += $(CODEC_UNITTEST_CFLAGS)
.PHONY: test gtest-bootstrap clean $(PROJECT_NAME).pc $(PROJECT_NAME)-static.pc
all: libraries binaries
@@ -136,7 +148,7 @@ clean:
ifeq (android,$(OS))
clean: clean_Android
endif
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(OBJS:.$(OBJ)=.obj) $(LIBRARIES) $(BINARIES) *.lib *.a *.dylib *.dll *.so
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(OBJS:.$(OBJ)=.obj) $(LIBRARIES) $(BINARIES) *.lib *.a *.dylib *.dll *.so *.exe *.pdb *.exp *.pc
gmp-bootstrap:
if [ ! -d gmp-api ] ; then git clone https://github.com/mozilla/gmp-api gmp-api ; fi
@@ -183,45 +195,70 @@ 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)
install-headers:
mkdir -p $(PREFIX)/include/wels
install -m 644 codec/api/svc/codec*.h $(PREFIX)/include/wels
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
ifneq ($(EXTRA_LIBRARY),)
install -m 644 $(EXTRA_LIBRARY) $(PREFIX)/lib
ifneq ($(SHAREDLIBSUFFIXVER),$(SHAREDLIBSUFFIX))
$(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX): $(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIXVER)
$(QUIET)ln -sfn $+ $@
endif
install: install-static install-shared
$(PROJECT_NAME).pc: $(PROJECT_NAME).pc.in
@sed -e 's;@prefix@;$(PREFIX);' -e 's;@VERSION@;$(VERSION);' -e 's;@LIBS@;;' -e 's;@LIBS_PRIVATE@;$(STATIC_LDFLAGS);' < $(PROJECT_NAME).pc.in > $@
$(PROJECT_NAME)-static.pc: $(PROJECT_NAME).pc.in
@sed -e 's;@prefix@;$(PREFIX);' -e 's;@VERSION@;$(VERSION);' -e 's;@LIBS@;$(STATIC_LDFLAGS);' -e 's;@LIBS_PRIVATE@;;' < $(PROJECT_NAME).pc.in > $@
install-headers:
mkdir -p $(DESTDIR)/$(PREFIX)/include/wels
install -m 644 codec/api/svc/codec*.h $(DESTDIR)/$(PREFIX)/include/wels
install-static-lib: $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX) install-headers
mkdir -p $(DESTDIR)/$(PREFIX)/lib
install -m 644 $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX) $(DESTDIR)/$(PREFIX)/lib
install-static: install-static-lib $(PROJECT_NAME)-static.pc
mkdir -p $(DESTDIR)/$(PREFIX)/lib/pkgconfig
install -m 644 $(PROJECT_NAME)-static.pc $(DESTDIR)/$(PREFIX)/lib/pkgconfig/$(PROJECT_NAME).pc
install-shared: $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX) install-headers $(PROJECT_NAME).pc
mkdir -p $(DESTDIR)/$(SHAREDLIB_DIR)
install -m 755 $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIXVER) $(DESTDIR)/$(SHAREDLIB_DIR)
if [ "$(SHAREDLIBSUFFIXVER)" != "$(SHAREDLIBSUFFIX)" ]; then \
cp -a $(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX) $(DESTDIR)/$(SHAREDLIB_DIR); \
fi
mkdir -p $(DESTDIR)/$(PREFIX)/lib/pkgconfig
install -m 644 $(PROJECT_NAME).pc $(DESTDIR)/$(PREFIX)/lib/pkgconfig
ifneq ($(EXTRA_LIBRARY),)
install -m 644 $(EXTRA_LIBRARY) $(DESTDIR)/$(PREFIX)/lib
endif
install: install-static-lib install-shared
@:
ifeq ($(HAVE_GTEST),Yes)

View File

@@ -38,13 +38,13 @@ OS Support
- Windows 64-bit and 32-bit
- Mac OS X 64-bit and 32-bit
- Linux 64-bit and 32-bit
- Android 32-bit
- Android 64-bit and 32-bit
- iOS 64-bit and 32-bit
Processor Support
-----------------
- Intel x86 optionally with MMX/SSE (no AVX yet, help is welcome)
- ARMv7 optionally with NEON
- ARMv7 optionally with NEON, AArch64 optionally with NEON
- Any architecture using C/C++ fallback functions
Building the Library

View File

@@ -1,5 +1,57 @@
Releases
-----------
v1.4.0
------
- Decoder new interface of DecodeFrameNoDelay
- Added new encoder and decoder statistics
- Added option for generating pdb in windows builds
- Added new rate control mode (RC_TIMESTAMP_MODE) for inconstant frame rate input
- Added new Sps/Pps strategies for real-time video
— Added support for simulcast avc
- Improvements in code structure, assembly, input parameter checking, logging, UT and comments
- In gmp-openh264, return decoder error correctly and other fixes
- Decoder bug fixes when for Error Concealment disabled
- Bug fixes for ParseOnly functions
- Bug fixes for encoding large frame size (>32767MBs)
- Fixes to avoid valgrind warnings, potential crash and calculation overflow
-----------
v1.3.1
------
- Fixed and enhanced protection to avoid crash when reading lossy bitstreams
- Adjust the default mode of Error Concealment used by gmp-openh264
-----------
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 +67,26 @@ Binaries
These binary releases are distributed under this license:
http://www.openh264.org/BINARY_LICENSE.txt
v1.3.0
------
http://ciscobinary.openh264.org/libopenh264-1.3.0-android19.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.3.0-linux32.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.3.0-linux64.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.3.0-osx32.dylib.bz2
http://ciscobinary.openh264.org/libopenh264-1.3.0-osx64.dylib.bz2
http://ciscobinary.openh264.org/openh264-1.3.0-win32msvc.dll.bz2
http://ciscobinary.openh264.org/openh264-1.3.0-win64msvc.dll.bz2
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

View File

@@ -10,7 +10,7 @@ else
endif
ifeq ($(ASM_ARCH), arm)
CCAS = gas-preprocessor.pl -as-type armasm -force-thumb -- armasm
CCASFLAGS = -nologo -DHAVE_NEON
CCASFLAGS = -nologo -DHAVE_NEON -ignore 4509
endif
CC=cl
@@ -22,7 +22,7 @@ CXX_O=-Fo$@
# it unconditionally. The same issue can also be worked around by adding
# -DGTEST_HAS_TR1_TUPLE=0 instead, but we prefer this version since it
# matches what gtest itself does.
CFLAGS += -nologo -W3 -EHsc -fp:precise -Zc:wchar_t -Zc:forScope -D_VARIADIC_MAX=10
CFLAGS += -nologo -Fd$(PROJECT_NAME).pdb -W3 -EHsc -fp:precise -Zc:wchar_t -Zc:forScope -D_VARIADIC_MAX=10
CXX_LINK_O=-nologo -Fe$@
AR_OPTS=-nologo -out:$@
CFLAGS_OPT=-O2 -Ob1 -Oy- -Zi -GF -Gm- -GS -Gy -DNDEBUG
@@ -35,7 +35,11 @@ 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=-Fd$(PROJECT_NAME).pdb -link -def:openh264.def -implib:$(EXTRA_LIBRARY)
STATIC_LDFLAGS=
CODEC_UNITTEST_CFLAGS=-D_CRT_SECURE_NO_WARNINGS

View File

@@ -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)
@@ -9,9 +12,6 @@ ifeq ($(ARCH), arm)
LDFLAGS += -march=armv7-a -Wl,--fix-cortex-a8
APP_ABI = armeabi-v7a
endif
ifeq (Yes, $(USE_ASM))
ASMFLAGS += -march=armv7-a -mfpu=neon
endif
else ifeq ($(ARCH), arm64)
APP_ABI = arm64-v8a
else ifeq ($(ARCH), x86)

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -1,4 +1,6 @@
/*!
*@page License
*
* \copy
* Copyright (c) 2013, Cisco Systems
* All rights reserved.
@@ -50,73 +52,383 @@ 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 = DecodeFrameNoDelay(pBuf, iSize, pData, &sDstBufInfo);
* //or
* 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.iNalNum > 0){
* Hardware decoding sDstParseInfo;
* }
* //no-delay decoding can be realized by directly calling DecodeFrameNoDelay(), which is the recommended usage.
* //no-delay decoding can also be realized by directly calling DecodeFrame2() 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 (&param, 0, sizeof (SEncParamBase));
* param.iUsageType = usageType;
* param.fMaxFrameRate = frameRate;
* param.iPicWidth = width;
* param.iPicHeight = height;
* param.iTargetBitrate = 5000000;
* encoder_->Initialize (&param);
* @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 (&param);
* 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 (&param);
* 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 DecodeFrameNoDelay() (4 parameters input),
* whatever the function return value is, the output data
* of I420 format will only be available when pDstInfo->iBufferStatus == 1,.
* This function will parse and reconstruct the input frame immediately if it is complete
* It is recommended as the main decoding function for H.264/AVC format input
* @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 DecodeFrameNoDelay (const unsigned char* pSrc,
const int iSrcLen,
unsigned char** ppDst,
SBufferInfo* pDstInfo) = 0;
/**
* @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 +438,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() {}
};
@@ -172,6 +492,11 @@ DECODING_STATE (*DecodeFrame) (ISVCDecoder*, const unsigned char* pSrc,
int* iWidth,
int* iHeight);
DECODING_STATE (*DecodeFrameNoDelay) (ISVCDecoder*, const unsigned char* pSrc,
const int iSrcLen,
unsigned char** ppDst,
SBufferInfo* pDstInfo);
DECODING_STATE (*DecodeFrame2) (ISVCDecoder*, const unsigned char* pSrc,
const int iSrcLen,
unsigned char** ppDst,
@@ -197,13 +522,53 @@ 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
* Note, old versions of Mingw (GCC < 4.7) are buggy and use an
* incorrect/different ABI for calling this function, making it
* incompatible with MSVC builds.
* @return The linked codec version
*/
OpenH264Version WelsGetCodecVersion (void);
/** @brief Get codec version
* @param pVersion struct to fill in with the version
*/
void WelsGetCodecVersionEx (OpenH264Version *pVersion);
#ifdef __cplusplus
}
#endif

View File

@@ -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,157 @@
#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 +205,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 +226,88 @@ 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_TIMESTAMP_MODE = 3, //rate control based timestamp
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,173 @@ 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 for real-time communication
SCREEN_CONTENT_REAL_TIME, ///< screen content signal
CAMERA_VIDEO_NON_REAL_TIME
} 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;
/**
* @brief Enumulate for the stategy of SPS/PPS strategy
*/
typedef enum {
CONSTANT_ID = 0, ///< constant id in SPS/PPS
INCREASING_ID = 0x01, ///< SPS/PPS id increases at each IDR
SPS_LISTING = 0x02, ///< using SPS in the existing list if possible
SPS_LISTING_AND_PPS_INCREASING = 0x03,
SPS_PPS_LISTING = 0x06,
} EParameterSetStrategy;
// 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
EParameterSetStrategy
eSpsPpsIdStrategy; ///< different stategy in adjust ID in SPS/PPS: 0- constant ID, 1-additional ID, 6-mapping and additional
bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL
bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI
bool bSimulcastAVC; ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVC -- coming soon
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 +503,168 @@ 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
long long iStatisticsTs; ///< Timestamp of updating the statistics
} 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
int iSpsReportErrorNum; ///< number of Sps Invalid report
int iSubSpsReportErrorNum; ///< number of SubSps Invalid report
int iPpsReportErrorNum; ///< number of Pps Invalid report
int iSpsNoExistNalNum; ///< number of Sps NoExist Nal
int iSubSpsNoExistNalNum; ///< number of SubSps NoExist Nal
int iPpsNoExistNalNum; ///< number of Pps NoExist Nal
} SDecoderStatistics; // in building, coming soon
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__

View File

@@ -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,
@@ -105,84 +121,93 @@ enum ENalPriority {
#define FRAME_NUM_PARAM_SET (-1)
#define FRAME_NUM_IDR 0
/**
* @brief eDeblockingIdc
*/
enum {
DEBLOCKING_IDC_0 = 0,
DEBLOCKING_IDC_1 = 1,
DEBLOCKING_IDC_2 = 2
};
#define DEBLOCKING_OFFSET (6)
#define DEBLOCKING_OFFSET_MINUS (-6)
/* 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
View 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,4,0,0};
static const char* const g_strCodecVer = "OpenH264 version:1.4.0.0";
#define OPENH264_MAJOR (1)
#define OPENH264_MINOR (4)
#define OPENH264_REVISION (0)
#define OPENH264_RESERVED (0)
#endif // CODEC_VER_H

View File

@@ -34,7 +34,7 @@ JNIEXPORT void JNICALL Java_com_wels_enc_WelsEncTest_DoEncoderTest
/**************** Add the native codes/API *****************/
char* argv[2];
int argc = 2;
argv[0] = (char*) ("decConsole.exe");
argv[0] = (char*) ("encConsole.exe");
argv[1] = (char*) ((*env).GetStringUTFChars (jsFileNameIn, NULL));
LOGI ("Start to run JNI module!+++");
EncMain (argc, argv);

View 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* const g_strCodecVer = \"OpenH264 version:$1\";" >>codec_ver.h
#if [ "$2"x = ""x ]; then
#echo "static const char* const g_strCodecBuildNum = \"OpenH264 revision:$revision\";" >> codec_ver.h
#else
#echo "static const char* const 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

View File

@@ -19,6 +19,8 @@
4CE443D918B722CD0017DF25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CE443D818B722CD0017DF25 /* Foundation.framework */; };
53C1C9BC193F0FB000404D8F /* expand_pic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53C1C9BB193F0FB000404D8F /* expand_pic.cpp */; };
5BA8F2C019603F5F00011CE4 /* common_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BA8F2BF19603F5F00011CE4 /* common_tables.cpp */; };
5BD896BA1A7B839B00D32B7D /* memory_align.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD896B91A7B839B00D32B7D /* memory_align.cpp */; };
5BDD15ED1A79027600B6CA2E /* mc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BDD15EC1A79027600B6CA2E /* mc.cpp */; };
F0B204F918FD23BF005DA23F /* copy_mb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F0B204F818FD23BF005DA23F /* copy_mb.cpp */; };
F556A8241906673900E156A8 /* arm_arch64_common_macro.S in Sources */ = {isa = PBXBuildFile; fileRef = F556A8221906673900E156A8 /* arm_arch64_common_macro.S */; };
F556A8251906673900E156A8 /* expand_picture_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F556A8231906673900E156A8 /* expand_picture_aarch64_neon.S */; };
@@ -54,7 +56,6 @@
4C3406BA18D96EA600DFA14A /* deblocking_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deblocking_common.h; sourceTree = "<group>"; };
4C3406BD18D96EA600DFA14A /* ls_defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ls_defines.h; sourceTree = "<group>"; };
4C3406BE18D96EA600DFA14A /* macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macros.h; sourceTree = "<group>"; };
4C3406BF18D96EA600DFA14A /* mc_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mc_common.h; sourceTree = "<group>"; };
4C3406C018D96EA600DFA14A /* measure_time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = measure_time.h; sourceTree = "<group>"; };
4C3406C118D96EA600DFA14A /* typedefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typedefs.h; sourceTree = "<group>"; };
4C3406C218D96EA600DFA14A /* WelsThreadLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WelsThreadLib.h; sourceTree = "<group>"; };
@@ -68,8 +69,13 @@
4CE443E918B722CD0017DF25 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
53C1C9BA193F0F9E00404D8F /* expand_pic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = expand_pic.h; sourceTree = "<group>"; };
53C1C9BB193F0FB000404D8F /* expand_pic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = expand_pic.cpp; sourceTree = "<group>"; };
5B9196F91A7F8BA40075D641 /* wels_const_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wels_const_common.h; sourceTree = "<group>"; };
5BA8F2BE19603F3500011CE4 /* wels_common_defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wels_common_defs.h; sourceTree = "<group>"; };
5BA8F2BF19603F5F00011CE4 /* common_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = common_tables.cpp; sourceTree = "<group>"; };
5BD896B81A7B837700D32B7D /* memory_align.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory_align.h; sourceTree = "<group>"; };
5BD896B91A7B839B00D32B7D /* memory_align.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory_align.cpp; sourceTree = "<group>"; };
5BDD15EB1A79026A00B6CA2E /* mc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mc.h; sourceTree = "<group>"; };
5BDD15EC1A79027600B6CA2E /* mc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mc.cpp; sourceTree = "<group>"; };
F0B204F718FD23B6005DA23F /* copy_mb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = copy_mb.h; sourceTree = "<group>"; };
F0B204F818FD23BF005DA23F /* copy_mb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = copy_mb.cpp; sourceTree = "<group>"; };
F556A8221906673900E156A8 /* arm_arch64_common_macro.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = arm_arch64_common_macro.S; path = arm64/arm_arch64_common_macro.S; sourceTree = "<group>"; };
@@ -123,10 +129,12 @@
4C3406BA18D96EA600DFA14A /* deblocking_common.h */,
4C3406BD18D96EA600DFA14A /* ls_defines.h */,
4C3406BE18D96EA600DFA14A /* macros.h */,
4C3406BF18D96EA600DFA14A /* mc_common.h */,
5BDD15EB1A79026A00B6CA2E /* mc.h */,
4C3406C018D96EA600DFA14A /* measure_time.h */,
5BD896B81A7B837700D32B7D /* memory_align.h */,
4C3406C118D96EA600DFA14A /* typedefs.h */,
5BA8F2BE19603F3500011CE4 /* wels_common_defs.h */,
5B9196F91A7F8BA40075D641 /* wels_const_common.h */,
4C3406C218D96EA600DFA14A /* WelsThreadLib.h */,
);
path = inc;
@@ -143,6 +151,8 @@
4C3406C518D96EA600DFA14A /* crt_util_safe_x.cpp */,
53C1C9BB193F0FB000404D8F /* expand_pic.cpp */,
4C3406C618D96EA600DFA14A /* deblocking_common.cpp */,
5BDD15EC1A79027600B6CA2E /* mc.cpp */,
5BD896B91A7B839B00D32B7D /* memory_align.cpp */,
4C3406C818D96EA600DFA14A /* WelsThreadLib.cpp */,
);
path = src;
@@ -253,9 +263,11 @@
F5B8D82D190757290037849A /* mc_aarch64_neon.S in Sources */,
4C3406C918D96EA600DFA14A /* arm_arch_common_macro.S in Sources */,
F556A8241906673900E156A8 /* arm_arch64_common_macro.S in Sources */,
5BDD15ED1A79027600B6CA2E /* mc.cpp in Sources */,
F5AC94FF193EB7D800F58154 /* deblocking_aarch64_neon.S in Sources */,
4C3406CE18D96EA600DFA14A /* crt_util_safe_x.cpp in Sources */,
F791965919D3BE2200F60C6B /* intra_pred_common.cpp in Sources */,
5BD896BA1A7B839B00D32B7D /* memory_align.cpp in Sources */,
4C3406CF18D96EA600DFA14A /* deblocking_common.cpp in Sources */,
5BA8F2C019603F5F00011CE4 /* common_tables.cpp in Sources */,
F791965419D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S in Sources */,
@@ -368,6 +380,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 +412,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;

View File

@@ -20,8 +20,6 @@
4CE4469318BC5EAB0017DF25 /* fmo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467018BC5EAA0017DF25 /* fmo.cpp */; };
4CE4469418BC5EAB0017DF25 /* get_intra_predictor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467118BC5EAA0017DF25 /* get_intra_predictor.cpp */; };
4CE4469518BC5EAB0017DF25 /* manage_dec_ref.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467218BC5EAA0017DF25 /* manage_dec_ref.cpp */; };
4CE4469618BC5EAB0017DF25 /* mc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467318BC5EAA0017DF25 /* mc.cpp */; };
4CE4469718BC5EAB0017DF25 /* mem_align.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467418BC5EAA0017DF25 /* mem_align.cpp */; };
4CE4469818BC5EAB0017DF25 /* memmgr_nal_unit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467518BC5EAA0017DF25 /* memmgr_nal_unit.cpp */; };
4CE4469918BC5EAB0017DF25 /* mv_pred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467618BC5EAA0017DF25 /* mv_pred.cpp */; };
4CE4469A18BC5EAB0017DF25 /* parse_mb_syn_cavlc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4467718BC5EAA0017DF25 /* parse_mb_syn_cavlc.cpp */; };
@@ -30,8 +28,9 @@
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 */; };
9AED66591946A203009A3567 /* utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AED66581946A203009A3567 /* utils.cpp */; };
F0B204FC18FD23D8005DA23F /* error_concealment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F0B204FB18FD23D8005DA23F /* error_concealment.cpp */; };
@@ -71,8 +70,6 @@
4CE4465318BC5EAA0017DF25 /* get_intra_predictor.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = get_intra_predictor.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
4CE4465418BC5EAA0017DF25 /* manage_dec_ref.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = manage_dec_ref.h; sourceTree = "<group>"; };
4CE4465518BC5EAA0017DF25 /* mb_cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mb_cache.h; sourceTree = "<group>"; };
4CE4465618BC5EAA0017DF25 /* mc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mc.h; sourceTree = "<group>"; };
4CE4465718BC5EAA0017DF25 /* mem_align.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mem_align.h; sourceTree = "<group>"; };
4CE4465818BC5EAA0017DF25 /* memmgr_nal_unit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memmgr_nal_unit.h; sourceTree = "<group>"; };
4CE4465918BC5EAA0017DF25 /* mv_pred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mv_pred.h; sourceTree = "<group>"; };
4CE4465A18BC5EAA0017DF25 /* nal_prefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nal_prefix.h; sourceTree = "<group>"; };
@@ -97,8 +94,6 @@
4CE4467018BC5EAA0017DF25 /* fmo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fmo.cpp; sourceTree = "<group>"; };
4CE4467118BC5EAA0017DF25 /* get_intra_predictor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = get_intra_predictor.cpp; sourceTree = "<group>"; };
4CE4467218BC5EAA0017DF25 /* manage_dec_ref.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = manage_dec_ref.cpp; sourceTree = "<group>"; };
4CE4467318BC5EAA0017DF25 /* mc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mc.cpp; sourceTree = "<group>"; tabWidth = 1; usesTabs = 0; wrapsLines = 1; };
4CE4467418BC5EAA0017DF25 /* mem_align.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mem_align.cpp; sourceTree = "<group>"; };
4CE4467518BC5EAA0017DF25 /* memmgr_nal_unit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memmgr_nal_unit.cpp; sourceTree = "<group>"; };
4CE4467618BC5EAA0017DF25 /* mv_pred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mv_pred.cpp; sourceTree = "<group>"; };
4CE4467718BC5EAA0017DF25 /* parse_mb_syn_cavlc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_mb_syn_cavlc.cpp; sourceTree = "<group>"; };
@@ -109,9 +104,11 @@
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>"; };
9AED66551946A1DE009A3567 /* welsCodecTrace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = welsCodecTrace.cpp; path = ../../../common/src/welsCodecTrace.cpp; sourceTree = "<group>"; };
9AED66571946A1EB009A3567 /* welsCodecTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = welsCodecTrace.h; path = ../../../common/inc/welsCodecTrace.h; sourceTree = "<group>"; };
9AED66581946A203009A3567 /* utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = utils.cpp; path = ../../../common/src/utils.cpp; sourceTree = "<group>"; };
@@ -191,8 +188,9 @@
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 */,
4CE4464518BC5EAA0017DF25 /* as264_common.h */,
4CE4464618BC5EAA0017DF25 /* au_parser.h */,
@@ -210,8 +208,6 @@
4CE4465318BC5EAA0017DF25 /* get_intra_predictor.h */,
4CE4465418BC5EAA0017DF25 /* manage_dec_ref.h */,
4CE4465518BC5EAA0017DF25 /* mb_cache.h */,
4CE4465618BC5EAA0017DF25 /* mc.h */,
4CE4465718BC5EAA0017DF25 /* mem_align.h */,
4CE4465818BC5EAA0017DF25 /* memmgr_nal_unit.h */,
4CE4465918BC5EAA0017DF25 /* mv_pred.h */,
4CE4465A18BC5EAA0017DF25 /* nal_prefix.h */,
@@ -232,8 +228,9 @@
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 */,
4CE4466718BC5EAA0017DF25 /* au_parser.cpp */,
4CE4466818BC5EAA0017DF25 /* bit_stream.cpp */,
@@ -246,8 +243,6 @@
4CE4467018BC5EAA0017DF25 /* fmo.cpp */,
4CE4467118BC5EAA0017DF25 /* get_intra_predictor.cpp */,
4CE4467218BC5EAA0017DF25 /* manage_dec_ref.cpp */,
4CE4467318BC5EAA0017DF25 /* mc.cpp */,
4CE4467418BC5EAA0017DF25 /* mem_align.cpp */,
4CE4467518BC5EAA0017DF25 /* memmgr_nal_unit.cpp */,
4CE4467618BC5EAA0017DF25 /* mv_pred.cpp */,
4CE4467718BC5EAA0017DF25 /* parse_mb_syn_cavlc.cpp */,
@@ -346,15 +341,15 @@
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 */,
4CE4469118BC5EAB0017DF25 /* decoder_data_tables.cpp in Sources */,
4CE4469718BC5EAB0017DF25 /* mem_align.cpp in Sources */,
9ABF4382193EB60900A6BD61 /* expand_pic.cpp in Sources */,
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 */,
@@ -363,7 +358,6 @@
4CBC1B81194AC4E100214D9E /* intra_pred_aarch64_neon.S in Sources */,
4CE4469018BC5EAB0017DF25 /* decoder_core.cpp in Sources */,
4CE447AE18BC6BE90017DF25 /* intra_pred_neon.S in Sources */,
4CE4469618BC5EAB0017DF25 /* mc.cpp in Sources */,
4CE4469C18BC5EAB0017DF25 /* rec_mb.cpp in Sources */,
4CE4468B18BC5EAB0017DF25 /* bit_stream.cpp in Sources */,
4CE4468D18BC5EAB0017DF25 /* decode_mb_aux.cpp in Sources */,

View File

@@ -24,9 +24,7 @@
4CE4471318BC605C0017DF25 /* encoder_data_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446E218BC605C0017DF25 /* encoder_data_tables.cpp */; };
4CE4471418BC605C0017DF25 /* encoder_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446E318BC605C0017DF25 /* encoder_ext.cpp */; };
4CE4471618BC605C0017DF25 /* get_intra_predictor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446E518BC605C0017DF25 /* get_intra_predictor.cpp */; };
4CE4471718BC605C0017DF25 /* mc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446E618BC605C0017DF25 /* mc.cpp */; };
4CE4471818BC605C0017DF25 /* md.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446E718BC605C0017DF25 /* md.cpp */; };
4CE4471918BC605C0017DF25 /* memory_align.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446E818BC605C0017DF25 /* memory_align.cpp */; };
4CE4471A18BC605C0017DF25 /* mv_pred.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446E918BC605C0017DF25 /* mv_pred.cpp */; };
4CE4471B18BC605C0017DF25 /* nal_encap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446EA18BC605C0017DF25 /* nal_encap.cpp */; };
4CE4471C18BC605C0017DF25 /* picture_handle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE446EB18BC605C0017DF25 /* picture_handle.cpp */; };
@@ -51,6 +49,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 */
@@ -91,9 +91,7 @@
4CE446B518BC605C0017DF25 /* extern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = extern.h; sourceTree = "<group>"; };
4CE446B618BC605C0017DF25 /* get_intra_predictor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = get_intra_predictor.h; sourceTree = "<group>"; };
4CE446B718BC605C0017DF25 /* mb_cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mb_cache.h; sourceTree = "<group>"; };
4CE446B818BC605C0017DF25 /* mc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mc.h; sourceTree = "<group>"; };
4CE446B918BC605C0017DF25 /* md.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md.h; sourceTree = "<group>"; };
4CE446BA18BC605C0017DF25 /* memory_align.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory_align.h; sourceTree = "<group>"; };
4CE446BB18BC605C0017DF25 /* mt_defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mt_defs.h; sourceTree = "<group>"; };
4CE446BC18BC605C0017DF25 /* mv_pred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mv_pred.h; sourceTree = "<group>"; };
4CE446BD18BC605C0017DF25 /* nal_encap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nal_encap.h; sourceTree = "<group>"; };
@@ -133,9 +131,7 @@
4CE446E218BC605C0017DF25 /* encoder_data_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = encoder_data_tables.cpp; sourceTree = "<group>"; };
4CE446E318BC605C0017DF25 /* encoder_ext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = encoder_ext.cpp; sourceTree = "<group>"; };
4CE446E518BC605C0017DF25 /* get_intra_predictor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = get_intra_predictor.cpp; sourceTree = "<group>"; };
4CE446E618BC605C0017DF25 /* mc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mc.cpp; sourceTree = "<group>"; };
4CE446E718BC605C0017DF25 /* md.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = md.cpp; sourceTree = "<group>"; };
4CE446E818BC605C0017DF25 /* memory_align.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory_align.cpp; sourceTree = "<group>"; };
4CE446E918BC605C0017DF25 /* mv_pred.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mv_pred.cpp; sourceTree = "<group>"; };
4CE446EA18BC605C0017DF25 /* nal_encap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nal_encap.cpp; sourceTree = "<group>"; };
4CE446EB18BC605C0017DF25 /* picture_handle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = picture_handle.cpp; sourceTree = "<group>"; };
@@ -164,6 +160,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 +254,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 */,
@@ -268,9 +270,7 @@
4CE446B518BC605C0017DF25 /* extern.h */,
4CE446B618BC605C0017DF25 /* get_intra_predictor.h */,
4CE446B718BC605C0017DF25 /* mb_cache.h */,
4CE446B818BC605C0017DF25 /* mc.h */,
4CE446B918BC605C0017DF25 /* md.h */,
4CE446BA18BC605C0017DF25 /* memory_align.h */,
4CE446BB18BC605C0017DF25 /* mt_defs.h */,
4CE446BC18BC605C0017DF25 /* mv_pred.h */,
4CE446BD18BC605C0017DF25 /* nal_encap.h */,
@@ -309,6 +309,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 */,
@@ -318,9 +320,7 @@
4CE446E218BC605C0017DF25 /* encoder_data_tables.cpp */,
4CE446E318BC605C0017DF25 /* encoder_ext.cpp */,
4CE446E518BC605C0017DF25 /* get_intra_predictor.cpp */,
4CE446E618BC605C0017DF25 /* mc.cpp */,
4CE446E718BC605C0017DF25 /* md.cpp */,
4CE446E818BC605C0017DF25 /* memory_align.cpp */,
4CE446E918BC605C0017DF25 /* mv_pred.cpp */,
4CE446EA18BC605C0017DF25 /* nal_encap.cpp */,
4CE446EB18BC605C0017DF25 /* picture_handle.cpp */,
@@ -445,12 +445,11 @@
4CE4470E18BC605C0017DF25 /* au_set.cpp in Sources */,
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 */,
4CE4471B18BC605C0017DF25 /* nal_encap.cpp in Sources */,
4CE4471918BC605C0017DF25 /* memory_align.cpp in Sources */,
4CE4472418BC605C0017DF25 /* svc_enc_slice_segment.cpp in Sources */,
4CE4472318BC605C0017DF25 /* svc_base_layer_md.cpp in Sources */,
4CB8F2B419235FC5005D6386 /* pixel_aarch64_neon.S in Sources */,
@@ -465,6 +464,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;
};

File diff suppressed because it is too large Load Diff

View File

@@ -351,51 +351,47 @@
</References>
<Files>
<Filter
Name="SW"
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
<File
RelativePath="..\..\..\common\inc\mem_align.h"
>
<File
RelativePath="..\..\..\decoder\plus\res\welsdec.rc"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
</File>
<File
RelativePath="..\..\..\common\inc\welsCodecTrace.h"
>
<File
RelativePath="..\..\..\decoder\plus\src\wels_dec_export.def"
>
</File>
<File
RelativePath="..\..\..\common\src\welsCodecTrace.cpp"
>
</File>
<File
RelativePath="..\..\..\decoder\plus\src\welsDecoderExt.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
</File>
<File
RelativePath="..\..\..\decoder\plus\inc\welsDecoderExt.h"
>
<File
RelativePath="..\..\..\decoder\core\inc\mem_align.h"
>
</File>
<File
RelativePath="..\..\..\common\inc\welsCodecTrace.h"
>
</File>
<File
RelativePath="..\..\..\decoder\plus\inc\welsDecoderExt.h"
>
</File>
</Filter>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
<File
RelativePath="..\..\..\decoder\plus\res\welsdec.rc"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\..\..\decoder\plus\src\wels_dec_export.def"
>
</File>
<File
RelativePath="..\..\..\common\src\welsCodecTrace.cpp"
>
</File>
<File
RelativePath="..\..\..\decoder\plus\src\welsDecoderExt.cpp"
>
</File>
</Filter>
</Files>
<Globals>

View File

@@ -386,7 +386,7 @@
>
</File>
<File
RelativePath="..\..\..\encoder\core\src\mc.cpp"
RelativePath="..\..\..\common\src\mc.cpp"
>
</File>
<File
@@ -394,7 +394,7 @@
>
</File>
<File
RelativePath="..\..\..\encoder\core\src\memory_align.cpp"
RelativePath="..\..\..\common\src\memory_align.cpp"
>
</File>
<File
@@ -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"
>
@@ -555,11 +563,7 @@
>
</File>
<File
RelativePath="..\..\..\encoder\core\inc\mc.h"
>
</File>
<File
RelativePath="..\..\..\common\inc\mc_common.h"
RelativePath="..\..\..\common\inc\mc.h"
>
</File>
<File
@@ -571,7 +575,7 @@
>
</File>
<File
RelativePath="..\..\..\encoder\core\inc\memory_align.h"
RelativePath="..\..\..\common\inc\memory_align.h"
>
</File>
<File
@@ -626,6 +630,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 +686,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"
>
@@ -710,6 +722,10 @@
RelativePath="..\..\..\encoder\core\inc\wels_const.h"
>
</File>
<File
RelativePath="..\..\..\common\inc\wels_const_common.h"
>
</File>
<File
RelativePath="..\..\..\encoder\core\inc\wels_func_ptr_def.h"
>

View File

@@ -50,6 +50,8 @@ mov pc, lr
.section .note.GNU-stack,"",%progbits // Mark stack as non-executable
.text
.arch armv7-a
.fpu neon
.macro WELS_ASM_FUNC_BEGIN funcName
.align 2

View File

@@ -834,17 +834,12 @@ WELS_ASM_FUNC_END
WELS_ASM_FUNC_BEGIN WelsNonZeroCount_neon
vld1.64 {d0-d2}, [r0]
vceq.s8 q0, q0, #0
vceq.s8 d2, d2, #0
vmvn q0, q0
vmvn d2, d2
vabs.s8 q0, q0
vabs.s8 d2, d2
vst1.64 {d0-d2}, [r0]
mov r1, #1
vdup.8 q2, r1
vld1.64 {d0,d1,d2}, [r0]
vmin.s8 q0, q0, q2
vmin.s8 d2, d2, d4
vst1.64 {d0,d1,d2}, [r0]
WELS_ASM_FUNC_END
#ifdef __APPLE__

View File

@@ -553,16 +553,12 @@ bs_mv_check_jump1:
#endif
WELS_ASM_AARCH64_FUNC_BEGIN WelsNonZeroCount_AArch64_neon
mov w1, #1
dup v3.8b, w1
ld1 {v0.8b, v1.8b, v2.8b}, [x0]
ins v0.d[1], v1.d[0]
uzp1 v0.2d, v0.2d, v1.2d
cmeq v0.16b, v0.16b, #0
cmeq v2.8b, v2.8b, #0
mvn v0.16b, v0.16b
mvn v2.8b, v2.8b
abs v0.16b, v0.16b
abs v2.8b, v2.8b
ins v1.d[0], v0.d[1]
umin v0.8b, v0.8b, v3.8b
umin v1.8b, v1.8b, v3.8b
umin v2.8b, v2.8b, v3.8b
st1 {v0.8b, v1.8b, v2.8b}, [x0]
WELS_ASM_AARCH64_FUNC_END

View File

@@ -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_gen.h.template | sed "s/\$FULL_VERSION/$GIT_VERSION/g" > codec/common/inc/version_gen.h.new
if cmp codec/common/inc/version_gen.h.new codec/common/inc/version_gen.h > /dev/null 2>&1; then
# Identical to old version, don't touch it (to avoid unnecessary rebuilds)
rm codec/common/inc/version_gen.h.new
echo "Keeping existing codec/common/inc/version_gen.h"
exit 0
fi
mv codec/common/inc/version_gen.h.new codec/common/inc/version_gen.h
echo "Generated codec/common/inc/version.h"
echo "Generated codec/common/inc/version_gen.h"

1
codec/common/inc/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
version_gen.h

View File

@@ -15,6 +15,16 @@ void DeblockChromaLt4H_c (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int
int8_t* pTc);
void DeblockChromaEq4H_c (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta);
void DeblockChromaLt4V2_c (uint8_t* pPixCbCr, int32_t iStride, int32_t iAlpha, int32_t iBeta,
int8_t* pTc);
void DeblockChromaEq4V2_c (uint8_t* pPixCbCr, int32_t iStride, int32_t iAlpha, int32_t iBeta);
void DeblockChromaLt4H2_c (uint8_t* pPixCbCr, int32_t iStride, int32_t iAlpha, int32_t iBeta,
int8_t* pTc);
void DeblockChromaEq4H2_c (uint8_t* pPixCbCr,int32_t iStride, int32_t iAlpha, int32_t iBeta);
void WelsNonZeroCount_c (int8_t* pNonZeroCount);
#if defined(__cplusplus)
extern "C" {
#endif//__cplusplus
@@ -32,6 +42,7 @@ void DeblockChromaLt4V_ssse3 (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride,
void DeblockChromaEq4H_ssse3 (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta);
void DeblockChromaLt4H_ssse3 (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta,
int8_t* pTC);
void WelsNonZeroCount_sse2 (int8_t* pNonZeroCount);
#endif
#if defined(HAVE_NEON)
@@ -48,6 +59,7 @@ void DeblockChromaEq4V_neon (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride,
void DeblockChromaLt4H_neon (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta,
int8_t* pTC);
void DeblockChromaEq4H_neon (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta);
void WelsNonZeroCount_neon (int8_t* pNonZeroCount);
#endif
#if defined(HAVE_NEON_AARCH64)
@@ -61,6 +73,7 @@ void DeblockChromaEq4V_AArch64_neon (uint8_t* pPixCb, uint8_t* pPixCr, int32_t i
void DeblockChromaLt4H_AArch64_neon (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta,
int8_t* pTC);
void DeblockChromaEq4H_AArch64_neon (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta);
void WelsNonZeroCount_AArch64_neon (int8_t* pNonZeroCount);
#endif
#if defined(__cplusplus)
}

View File

@@ -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__

View File

@@ -30,11 +30,36 @@
*
*/
#ifndef MC_COMMON_H
#define MC_COMMON_H
#ifndef MC_H
#define MC_H
#include "typedefs.h"
typedef void (*PWelsMcFunc) (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int16_t iMvX, int16_t iMvY, int32_t iWidth, int32_t iHeight);
typedef void (*PWelsLumaHalfpelMcFunc) (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight);
typedef void (*PWelsSampleAveragingFunc) (uint8_t*, int32_t, const uint8_t*, int32_t, const uint8_t*, int32_t,
int32_t, int32_t);
typedef struct TagMcFunc {
PWelsLumaHalfpelMcFunc pfLumaHalfpelHor;
PWelsLumaHalfpelMcFunc pfLumaHalfpelVer;
PWelsLumaHalfpelMcFunc pfLumaHalfpelCen;
PWelsMcFunc pMcChromaFunc;
PWelsMcFunc pMcLumaFunc;
PWelsSampleAveragingFunc pfSampleAveraging;
} SMcFunc;
namespace WelsCommon {
void InitMcFunc (SMcFunc* pMcFunc, uint32_t iCpu);
} // namespace WelsCommon
#if defined(__cplusplus)
extern "C" {
#endif//__cplusplus
@@ -272,4 +297,4 @@ void McChromaWidthEq8_ssse3 (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* p
}
#endif//__cplusplus
#endif//MC_COMMON_H
#endif//MC_H

View File

@@ -30,16 +30,26 @@
*
*/
#if !defined(WELS_ENCODER_MEMORY_ALIGN_H__)
#define WELS_ENCODER_MEMORY_ALIGN_H__
#if !defined(WELS_COMMON_MEMORY_ALIGN_H__)
#define WELS_COMMON_MEMORY_ALIGN_H__
#include "typedefs.h"
#include "as264_common.h"
// NOTE: please do not clean below lines even comment, turn on for potential memory leak verify and memory usage monitor etc.
//#define MEMORY_CHECK
#define MEMORY_MONITOR
#ifdef MEMORY_CHECK
#ifndef MEMORY_MONITOR
#define MEMORY_MONITOR
#endif//MEMORY_MONITOR
#endif//MEMORY_CHECK
#ifdef MEMORY_CHECK
#include <stdio.h>
#endif//MEMORY_CHECK
namespace WelsEnc {
namespace WelsCommon {
class CMemoryAlign {
public:
@@ -63,13 +73,38 @@ uint32_t m_nCacheLineSize;
#ifdef MEMORY_MONITOR
uint32_t m_nMemoryUsageInBytes;
#endif//MEMORY_MONITOR
#ifdef MEMORY_CHECK
FILE* m_fpMemChkPoint;
uint32_t m_nCountRequestNum;
#endif//MEMORY_CHECK
};
/*!
*************************************************************************************
* \brief malloc with zero filled utilization in Wels
*
* \param kuiSize size of memory block required
*
* \return allocated memory pointer exactly, failed in case of NULL return
*
* \note N/A
*************************************************************************************
*/
void* WelsMallocz (const uint32_t kuiSize, const char* kpTag);
/*!
*************************************************************************************
* \brief free utilization in Wels
*
* \param pPtr data pointer to be free.
* i.e, uint8_t *pPtr = actual data to be free, argv = &pPtr.
*
* \return NONE
*
* \note N/A
*************************************************************************************
*/
void WelsFree (void* pPtr, const char* kpTag);
#define WELS_SAFE_FREE(pPtr, pTag) if (pPtr) { WelsFree(pPtr, pTag); pPtr = NULL; }
}
#endif//WELS_ENCODER_MEMORY_ALIGN_H__
#endif//WELS_COMMON_MEMORY_ALIGN_H__

View File

@@ -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;

View File

@@ -1,6 +1,10 @@
#ifndef VERSION_H
#define VERSION_H
#define VERSION_NUMBER "openh264 default: 1.1"
#ifdef GENERATED_VERSION_HEADER
#include "version_gen.h"
#else
#define VERSION_NUMBER "openh264 default: 1.4"
#endif
#endif // VERSION_H

View File

@@ -1,6 +0,0 @@
#ifndef VERSION_H
#define VERSION_H
#define VERSION_NUMBER $FULL_VERSION
#endif // VERSION_H

View File

@@ -0,0 +1,6 @@
#ifndef VERSION_GEN_H
#define VERSION_GEN_H
#define VERSION_NUMBER $FULL_VERSION
#endif // VERSION_GEN_H

View File

@@ -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);

View File

@@ -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,14 +58,21 @@ 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];
extern const uint8_t g_kuiDequantScaling4x4Default[2][16];
extern const uint8_t g_kuiDequantScaling8x8Default[2][64];
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)
*/

View File

@@ -30,21 +30,27 @@
*
*/
#ifndef WELS_MC_H__
#define WELS_MC_H__
#ifndef WELS_CONST_COMMON_H__
#define WELS_CONST_COMMON_H__
#include "wels_const.h"
#include "macros.h"
#include "decoder_context.h"
#include "mc_common.h"
// Miscellaneous sizing infos
#ifndef MAX_FNAME_LEN
#define MAX_FNAME_LEN 256 // maximal length of file name in char size
#endif//MAX_FNAME_LEN
namespace WelsDec {
#ifndef WELS_LOG_BUF_SIZE
#define WELS_LOG_BUF_SIZE 4096
#endif//WELS_LOG_BUF_SIZE
typedef void (*PMcChromaWidthExtFunc) (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
const uint8_t* kpABCD, int32_t iHeight);
#ifndef MAX_TRACE_LOG_SIZE
#define MAX_TRACE_LOG_SIZE (50 * (1<<20)) // max trace log size: 50 MB, overwrite occur if log file size exceeds this size
#endif//MAX_TRACE_LOG_SIZE
void InitMcFunc (SMcFunc* pMcFunc, int32_t iCpu);
/* MB width in pixels for specified colorspace I420 usually used in codec */
#define MB_WIDTH_LUMA 16
#define MB_WIDTH_CHROMA (MB_WIDTH_LUMA>>1)
/* MB height in pixels for specified colorspace I420 usually used in codec */
#define MB_HEIGHT_LUMA 16
#define MB_HEIGHT_CHROMA (MB_HEIGHT_LUMA>>1)
} // namespace WelsDec
#endif//WELS_MC_H__
#endif//WELS_CONST_COMMON_H__

View File

@@ -74,6 +74,7 @@ const uint8_t g_kuiCache30ScanIdx[16] = { //mv or uiRefIndex cache scan index, 4
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// extern at wels_common_defs.h
const uint8_t g_kuiChromaQpTable[52] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
@@ -119,7 +120,29 @@ const EVclType g_keTypeMap[32][2] = {
{ NON_VCL, NON_VCL }, // 30: NAL_UNIT_UNSPEC_30
{ NON_VCL, NON_VCL } // 31: NAL_UNIT_UNSPEC_31
};
//default scaling list matrix value of 4x4
const uint8_t g_kuiDequantScaling4x4Default[2][16]={
{ 6, 13, 20, 28, 13, 20, 28, 32, 20, 28, 32, 37, 28, 32, 37, 42 },
{ 10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34 }
};
//default scaling list matrix value of 8x8
const uint8_t g_kuiDequantScaling8x8Default[2][64]={
{ 6, 10, 13, 16, 18, 23, 25, 27, 10, 11, 16, 18, 23, 25, 27, 29,
13, 16, 18, 23, 25, 27, 29, 31,
16, 18, 23, 25, 27, 29, 31, 33,
18, 23, 25, 27, 29, 31, 33, 36,
23, 25, 27, 29, 31, 33, 36, 38,
25, 27, 29, 31, 33, 36, 38, 40,
27, 29, 31, 33, 36, 38, 40, 42 },
{ 9, 13, 15, 17, 19, 21, 22, 24,
13, 13, 17, 19, 21, 22, 24, 25,
15, 17, 19, 21, 22, 24, 25, 27,
17, 19, 21, 22, 24, 25, 27, 28,
19, 21, 22, 24, 25, 27, 28, 30,
21, 22, 24, 25, 27, 28, 30, 32,
22, 24, 25, 27, 28, 30, 32, 33,
24, 25, 27, 28, 30, 32, 33, 35 }
};
ALIGNED_DECLARE (const uint16_t, g_kuiDequantCoeff[52][8], 16) = {
/* 0*/{ 10, 13, 10, 13, 13, 16, 13, 16 }, /* 1*/{ 11, 14, 11, 14, 14, 18, 14, 18 },
/* 2*/{ 13, 16, 13, 16, 16, 20, 16, 20 }, /* 3*/{ 14, 18, 14, 18, 18, 23, 18, 23 },
@@ -151,27 +174,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}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

View File

@@ -1,5 +1,6 @@
#include "deblocking_common.h"
#include "macros.h"
// C code only
void DeblockLumaLt4_c (uint8_t* pPix, int32_t iStrideX, int32_t iStrideY, int32_t iAlpha, int32_t iBeta,
int8_t* pTc) {
@@ -180,6 +181,77 @@ void DeblockChromaEq4H_c (uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, int
DeblockChromaEq4_c (pPixCb, pPixCr, 1, iStride, iAlpha, iBeta);
}
void DeblockChromaLt42_c (uint8_t* pPixCbCr, int32_t iStrideX, int32_t iStrideY, int32_t iAlpha,
int32_t iBeta, int8_t* pTc) {
int32_t p0, p1, q0, q1, iDeta;
bool bDetaP0Q0, bDetaP1P0, bDetaQ1Q0;
for (int32_t i = 0; i < 8; i++) {
int32_t iTc0 = pTc[i >> 1];
if (iTc0 > 0) {
p0 = pPixCbCr[-iStrideX];
p1 = pPixCbCr[-2 * iStrideX];
q0 = pPixCbCr[0];
q1 = pPixCbCr[iStrideX];
bDetaP0Q0 = WELS_ABS (p0 - q0) < iAlpha;
bDetaP1P0 = WELS_ABS (p1 - p0) < iBeta;
bDetaQ1Q0 = WELS_ABS (q1 - q0) < iBeta;
if (bDetaP0Q0 && bDetaP1P0 && bDetaQ1Q0) {
iDeta = WELS_CLIP3 ((((q0 - p0) << 2) + (p1 - q1) + 4) >> 3, -iTc0, iTc0);
pPixCbCr[-iStrideX] = WelsClip1 (p0 + iDeta); /* p0' */
pPixCbCr[0] = WelsClip1 (q0 - iDeta); /* q0' */
}
}
pPixCbCr += iStrideY;
}
}
void DeblockChromaEq42_c (uint8_t* pPixCbCr, int32_t iStrideX, int32_t iStrideY, int32_t iAlpha,
int32_t iBeta) {
int32_t p0, p1, q0, q1;
bool bDetaP0Q0, bDetaP1P0, bDetaQ1Q0;
for (int32_t i = 0; i < 8; i++) {
p0 = pPixCbCr[-iStrideX];
p1 = pPixCbCr[-2 * iStrideX];
q0 = pPixCbCr[0];
q1 = pPixCbCr[iStrideX];
bDetaP0Q0 = WELS_ABS (p0 - q0) < iAlpha;
bDetaP1P0 = WELS_ABS (p1 - p0) < iBeta;
bDetaQ1Q0 = WELS_ABS (q1 - q0) < iBeta;
if (bDetaP0Q0 && bDetaP1P0 && bDetaQ1Q0) {
pPixCbCr[-iStrideX] = ((p1 << 1) + p0 + q1 + 2) >> 2; /* p0' */
pPixCbCr[0] = ((q1 << 1) + q0 + p1 + 2) >> 2; /* q0' */
}
pPixCbCr += iStrideY;
}
}
void DeblockChromaLt4V2_c (uint8_t* pPixCbCr, int32_t iStride, int32_t iAlpha, int32_t iBeta,
int8_t* tc) {
DeblockChromaLt42_c (pPixCbCr, iStride, 1, iAlpha, iBeta, tc);
}
void DeblockChromaLt4H2_c (uint8_t* pPixCbCr, int32_t iStride, int32_t iAlpha, int32_t iBeta,
int8_t* tc) {
DeblockChromaLt42_c (pPixCbCr, 1, iStride, iAlpha, iBeta, tc);
}
void DeblockChromaEq4V2_c (uint8_t* pPixCbCr, int32_t iStride, int32_t iAlpha, int32_t iBeta) {
DeblockChromaEq42_c (pPixCbCr, iStride, 1, iAlpha, iBeta);
}
void DeblockChromaEq4H2_c (uint8_t* pPixCbCr, int32_t iStride, int32_t iAlpha, int32_t iBeta) {
DeblockChromaEq42_c (pPixCbCr, 1, iStride, iAlpha, iBeta);
}
void WelsNonZeroCount_c (int8_t* pNonZeroCount) {
int32_t i;
for (i = 0; i < 24; i++) {
pNonZeroCount[i] = !!pNonZeroCount[i];
}
}
#ifdef X86_ASM
extern "C" {
void DeblockLumaLt4H_ssse3 (uint8_t* pPixY, int32_t iStride, int32_t iAlpha, int32_t iBeta, int8_t* pTc) {

View File

@@ -41,8 +41,17 @@
#include "mc.h"
#include "cpu_core.h"
#include "ls_defines.h"
#include "macros.h"
namespace WelsDec {
typedef void (*PMcChromaWidthExtFunc) (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
const uint8_t* kpABCD, int32_t iHeight);
typedef void (*PWelsSampleWidthAveragingFunc) (uint8_t*, int32_t, const uint8_t*, int32_t, const uint8_t*,
int32_t, int32_t);
typedef void (*PWelsMcWidthHeightFunc) (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight);
namespace WelsCommon {
/*------------------weight for chroma fraction pixel interpolation------------------*/
//iA = (8 - dx) * (8 - dy);
@@ -84,9 +93,6 @@ static const uint8_t g_kuiABCD[8][8][4] = { //g_kA[dy][dx], g_kB[dy][dx], g_kC[d
}
};
typedef void (*PWelsMcWidthHeightFunc) (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight);
//***************************************************************************//
// C code implementation //
//***************************************************************************//
@@ -133,10 +139,10 @@ static inline void McCopyWidthEq16_c (const uint8_t* pSrc, int32_t iSrcStride, u
//--------------------Luma sample MC------------------//
static inline int32_t HorFilterInput16bit_c (int16_t* pSrc) {
int32_t iPix05 = pSrc[-2] + pSrc[3];
int32_t iPix14 = pSrc[-1] + pSrc[2];
int32_t iPix23 = pSrc[ 0] + pSrc[1];
static inline int32_t HorFilterInput16bit_c (const int16_t* pSrc) {
int32_t iPix05 = pSrc[0] + pSrc[5];
int32_t iPix14 = pSrc[1] + pSrc[4];
int32_t iPix23 = pSrc[2] + pSrc[3];
return (iPix05 - (iPix14 * 5) + (iPix23 * 20));
}
@@ -176,6 +182,7 @@ static inline void McCopy_c (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* p
McCopyWidthEq2_c (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
//horizontal filter to gain half sample, that is (2, 0) location in quarter sample
static inline void McHorVer20_c (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth,
int32_t iHeight) {
@@ -189,6 +196,7 @@ static inline void McHorVer20_c (const uint8_t* pSrc, int32_t iSrcStride, uint8_
}
}
//vertical filter to gain half sample, that is (0, 2) location in quarter sample
static inline void McHorVer02_c (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth,
int32_t iHeight) {
@@ -202,10 +210,11 @@ static inline void McHorVer02_c (const uint8_t* pSrc, int32_t iSrcStride, uint8_
}
}
//horizontal and vertical filter to gain half sample, that is (2, 2) location in quarter sample
static inline void McHorVer22_c (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth,
int32_t iHeight) {
int16_t iTmp[16 + 5]; //16
int16_t iTmp[17 + 5];
int32_t i, j, k;
for (i = 0; i < iHeight; i++) {
@@ -213,7 +222,7 @@ static inline void McHorVer22_c (const uint8_t* pSrc, int32_t iSrcStride, uint8_
iTmp[j] = FilterInput8bitWithStride_c (pSrc - 2 + j, iSrcStride);
}
for (k = 0; k < iWidth; k++) {
pDst[k] = WelsClip1 ((HorFilterInput16bit_c (&iTmp[2 + k]) + 512) >> 10);
pDst[k] = WelsClip1 ((HorFilterInput16bit_c (&iTmp[k]) + 512) >> 10);
}
pSrc += iSrcStride;
pDst += iDstStride;
@@ -390,6 +399,14 @@ static inline void McHorVer22WidthEq16_sse2 (const uint8_t* pSrc, int32_t iSrcSt
McHorVer22WidthEq8_sse2 (pSrc, iSrcStride, pDst, iDstStride, iHeight);
McHorVer22WidthEq8_sse2 (&pSrc[8], iSrcStride, &pDst[8], iDstStride, iHeight);
}
void McHorVer22Width9Or17Height9Or17_sse2 (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
ENFORCE_STACK_ALIGN_2D (int16_t, pTap, 22, 24, 16)
int32_t tmp1 = 2 * (iWidth - 8);
McHorVer22HorFirst_sse2 (pSrc - 2, iSrcStride, (uint8_t*)pTap, 48, iWidth, iHeight + 5);
McHorVer22Width8VerLastAlign_sse2 ((uint8_t*)pTap, 48, pDst, iDstStride, iWidth - 1, iHeight);
McHorVer22Width8VerLastUnAlign_sse2 ((uint8_t*)pTap + tmp1, 48, pDst + iWidth - 8, iDstStride, 8, iHeight);
}
static inline void McCopy_sse2 (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth,
@@ -667,19 +684,69 @@ void McChroma_sse2 (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int3
McChromaWithFragMv_c (pSrc, iSrcStride, pDst, iDstStride, iMvX, iMvY, iWidth, iHeight);
}
void McChroma_ssse3 (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int16_t iMvX, int16_t iMvY, int32_t iWidth, int32_t iHeight) {
static const PMcChromaWidthExtFunc kpMcChromaWidthFuncs[2] = {
McChromaWidthEq4_mmx,
McChromaWidthEq8_ssse3
};
const int32_t kiD8x = iMvX & 0x07;
const int32_t kiD8y = iMvY & 0x07;
if (kiD8x == 0 && kiD8y == 0) {
McCopy_sse2 (pSrc, iSrcStride, pDst, iDstStride, iWidth, iHeight);
return;
}
if (iWidth != 2) {
kpMcChromaWidthFuncs[iWidth >> 3] (pSrc, iSrcStride, pDst, iDstStride, g_kuiABCD[kiD8y][kiD8x], iHeight);
} else
McChromaWithFragMv_c (pSrc, iSrcStride, pDst, iDstStride, iMvX, iMvY, iWidth, iHeight);
}
void PixelAvg_sse2 (uint8_t* pDst, int32_t iDstStride, const uint8_t* pSrcA, int32_t iSrcAStride,
const uint8_t* pSrcB, int32_t iSrcBStride, int32_t iWidth, int32_t iHeight) {
static const PWelsSampleWidthAveragingFunc kpfFuncs[2] = {
PixelAvgWidthEq8_mmx,
PixelAvgWidthEq16_sse2
};
kpfFuncs[iWidth >> 4] (pDst, iDstStride, pSrcA, iSrcAStride, pSrcB, iSrcBStride, iHeight);
}
#endif //X86_ASM
//***************************************************************************//
// NEON implementation //
//***************************************************************************//
#if defined(HAVE_NEON)
void McHorVer20Width9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 17)
McHorVer20Width17_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else //if (iWidth == 9)
McHorVer20Width9_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McHorVer02Height9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 16)
McHorVer02Height17_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else //if (iWidth == 8)
McHorVer02Height9_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McHorVer22Width9Or17Height9Or17_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 17)
McHorVer22Width17_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else //if (iWidth == 9)
McHorVer22Width9_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McCopy_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (16 == iWidth)
McCopyWidthEq16_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else if (8 == iWidth)
McCopyWidthEq8_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else
else if (4 == iWidth)
McCopyWidthEq4_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else
McCopyWidthEq2_c (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McHorVer20_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
@@ -921,16 +988,48 @@ void McChroma_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int3
McChromaWithFragMv_c (pSrc, iSrcStride, pDst, iDstStride, iMvX, iMvY, iWidth, iHeight);
}
}
void PixelAvg_neon (uint8_t* pDst, int32_t iDstStride, const uint8_t* pSrcA, int32_t iSrcAStride,
const uint8_t* pSrcB, int32_t iSrcBStride, int32_t iWidth, int32_t iHeight) {
static const PWelsSampleWidthAveragingFunc kpfFuncs[2] = {
PixStrideAvgWidthEq8_neon,
PixStrideAvgWidthEq16_neon
};
kpfFuncs[iWidth >> 4] (pDst, iDstStride, pSrcA, iSrcAStride, pSrcB, iSrcBStride, iHeight);
}
#endif
#if defined(HAVE_NEON_AARCH64)
void McHorVer20Width9Or17_AArch64_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 17)
McHorVer20Width17_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else //if (iWidth == 9)
McHorVer20Width9_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McHorVer02Height9Or17_AArch64_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 16)
McHorVer02Height17_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else //if (iWidth == 8)
McHorVer02Height9_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McHorVer22Width9Or17Height9Or17_AArch64_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst,
int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (iWidth == 17)
McHorVer22Width17_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else //if (iWidth == 9)
McHorVer22Width9_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McCopy_AArch64_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
if (16 == iWidth)
McCopyWidthEq16_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else if (8 == iWidth)
McCopyWidthEq8_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else
else if (4 == iWidth)
McCopyWidthEq4_AArch64_neon (pSrc, iSrcStride, pDst, iDstStride, iHeight);
else
McCopyWidthEq2_c (pSrc, iSrcStride, pDst, iDstStride, iHeight);
}
void McHorVer20_AArch64_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int32_t iWidth, int32_t iHeight) {
@@ -1172,30 +1271,58 @@ void McChroma_AArch64_neon (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pD
McChromaWithFragMv_c (pSrc, iSrcStride, pDst, iDstStride, iMvX, iMvY, iWidth, iHeight);
}
}
void PixelAvg_AArch64_neon (uint8_t* pDst, int32_t iDstStride, const uint8_t* pSrcA, int32_t iSrcAStride,
const uint8_t* pSrcB, int32_t iSrcBStride, int32_t iWidth, int32_t iHeight) {
static const PWelsSampleWidthAveragingFunc kpfFuncs[2] = {
PixStrideAvgWidthEq8_AArch64_neon,
PixStrideAvgWidthEq16_AArch64_neon
};
kpfFuncs[iWidth >> 4] (pDst, iDstStride, pSrcA, iSrcAStride, pSrcB, iSrcBStride, iHeight);
}
#endif
void InitMcFunc (SMcFunc* pMcFunc, int32_t iCpu) {
pMcFunc->pMcLumaFunc = McLuma_c;
pMcFunc->pMcChromaFunc = McChroma_c;
void InitMcFunc (SMcFunc* pMcFuncs, uint32_t uiCpuFlag) {
pMcFuncs->pfLumaHalfpelHor = McHorVer20_c;
pMcFuncs->pfLumaHalfpelVer = McHorVer02_c;
pMcFuncs->pfLumaHalfpelCen = McHorVer22_c;
pMcFuncs->pfSampleAveraging = PixelAvg_c;
pMcFuncs->pMcChromaFunc = McChroma_c;
pMcFuncs->pMcLumaFunc = McLuma_c;
#ifdef HAVE_NEON
if (iCpu & WELS_CPU_NEON) {
pMcFunc->pMcLumaFunc = McLuma_neon;
pMcFunc->pMcChromaFunc = McChroma_neon;
}
#endif
#ifdef HAVE_NEON_AARCH64
if (iCpu & WELS_CPU_NEON) {
pMcFunc->pMcLumaFunc = McLuma_AArch64_neon;
pMcFunc->pMcChromaFunc = McChroma_AArch64_neon;
}
#endif
#if defined (X86_ASM)
if (iCpu & WELS_CPU_SSE2) {
pMcFunc->pMcLumaFunc = McLuma_sse2;
pMcFunc->pMcChromaFunc = McChroma_sse2;
if (uiCpuFlag & WELS_CPU_SSE2) {
pMcFuncs->pfLumaHalfpelHor = McHorVer20Width9Or17_sse2;
pMcFuncs->pfLumaHalfpelVer = McHorVer02Height9Or17_sse2;
pMcFuncs->pfLumaHalfpelCen = McHorVer22Width9Or17Height9Or17_sse2;
pMcFuncs->pfSampleAveraging = PixelAvg_sse2;
pMcFuncs->pMcChromaFunc = McChroma_sse2;
pMcFuncs->pMcLumaFunc = McLuma_sse2;
}
if (uiCpuFlag & WELS_CPU_SSSE3) {
pMcFuncs->pMcChromaFunc = McChroma_ssse3;
}
#endif //(X86_ASM)
}
} // namespace WelsDec
#if defined(HAVE_NEON)
if (uiCpuFlag & WELS_CPU_NEON) {
pMcFuncs->pMcLumaFunc = McLuma_neon;
pMcFuncs->pMcChromaFunc = McChroma_neon;
pMcFuncs->pfSampleAveraging = PixelAvg_neon;
pMcFuncs->pfLumaHalfpelHor = McHorVer20Width9Or17_neon;//iWidth+1:8/16
pMcFuncs->pfLumaHalfpelVer = McHorVer02Height9Or17_neon;//heigh+1:8/16
pMcFuncs->pfLumaHalfpelCen = McHorVer22Width9Or17Height9Or17_neon;//iWidth+1/heigh+1
}
#endif
#if defined(HAVE_NEON_AARCH64)
if (uiCpuFlag & WELS_CPU_NEON) {
pMcFuncs->pMcLumaFunc = McLuma_AArch64_neon;
pMcFuncs->pMcChromaFunc = McChroma_AArch64_neon;
pMcFuncs->pfSampleAveraging = PixelAvg_AArch64_neon;
pMcFuncs->pfLumaHalfpelHor = McHorVer20Width9Or17_AArch64_neon;//iWidth+1:8/16
pMcFuncs->pfLumaHalfpelVer = McHorVer02Height9Or17_AArch64_neon;//heigh+1:8/16
pMcFuncs->pfLumaHalfpelCen = McHorVer22Width9Or17Height9Or17_AArch64_neon;//iWidth+1/heigh+1
}
#endif
}
} // namespace WelsCommon

View File

@@ -35,7 +35,13 @@
#include "memory_align.h"
#include "macros.h"
namespace WelsEnc {
namespace WelsCommon {
#ifdef MEMORY_CHECK
static FILE* fpMemChkPoint;
static uint32_t nCountRequestNum;
#endif
CMemoryAlign::CMemoryAlign (const uint32_t kuiCacheLineSize)
#ifdef MEMORY_MONITOR
@@ -46,24 +52,66 @@ CMemoryAlign::CMemoryAlign (const uint32_t kuiCacheLineSize)
m_nCacheLineSize = 0x10;
else
m_nCacheLineSize = kuiCacheLineSize;
#ifdef MEMORY_CHECK
m_fpMemChkPoint = fopen ("./enc_mem_check_point.txt", "wt+");
m_nCountRequestNum = 0;
#endif//MEMORY_CHECK
}
CMemoryAlign::~CMemoryAlign() {
#ifdef MEMORY_MONITOR
assert (m_nMemoryUsageInBytes == 0);
#endif//MEMORY_MONITOR
}
void* WelsMalloc (const uint32_t kuiSize, const char* kpTag, const uint32_t kiAlign) {
const int32_t kiSizeOfVoidPointer = sizeof (void**);
const int32_t kiSizeOfInt = sizeof (int32_t);
const int32_t kiAlignedBytes = kiAlign - 1;
const int32_t kiTrialRequestedSize = kuiSize + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
const int32_t kiActualRequestedSize = kiTrialRequestedSize;
const uint32_t kiPayloadSize = kuiSize;
uint8_t* pBuf = (uint8_t*) malloc (kiActualRequestedSize);
#ifdef MEMORY_CHECK
fclose (m_fpMemChkPoint);
m_fpMemChkPoint = NULL;
if (fpMemChkPoint == NULL) {
m_fpMemChkPoint = fopen ("./enc_mem_check_point.txt", "at+");
m_nCountRequestNum = 0;
}
m_nCountRequestNum = 0;
#endif//MEMORY_CHECK
if (fpMemChkPoint != NULL) {
if (kpTag != NULL)
fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d - %s\n",
(void*)pBuf, kiActualRequestedSize, kuiSize, nCountRequestNum++, kpTag);
else
fprintf (fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d \n", (void*)pBuf,
kiActualRequestedSize, kuiSize, nCountRequestNum++);
fflush (fpMemChkPoint);
}
#endif
uint8_t* pAlignedBuffer;
if (NULL == pBuf)
return NULL;
pAlignedBuffer = pBuf + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
pAlignedBuffer -= ((uintptr_t) pAlignedBuffer & kiAlignedBytes);
* ((void**) (pAlignedBuffer - kiSizeOfVoidPointer)) = pBuf;
* ((int32_t*) (pAlignedBuffer - (kiSizeOfVoidPointer + kiSizeOfInt))) = kiPayloadSize;
return pAlignedBuffer;
}
void WelsFree (void* pPointer, const char* kpTag) {
if (pPointer) {
#ifdef MEMORY_CHECK
if (m_fpMemChkPoint != NULL) {
if (kpTag != NULL)
fprintf (fpMemChkPoint, "WelsFree(), 0x%x - %s: \t%d\t bytes \n", (void*) (* (((void**) pPointer) - 1)), kpTag,
kiMemoryLength);
else
fprintf (fpMemChkPoint, "WelsFree(), 0x%x \n", (void*) (* (((void**) pPointer) - 1)));
fflush (fpMemChkPoint);
}
#endif
free (* (((void**) pPointer) - 1));
}
}
void* CMemoryAlign::WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
@@ -78,40 +126,15 @@ void* CMemoryAlign::WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
}
void* CMemoryAlign::WelsMalloc (const uint32_t kuiSize, const char* kpTag) {
const int32_t kiSizeOfVoidPointer = sizeof (void**);
const int32_t kiSizeOfInt = sizeof (int32_t);
const int32_t kiAlignedBytes = m_nCacheLineSize - 1;
const int32_t kiTrialRequestedSize = kuiSize + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
const int32_t kiActualRequestedSize = kiTrialRequestedSize;
const uint32_t kiPayloadSize = kuiSize;
uint8_t* pBuf = (uint8_t*) malloc (kiActualRequestedSize);
#ifdef MEMORY_CHECK
if (m_fpMemChkPoint != NULL) {
if (kpTag != NULL)
fprintf (m_fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d - %s\n",
(void*)pBuf, kiActualRequestedSize, kuiSize, m_nCountRequestNum++, kpTag);
else
fprintf (m_fpMemChkPoint, "WelsMalloc(), 0x%x : actual uiSize:\t%d\tbytes, input uiSize: %d bytes, %d \n", (void*)pBuf,
kiActualRequestedSize, kuiSize, m_nCountRequestNum++);
fflush (m_fpMemChkPoint);
}
#endif
uint8_t* pAlignedBuffer;
if (NULL == pBuf)
return NULL;
pAlignedBuffer = pBuf + kiAlignedBytes + kiSizeOfVoidPointer + kiSizeOfInt;
pAlignedBuffer -= ((uintptr_t) pAlignedBuffer & kiAlignedBytes);
* ((void**) (pAlignedBuffer - kiSizeOfVoidPointer)) = pBuf;
* ((int32_t*) (pAlignedBuffer - (kiSizeOfVoidPointer + kiSizeOfInt))) = kiPayloadSize;
void* pPointer = WelsCommon::WelsMalloc (kuiSize, kpTag, m_nCacheLineSize);
#ifdef MEMORY_MONITOR
m_nMemoryUsageInBytes += kiActualRequestedSize;
if (pPointer != NULL) {
const int32_t kiMemoryLength = * ((int32_t*) ((uint8_t*)pPointer - sizeof (void**) - sizeof (
int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
m_nMemoryUsageInBytes += kiMemoryLength;
}
#endif//MEMORY_MONITOR
return pAlignedBuffer;
return pPointer;
}
void CMemoryAlign::WelsFree (void* pPointer, const char* kpTag) {
@@ -121,18 +144,17 @@ void CMemoryAlign::WelsFree (void* pPointer, const char* kpTag) {
int32_t))) + m_nCacheLineSize - 1 + sizeof (void**) + sizeof (int32_t);
m_nMemoryUsageInBytes -= kiMemoryLength;
#endif//MEMORY_MONITOR
#ifdef MEMORY_CHECK
if (m_fpMemChkPoint != NULL) {
if (kpTag != NULL)
fprintf (m_fpMemChkPoint, "WelsFree(), 0x%x - %s: \t%d\t bytes \n", (void*) (* (((void**) pPointer) - 1)), kpTag,
kiMemoryLength);
else
fprintf (m_fpMemChkPoint, "WelsFree(), 0x%x \n", (void*) (* (((void**) pPointer) - 1)));
fflush (m_fpMemChkPoint);
}
#endif
free (* (((void**) pPointer) - 1));
}
WelsCommon::WelsFree (pPointer, kpTag);
}
void* WelsMallocz (const uint32_t kuiSize, const char* kpTag) {
void* pPointer = WelsMalloc (kuiSize, kpTag, 16);
if (NULL == pPointer) {
return NULL;
}
memset (pPointer, 0, kuiSize);
return pPointer;
}
const uint32_t CMemoryAlign::WelsGetCacheLineSize() const {
@@ -143,4 +165,4 @@ const uint32_t CMemoryAlign::WelsGetMemoryUsage() const {
return m_nMemoryUsageInBytes;
}
} // end of namespace WelsEnc
} // end of namespace WelsCommon

View File

@@ -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);

View File

@@ -58,6 +58,7 @@ welsCodecTrace::welsCodecTrace() {
m_sLogCtx.pLogCtx = this;
m_sLogCtx.pfLog = StaticCodecTrace;
m_sLogCtx.pCodecInstance = NULL;
}
welsCodecTrace::~welsCodecTrace() {
@@ -83,6 +84,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;

View File

@@ -7,6 +7,8 @@ COMMON_CPP_SRCS=\
$(COMMON_SRCDIR)/src/deblocking_common.cpp\
$(COMMON_SRCDIR)/src/expand_pic.cpp\
$(COMMON_SRCDIR)/src/intra_pred_common.cpp\
$(COMMON_SRCDIR)/src/mc.cpp\
$(COMMON_SRCDIR)/src/memory_align.cpp\
$(COMMON_SRCDIR)/src/sad_common.cpp\
$(COMMON_SRCDIR)/src/utils.cpp\
$(COMMON_SRCDIR)/src/welsCodecTrace.cpp\

View File

@@ -60,10 +60,10 @@
; Macros
;***********************************************************************
DEFAULT REL
%ifdef WIN64 ; Windows x64 ;************************************
DEFAULT REL
BITS 64
%define arg1 rcx
@@ -114,6 +114,8 @@ BITS 64
%elifdef UNIX64 ; Unix x64 ;************************************
DEFAULT REL
BITS 64
%ifidn __OUTPUT_FORMAT__,elf64

View File

@@ -5276,3 +5276,14 @@ WELS_EXTERN DeblockLumaTransposeV2H_sse2
pop r3
ret
WELS_EXTERN WelsNonZeroCount_sse2
%assign push_num 0
LOAD_1_PARA
movdqu xmm0, [r0]
movq xmm1, [r0+16]
WELS_DB1 xmm2
pminub xmm0, xmm2
pminub xmm1, xmm2
movdqu [r0], xmm0
movq [r0+16], xmm1
ret

View File

@@ -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);
}
@@ -604,23 +605,17 @@ int CUtils::CheckOS() {
OSVERSIONINFOEX osvi;
ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
osvi.dwPlatformId = VER_PLATFORM_WIN32_NT;
osvi.dwMajorVersion = 6; // Vista
DWORDLONG condmask = VerSetConditionMask (VerSetConditionMask (0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_PLATFORMID, VER_EQUAL);
if (!GetVersionEx ((OSVERSIONINFO*) &osvi)) {
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ((OSVERSIONINFO*) &osvi))
return iType;
}
switch (osvi.dwPlatformId) {
case VER_PLATFORM_WIN32_NT:
if (osvi.dwMajorVersion >= 6)
iType = OS_VISTA_UPPER;
else if (osvi.dwMajorVersion == 5)
if (VerifyVersionInfo (&osvi, VER_MAJORVERSION | VER_PLATFORMID, condmask)) {
iType = OS_VISTA_UPPER;
} else {
osvi.dwMajorVersion = 5; // XP/2000
if (VerifyVersionInfo (&osvi, VER_MAJORVERSION | VER_PLATFORMID, condmask))
iType = OS_XP;
break;
default:
break;
}
#endif

View File

@@ -62,13 +62,23 @@ using namespace std;
#endif
//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) {
int32_t& iWidth, int32_t& iHeight, const char* pOptionFileName, const char* pLengthFileName) {
FILE* pH264File = NULL;
FILE* pYuvFile = NULL;
FILE* pOptionFile = NULL;
// Lenght input mode support
FILE* fpTrack = NULL;
if (pLengthFileName != NULL) {
fpTrack = fopen (pLengthFileName, "rb");
if (fpTrack == NULL)
printf ("Length file open ERROR!\n");
}
int32_t pInfo[4];
unsigned long long uiTimeStamp = 0;
int64_t iStart = 0, iEnd = 0, iTotal = 0;
int32_t iSliceSize;
int32_t iSliceIndex = 0;
@@ -86,7 +96,10 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
int32_t iFrameCount = 0;
int32_t iEndOfStreamFlag = 0;
int32_t iColorFormat = videoFormatInternal;
//for coverage test purpose
int32_t iErrorConMethod = (int32_t) ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
pDecoder->SetOption (DECODER_OPTION_ERROR_CON_IDC, &iErrorConMethod);
//~end for
CUtils cOutputModule;
double dElapsed = 0;
@@ -153,12 +166,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) {
@@ -167,19 +174,24 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
pDecoder->SetOption (DECODER_OPTION_END_OF_STREAM, (void*)&iEndOfStreamFlag);
break;
}
#if defined ( STICK_STREAM_SIZE )
if (fpTrack)
fread (&iSliceSize, 1, sizeof (int32_t), fpTrack);
#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
&& i > 0) || (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 1 && i > 0)) {
break;
// Read length from file if needed
if (fpTrack) {
if (fread (pInfo, 4, sizeof (int32_t), fpTrack) < 4)
return;
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
&& i > 0) || (pBuf[iBufPos + i] == 0 && pBuf[iBufPos + i + 1] == 0 && pBuf[iBufPos + i + 2] == 1 && i > 0)) {
break;
}
}
iSliceSize = i;
}
if (iSliceSize < 4) { //too small size, no effective data, ignore
iBufPos += iSliceSize;
continue;
}
iSliceSize = i;
#endif
//for coverage test purpose
int32_t iOutputColorFormat;
@@ -198,17 +210,20 @@ 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;
pDecoder->SetOption (DECODER_OPTION_ERROR_CON_IDC, &iErrorConMethod);
//~end for
iStart = WelsTime();
pData[0] = NULL;
pData[1] = NULL;
pData[2] = NULL;
uiTimeStamp ++;
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
#ifndef NO_DELAY_DECODING
pDecoder->DecodeFrameNoDelay (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);
#else
pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);
#endif
if (sDstBufInfo.iBufferStatus == 1) {
pDst[0] = pData[0];
@@ -234,46 +249,46 @@ 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;
}
// Get pending last frame
pData[0] = NULL;
pData[1] = NULL;
pData[2] = NULL;
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);
if (sDstBufInfo.iBufferStatus == 1) {
pDst[0] = pData[0];
pDst[1] = pData[1];
pDst[2] = pData[2];
}
if (sDstBufInfo.iBufferStatus == 1) {
cOutputModule.Process ((void**)pDst, &sDstBufInfo, pYuvFile);
iWidth = sDstBufInfo.UsrData.sSystemBuffer.iWidth;
iHeight = sDstBufInfo.UsrData.sSystemBuffer.iHeight;
if (pOptionFile != NULL) {
/* Anyway, we need write in case of final frame decoding */
fwrite (&iFrameCount, sizeof (iFrameCount), 1, pOptionFile);
fwrite (&iWidth , sizeof (iWidth) , 1, pOptionFile);
fwrite (&iHeight, sizeof (iHeight), 1, pOptionFile);
iLastWidth = iWidth;
iLastHeight = iHeight;
}
++ iFrameCount;
}
#if defined ( STICK_STREAM_SIZE )
if (fpTrack) {
fclose (fpTrack);
fpTrack = NULL;
}
#endif// STICK_STREAM_SIZE
dElapsed = iTotal / 1e6;
fprintf (stderr, "-------------------------------------------------------\n");
@@ -309,8 +324,8 @@ int32_t main (int32_t iArgC, char* pArgV[]) {
ISVCDecoder* pDecoder = NULL;
SDecodingParam sDecParam = {0};
string strInputFile (""), strOutputFile (""), strOptionFile ("");
int iLevelSetting = -1;
string strInputFile (""), strOutputFile (""), strOptionFile (""), strLengthFile ("");
int iLevelSetting = (int) WELS_LOG_WARNING;
sDecParam.sVideoProperty.size = sizeof (sDecParam.sVideoProperty);
@@ -396,6 +411,13 @@ int32_t main (int32_t iArgC, char* pArgV[]) {
printf ("trace level not specified.\n");
return 1;
}
} else if (!strcmp (cmd, "-length")) {
if (i + 1 < iArgC)
strLengthFile = pArgV[++i];
else {
printf ("lenght file not specified.\n");
return 1;
}
}
}
}
@@ -434,7 +456,7 @@ int32_t main (int32_t iArgC, char* pArgV[]) {
H264DecodeInstance (pDecoder, strInputFile.c_str(), !strOutputFile.empty() ? strOutputFile.c_str() : NULL, iWidth,
iHeight,
(!strOptionFile.empty() ? strOptionFile.c_str() : NULL));
(!strOptionFile.empty() ? strOptionFile.c_str() : NULL), (!strLengthFile.empty() ? strLengthFile.c_str() : NULL));
if (sDecParam.pFileNameRestructed != NULL) {
delete []sDecParam.pFileNameRestructed;

View File

@@ -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()) {
@@ -232,12 +232,34 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("MaxNalSize") == 0) {
pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("EnableSpsPpsIDAddition") == 0) {
pSvcParam.bEnableSpsPpsIdAddition = atoi (strTag[1].c_str()) ? true : false;
} else if (strTag[0].compare ("SpsPpsIDStrategy") == 0) {
int32_t iValue = atoi (strTag[1].c_str());
switch (iValue) {
case 0:
pSvcParam.eSpsPpsIdStrategy = CONSTANT_ID;
break;
case 0x01:
pSvcParam.eSpsPpsIdStrategy = INCREASING_ID;
break;
case 0x02:
pSvcParam.eSpsPpsIdStrategy = SPS_LISTING;
break;
case 0x03:
pSvcParam.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
break;
case 0x06:
pSvcParam.eSpsPpsIdStrategy = SPS_PPS_LISTING;
break;
default:
pSvcParam.eSpsPpsIdStrategy = CONSTANT_ID;
break;
}
} else if (strTag[0].compare ("EnableScalableSEI") == 0) {
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 +376,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");
@@ -417,8 +440,31 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE
else if (!strcmp (pCommand, "-nalsize") && (n < argc))
pSvcParam.uiMaxNalSize = atoi (argv[n++]);
else if (!strcmp (pCommand, "-spsid") && (n < argc))
pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false;
else if (!strcmp (pCommand, "-spsid") && (n < argc)) {
int32_t iValue = atoi (argv[n++]);
switch (iValue) {
case 0:
pSvcParam.eSpsPpsIdStrategy = CONSTANT_ID;
break;
case 0x01:
pSvcParam.eSpsPpsIdStrategy = INCREASING_ID;
break;
case 0x02:
pSvcParam.eSpsPpsIdStrategy = SPS_LISTING;
break;
case 0x03:
pSvcParam.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
break;
case 0x06:
pSvcParam.eSpsPpsIdStrategy = SPS_PPS_LISTING;
break;
default:
pSvcParam.eSpsPpsIdStrategy = CONSTANT_ID;
break;
}
}
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 +620,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
@@ -585,7 +631,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
sParam.bEnableLongTermReference = 0; // long term reference control
sParam.iLtrMarkPeriod = 30;
sParam.uiIntraPeriod = 320; // period of Intra frame
sParam.bEnableSpsPpsIdAddition = 1;
sParam.eSpsPpsIdStrategy = INCREASING_ID;
sParam.bPrefixNalAddingCtrl = 0;
sParam.iComplexityMode = MEDIUM_COMPLEXITY;
int iIndexLayer = 0;
@@ -594,7 +640,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 +649,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 +658,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 +668,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;
@@ -661,7 +707,7 @@ int ProcessEncoding (ISVCEncoder* pPtrEnc, int argc, char** argv, bool bConfigFi
FILE* fpGolden = NULL;
#endif
#if defined ( STICK_STREAM_SIZE )
FILE* fTrackStream = fopen ("coding_size.stream", "wb");;
FILE* fTrackStream = fopen ("coding_size.stream", "wb");
#endif
SFilesSet fs;
// for configuration file
@@ -704,9 +750,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;

View File

@@ -99,18 +99,6 @@
// }
.endm
#endif
// r0 int8_t* non_zero_count,
WELS_ASM_FUNC_BEGIN SetNonZeroCount_neon
vld1.64 {d0-d2}, [r0]
vceq.s8 q0, q0, #0
vceq.s8 d2, d2, #0
vmvn q0, q0
vmvn d2, d2
vabs.s8 q0, q0
vabs.s8 d2, d2
vst1.64 {d0-d2}, [r0]
WELS_ASM_FUNC_END
// uint8_t *pred, const int32_t stride, int16_t *rs
WELS_ASM_FUNC_BEGIN IdctResAddPred_neon
@@ -156,4 +144,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

View File

@@ -100,20 +100,6 @@
// }
.endm
#endif
// x0 int8_t* non_zero_count,
WELS_ASM_AARCH64_FUNC_BEGIN SetNonZeroCount_AArch64_neon
mov x1, x0
ld1 {v0.16b}, [x1], #16
ld1 {v1.8b}, [x1]
cmeq v0.16b, v0.16b, #0
cmeq v1.8b, v1.8b, #0
mvn v0.16b, v0.16b
mvn v1.8b, v1.8b
abs v0.16b, v0.16b
abs v1.8b, v1.8b
st1 {v0.16b}, [x0], #16
st1 {v1.8b}, [x0]
WELS_ASM_AARCH64_FUNC_END
// uint8_t *pred, const int32_t stride, int16_t *rs
WELS_ASM_AARCH64_FUNC_BEGIN IdctResAddPred_AArch64_neon
@@ -158,4 +144,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

View File

@@ -46,6 +46,7 @@
#include "parameter_sets.h"
#include "decoder_context.h"
#define DISABLE_HP_BRANCH_1_4
namespace WelsDec {
/*!
@@ -86,7 +87,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 +114,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,13 +130,28 @@ 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);
/*!
*************************************************************************************
* \brief to parse scaling list message payload
*
* \param PPS SPS scaling list matrix message to be parsed output
* \param pBsAux bitstream reader auxiliary
*
* \return 0 - successed
* 1 - failed
*
* \note Call it in case scaling matrix present at sps or pps
*************************************************************************************
*/
int32_t SetScalingListValue (uint8_t *pScalingList,int iScalingListNum,bool* bUseDefaultScalingMatrixFlag,PBitStringAux pBsAux);
int32_t ParseScalingList(PSps pSps,PBitStringAux pBs,bool bPPS,bool *bScalingListPresentFlag,uint8_t(*iScalingList4x4)[16],uint8_t(*iScalingList8x8)[64]);
/*!
*************************************************************************************
* \brief to parse SEI message payload
*
* \param pSei sei message to be parsed output
* \param pSei sei message to be parsed output
* \param pBsAux bitstream reader auxiliary
*
* \return 0 - successed

View File

@@ -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

View 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

View File

@@ -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 (*pChromaQp)[2];
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];
@@ -99,13 +102,16 @@ struct TagDqLayer {
int32_t iInterLayerSliceBetaOffset;
//SPosOffset sScaledRefLayer;
int32_t iSliceGroupChangeCycle;
PRefPicListReorderSyn pRefPicListReordering;
PPredWeightTabSyn pPredWeightTable;
PRefPicMarking pRefPicMarking; // Decoded reference picture marking syntaxs
PRefBasePicMarking pRefPicBaseMarking;
PPicture pRef; // reference picture pointer
PPicture pDec; // reconstruction picture pointer for layer
bool bUseWeightPredictionFlag;
bool bStoreRefBasePicFlag; // iCurTid == 0 && iCurQid = 0 && bEncodeKeyPic = 1
bool bTCoeffLevelPredFlag;
bool bConstrainedIntraResamplingFlag;

View File

@@ -89,7 +89,9 @@ static inline int32_t BsGetBits (PBitStringAux pBs, int32_t iNumBits, uint32_t*
// for data sharing cross modules and try to reduce size of binary generated, 12/10/2009
extern const uint8_t g_kuiIntra4x4CbpTable[48];
extern const uint8_t g_kuiIntra4x4CbpTable400[16];
extern const uint8_t g_kuiInterCbpTable[48];
extern const uint8_t g_kuiInterCbpTable400[16];
extern const uint8_t g_kuiLeadingZeroTable[256];
@@ -219,7 +221,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)

View File

@@ -38,24 +38,28 @@
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);
int32_t WelsMbInterSampleConstruction (PWelsDecoderContext pCtx, PDqLayer pCurLayer,
uint8_t* pDstY, uint8_t* pDstU, uint8_t* pDstV, int32_t iStrideL, int32_t iStrideC);
int32_t WelsMbInterConstruction (PWelsDecoderContext pCtx, PDqLayer pCurLayer);
void WelsLumaDcDequantIdct (int16_t* pBlock, int32_t iQp);
void WelsLumaDcDequantIdct (int16_t* pBlock, int32_t iQp,PWelsDecoderContext pCtx);
int32_t WelsMbInterPrediction (PWelsDecoderContext pCtx, PDqLayer pCurLayer);
void WelsChromaDcIdct (int16_t* pBlock);
@@ -63,20 +67,27 @@ 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
}
#endif//__cplusplus
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

View File

@@ -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

View File

@@ -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"
@@ -54,17 +55,66 @@
#include "crt_util_safe_x.h"
#include "mb_cache.h"
#include "expand_pic.h"
#include "mc.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;
uint8_t* pEnd;
uint8_t* pHead;
uint8_t* pEnd;
uint8_t* pStartPos;
uint8_t* pCurPos;
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
@@ -83,40 +133,33 @@ typedef void (*PExpandPictureFunc) (uint8_t* pDst, const int32_t kiStride, const
/**/
typedef struct TagRefPic {
PPicture pRefList[LIST_A][MAX_REF_PIC_COUNT]; // reference picture marking plus FIFO scheme
PPicture pShortRefList[LIST_A][MAX_SHORT_REF_COUNT];
PPicture pLongRefList[LIST_A][MAX_LONG_REF_COUNT];
uint8_t uiRefCount[LIST_A];
uint8_t uiShortRefCount[LIST_A];
uint8_t uiLongRefCount[LIST_A]; // dependend on ref pic module
int32_t iMaxLongTermFrameIdx;
PPicture pRefList[LIST_A][MAX_REF_PIC_COUNT]; // reference picture marking plus FIFO scheme
PPicture pShortRefList[LIST_A][MAX_SHORT_REF_COUNT];
PPicture pLongRefList[LIST_A][MAX_LONG_REF_COUNT];
uint8_t uiRefCount[LIST_A];
uint8_t uiShortRefCount[LIST_A];
uint8_t uiLongRefCount[LIST_A]; // dependend on ref pic module
int32_t iMaxLongTermFrameIdx;
} SRefPic, *PRefPic;
typedef void (*PWelsMcFunc) (const uint8_t* pSrc, int32_t iSrcStride, uint8_t* pDst, int32_t iDstStride,
int16_t iMvX, int16_t iMvY, int32_t iWidth, int32_t iHeight);
typedef struct TagMcFunc {
PWelsMcFunc pMcLumaFunc;
PWelsMcFunc pMcChromaFunc;
} SMcFunc;
typedef void (*PCopyFunc) (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
typedef struct TagCopyFunc {
PCopyFunc pCopyLumaFunc;
PCopyFunc pCopyChromaFunc;
PCopyFunc pCopyLumaFunc;
PCopyFunc pCopyChromaFunc;
} SCopyFunc;
//deblock module defination
struct TagDeblockingFunc;
typedef struct tagDeblockingFilter {
uint8_t* pCsData[3]; // pointer to reconstructed picture data
int32_t iCsStride[2]; // Cs stride
EWelsSliceType eSliceType;
int8_t iSliceAlphaC0Offset;
int8_t iSliceBetaOffset;
int8_t iChromaQP;
int8_t iLumaQP;
struct TagDeblockingFunc* pLoopf;
uint8_t* pCsData[3]; // pointer to reconstructed picture data
int32_t iCsStride[2]; // Cs stride
EWelsSliceType eSliceType;
int8_t iSliceAlphaC0Offset;
int8_t iSliceBetaOffset;
int8_t iChromaQP[2];
int8_t iLumaQP;
struct TagDeblockingFunc* pLoopf;
} SDeblockingFilter, *PDeblockingFilter;
typedef void (*PDeblockingFilterMbFunc) (PDqLayer pCurDqLayer, PDeblockingFilter filter, int32_t boundry_flag);
@@ -127,36 +170,50 @@ typedef void (*PChromaDeblockingLT4Func) (uint8_t* iSampleCb, uint8_t* iSampleCr
int32_t iBeta, int8_t* iTc);
typedef void (*PChromaDeblockingEQ4Func) (uint8_t* iSampleCb, uint8_t* iSampleCr, int32_t iStride, int32_t iAlpha,
int32_t iBeta);
typedef void (*PChromaDeblockingLT4Func2) (uint8_t* iSampleCbr, int32_t iStride, int32_t iAlpha,
int32_t iBeta, int8_t* iTc);
typedef void (*PChromaDeblockingEQ4Func2) (uint8_t* iSampleCbr, int32_t iStride, int32_t iAlpha,
int32_t iBeta);
typedef struct TagDeblockingFunc {
PLumaDeblockingLT4Func pfLumaDeblockingLT4Ver;
PLumaDeblockingEQ4Func pfLumaDeblockingEQ4Ver;
PLumaDeblockingLT4Func pfLumaDeblockingLT4Hor;
PLumaDeblockingEQ4Func pfLumaDeblockingEQ4Hor;
PLumaDeblockingLT4Func pfLumaDeblockingLT4Ver;
PLumaDeblockingEQ4Func pfLumaDeblockingEQ4Ver;
PLumaDeblockingLT4Func pfLumaDeblockingLT4Hor;
PLumaDeblockingEQ4Func pfLumaDeblockingEQ4Hor;
PChromaDeblockingLT4Func pfChromaDeblockingLT4Ver;
PChromaDeblockingEQ4Func pfChromaDeblockingEQ4Ver;
PChromaDeblockingLT4Func pfChromaDeblockingLT4Hor;
PChromaDeblockingEQ4Func pfChromaDeblockingEQ4Hor;
PChromaDeblockingLT4Func2 pfChromaDeblockingLT4Ver2;
PChromaDeblockingEQ4Func2 pfChromaDeblockingEQ4Ver2;
PChromaDeblockingLT4Func2 pfChromaDeblockingLT4Hor2;
PChromaDeblockingEQ4Func2 pfChromaDeblockingEQ4Hor2;
PChromaDeblockingLT4Func pfChromaDeblockingLT4Ver;
PChromaDeblockingEQ4Func pfChromaDeblockingEQ4Ver;
PChromaDeblockingLT4Func pfChromaDeblockingLT4Hor;
PChromaDeblockingEQ4Func pfChromaDeblockingEQ4Hor;
} SDeblockingFunc, *PDeblockingFunc;
typedef void (*PWelsNonZeroCountFunc) (int8_t* pNonZeroCount);
typedef void (*PWelsBlockZeroFunc) (int16_t* block, int32_t stride);
typedef struct TagBlockFunc {
PWelsNonZeroCountFunc pWelsSetNonZeroCountFunc;
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,
OVERWRITE_PPS = 1,
OVERWRITE_SPS = 1 << 1,
OVERWRITE_SUBSETSPS = 1 << 2
OVERWRITE_NONE = 0,
OVERWRITE_PPS = 1,
OVERWRITE_SPS = 1 << 1,
OVERWRITE_SUBSETSPS = 1 << 2
};
/*
@@ -164,179 +221,234 @@ OVERWRITE_SUBSETSPS = 1 << 2
*/
typedef struct TagWelsDecoderContext {
SLogContext sLogCtx;
SLogContext sLogCtx;
// Input
void* pArgDec; // structured arguments for decoder, reserved here for extension in the future
void* pArgDec; // structured arguments for decoder, reserved here for extension in the future
SDataBuffer sRawData;
SDataBuffer sRawData;
SDataBuffer sSavedData; //for parse only purpose
// Configuration
SDecodingParam* pParam;
uint32_t uiCpuFlag; // CPU compatibility detected
SDecodingParam* pParam;
uint32_t uiCpuFlag; // CPU compatibility detected
EVideoFormatType eOutputColorFormat; // color space format to be outputed
VIDEO_BITSTREAM_TYPE eVideoType; //indicate the type of video to decide whether or not to do qp_delta error detection.
bool bHaveGotMemory; // global memory for decoder context related ever requested?
EVideoFormatType eOutputColorFormat; // color space format to be outputed
VIDEO_BITSTREAM_TYPE eVideoType; //indicate the type of video to decide whether or not to do qp_delta error detection.
bool bHaveGotMemory; // global memory for decoder context related ever requested?
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
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
// Derived common elements
SNalUnitHeader sCurNalHead;
EWelsSliceType eSliceType; // Slice type
int32_t iFrameNum;
int32_t iPrevFrameNum; // frame number of previous frame well decoded for non-truncated mode yet
bool bLastHasMmco5; //
int32_t iErrorCode; // error code return while decoding in case packets lost
SFmo sFmoList[MAX_PPS_COUNT]; // list for FMO storage
PFmo pFmo; // current fmo context after parsed slice_header
int32_t iActiveFmoNum; // active count number of fmo context in list
SNalUnitHeader sCurNalHead;
EWelsSliceType eSliceType; // Slice type
int32_t iFrameNum;
int32_t iPrevFrameNum; // frame number of previous frame well decoded for non-truncated mode yet
bool bLastHasMmco5; //
int32_t iErrorCode; // error code return while decoding in case packets lost
SFmo sFmoList[MAX_PPS_COUNT]; // list for FMO storage
PFmo pFmo; // current fmo context after parsed slice_header
int32_t iActiveFmoNum; // active count number of fmo context in list
/*needed info by decode slice level and mb level*/
int32_t
iDecBlockOffsetArray[24]; // address talbe for sub 4x4 block in intra4x4_mb, so no need to caculta the address every time.
/*needed info by decode slice level and mb level*/
int32_t
iDecBlockOffsetArray[24]; // address talbe for sub 4x4 block in intra4x4_mb, so no need to caculta the address every time.
struct {
int8_t* pMbType[LAYER_NUM_EXCHANGEABLE]; /* mb type */
int16_t (*pMv[LAYER_NUM_EXCHANGEABLE][LIST_A])[MB_BLOCK4x4_NUM][MV_A]; //[LAYER_NUM_EXCHANGEABLE MB_BLOCK4x4_NUM*]
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*/
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*/
int8_t (*pIntraPredMode[LAYER_NUM_EXCHANGEABLE])[8]; //0~3 top4x4 ; 4~6 left 4x4; 7 intra16x16
int8_t (*pIntra4x4FinalMode[LAYER_NUM_EXCHANGEABLE])[MB_BLOCK4x4_NUM];
int8_t* pChromaPredMode[LAYER_NUM_EXCHANGEABLE];
int8_t* pCbp[LAYER_NUM_EXCHANGEABLE];
uint8_t (*pMotionPredFlag[LAYER_NUM_EXCHANGEABLE][LIST_A])[MB_PARTITION_SIZE]; // 8x8
int8_t (*pSubMbType[LAYER_NUM_EXCHANGEABLE])[MB_SUB_PARTITION_SIZE];
int32_t* pSliceIdc[LAYER_NUM_EXCHANGEABLE]; // using int32_t for slice_idc
int8_t* pResidualPredFlag[LAYER_NUM_EXCHANGEABLE];
int8_t* pInterPredictionDoneFlag[LAYER_NUM_EXCHANGEABLE];
bool* pMbCorrectlyDecodedFlag[LAYER_NUM_EXCHANGEABLE];
uint32_t iMbWidth;
uint32_t iMbHeight;
} sMb;
struct {
int8_t* pMbType[LAYER_NUM_EXCHANGEABLE]; /* mb type */
int16_t (*pMv[LAYER_NUM_EXCHANGEABLE][LIST_A])[MB_BLOCK4x4_NUM][MV_A]; //[LAYER_NUM_EXCHANGEABLE MB_BLOCK4x4_NUM*]
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])[2]; /*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*/
int8_t (*pIntraPredMode[LAYER_NUM_EXCHANGEABLE])[8]; //0~3 top4x4 ; 4~6 left 4x4; 7 intra16x16
int8_t (*pIntra4x4FinalMode[LAYER_NUM_EXCHANGEABLE])[MB_BLOCK4x4_NUM];
int8_t* pChromaPredMode[LAYER_NUM_EXCHANGEABLE];
int8_t* pCbp[LAYER_NUM_EXCHANGEABLE];
uint8_t (*pMotionPredFlag[LAYER_NUM_EXCHANGEABLE][LIST_A])[MB_PARTITION_SIZE]; // 8x8
int8_t (*pSubMbType[LAYER_NUM_EXCHANGEABLE])[MB_SUB_PARTITION_SIZE];
int32_t* pSliceIdc[LAYER_NUM_EXCHANGEABLE]; // using int32_t for slice_idc
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;
// reconstruction picture
PPicture pDec; //pointer to current picture being reconstructed
PPicture pDec; //pointer to current picture being reconstructed
// reference pictures
SRefPic sRefPic;
SRefPic sRefPic;
SVlcTable sVlcTable; // vlc table
SVlcTable sVlcTable; // vlc table
SBitStringAux sBs;
int32_t iMaxBsBufferSizeInByte; //actual memory size for BS buffer
SBitStringAux sBs;
int32_t iMaxBsBufferSizeInByte; //actual memory size for BS buffer
/* Global memory external */
/* Global memory external */
SPosOffset sFrameCrop;
SPosOffset sFrameCrop;
SSps sSpsBuffer[MAX_SPS_COUNT + 1];
SPps sPpsBuffer[MAX_PPS_COUNT + 1];
PSliceHeader pSliceHeader;
SSps sSpsBuffer[MAX_SPS_COUNT + 1];
SPps sPpsBuffer[MAX_PPS_COUNT + 1];
PSliceHeader pSliceHeader;
PPicBuff pPicBuff[LIST_A]; // Initially allocated memory for pictures which are used in decoding.
int32_t iPicQueueNumber;
PPicBuff pPicBuff[LIST_A]; // Initially allocated memory for pictures which are used in decoding.
int32_t iPicQueueNumber;
SSubsetSps sSubsetSpsBuffer[MAX_SPS_COUNT + 1];
SNalUnit sPrefixNal;
SSubsetSps sSubsetSpsBuffer[MAX_SPS_COUNT + 1];
SNalUnit sPrefixNal;
PAccessUnit pAccessUnitList; // current access unit list to be performed
PSps pActiveLayerSps[MAX_LAYER_NUM];
PSps pSps; // used by current AU
PPps pPps; // used by current AU
PAccessUnit pAccessUnitList; // current access unit list to be performed
PSps pActiveLayerSps[MAX_LAYER_NUM];
PSps pSps; // used by current AU
PPps pPps; // used by current AU
// Memory for pAccessUnitList is dynamically held till decoder destruction.
PDqLayer pCurDqLayer; // current DQ layer representation, also carry reference base layer if applicable
PDqLayer pDqLayersList[LAYER_NUM_EXCHANGEABLE]; // DQ layers list with memory allocated
PDqLayer pCurDqLayer; // current DQ layer representation, also carry reference base layer if applicable
PDqLayer pDqLayersList[LAYER_NUM_EXCHANGEABLE]; // DQ layers list with memory allocated
int32_t iPicWidthReq; // picture width have requested the memory
int32_t iPicHeightReq; // picture height have requested the memory
int32_t iPicWidthReq; // picture width have requested the memory
int32_t iPicHeightReq; // picture height have requested the memory
uint8_t uiTargetDqId; // maximal DQ ID in current access unit, meaning target layer ID
bool bAvcBasedFlag; // For decoding bitstream:
bool bEndOfStreamFlag; // Flag on end of stream requested by external application layer
bool bInstantDecFlag; // Flag for no-delay decoding
bool bInitialDqLayersMem; // dq layers related memory is available?
uint8_t uiTargetDqId; // maximal DQ ID in current access unit, meaning target layer ID
bool bAvcBasedFlag; // For decoding bitstream:
bool bEndOfStreamFlag; // Flag on end of stream requested by external application layer
bool bInstantDecFlag; // Flag for no-delay decoding
bool bInitialDqLayersMem; // dq layers related memory is available?
bool bOnlyOneLayerInCurAuFlag; //only one layer in current AU: 1
bool bOnlyOneLayerInCurAuFlag; //only one layer in current AU: 1
// for EC parameter sets
bool bSpsExistAheadFlag; // whether does SPS NAL exist ahead of sequence?
bool bSubspsExistAheadFlag;// whether does Subset SPS NAL exist ahead of sequence?
bool bPpsExistAheadFlag; // whether does PPS NAL exist ahead of sequence?
bool bSpsExistAheadFlag; // whether does SPS NAL exist ahead of sequence?
bool bSubspsExistAheadFlag;// whether does Subset SPS NAL exist ahead of sequence?
bool bPpsExistAheadFlag; // whether does PPS NAL exist ahead of sequence?
bool bSpsAvailFlags[MAX_SPS_COUNT];
bool bSubspsAvailFlags[MAX_SPS_COUNT];
bool bPpsAvailFlags[MAX_PPS_COUNT];
bool bReferenceLostAtT0Flag;
int32_t iTotalNumMbRec; //record current number of decoded MB
int32_t iSpsErrorIgnored;
int32_t iSubSpsErrorIgnored;
int32_t iPpsErrorIgnored;
bool bSpsAvailFlags[MAX_SPS_COUNT];
bool bSubspsAvailFlags[MAX_SPS_COUNT];
bool bPpsAvailFlags[MAX_PPS_COUNT];
int32_t iPPSLastInvalidId;
int32_t iPPSInvalidNum;
int32_t iSPSLastInvalidId;
int32_t iSPSInvalidNum;
int32_t iSubSPSLastInvalidId;
int32_t iSubSPSInvalidNum;
bool bReferenceLostAtT0Flag;
int32_t iTotalNumMbRec; //record current number of decoded MB
#ifdef LONG_TERM_REF
bool bParamSetsLostFlag; //sps or pps do not exist or not correct
bool bParamSetsLostFlag; //sps or pps do not exist or not correct
bool
bCurAuContainLtrMarkSeFlag; //current AU has the LTR marking syntax element, mark the previous frame or self
int32_t iFrameNumOfAuMarkedLtr; //if bCurAuContainLtrMarkSeFlag==true, SHOULD set this variable
bool
bCurAuContainLtrMarkSeFlag; //current AU has the LTR marking syntax element, mark the previous frame or self
int32_t iFrameNumOfAuMarkedLtr; //if bCurAuContainLtrMarkSeFlag==true, SHOULD set this variable
uint16_t uiCurIdrPicId;
uint16_t uiCurIdrPicId;
#endif
bool bNewSeqBegin;
bool bNextNewSeqBegin;
int iOverwriteFlags;
ERROR_CON_IDC eErrorConMethod; //
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
PGetIntraPredFunc pGetIChromaPredFunc[7]; // h264_predict_8x8_t
PIdctResAddPredFunc pIdctResAddPredFunc;
SMcFunc sMcFunc;
bool bNewSeqBegin;
bool bNextNewSeqBegin;
int iOverwriteFlags;
ERROR_CON_IDC eErrorConMethod; //
//for Parse only
bool bParseOnly;
bool bFramePending;
int32_t iNalNum;
int32_t iNalLenInByte[MAX_NAL_UNITS_IN_LAYER];
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
PGetIntraPredFunc pGetIChromaPredFunc[7]; // h264_predict_8x8_t
PIdctResAddPredFunc pIdctResAddPredFunc;
SMcFunc sMcFunc;
//For error concealment
SCopyFunc sCopyFunc;
/* For Deblocking */
SDeblockingFunc sDeblockingFunc;
SExpandPicFunc sExpandPicFunc;
SCopyFunc sCopyFunc;
/* For Deblocking */
SDeblockingFunc sDeblockingFunc;
SExpandPicFunc sExpandPicFunc;
/* For Block */
SBlockFunc sBlockFunc;
/* For Block */
SBlockFunc sBlockFunc;
int32_t iCurSeqIntervalTargetDependId;
int32_t iCurSeqIntervalMaxPicWidth;
int32_t iCurSeqIntervalMaxPicHeight;
int32_t iCurSeqIntervalTargetDependId;
int32_t iCurSeqIntervalMaxPicWidth;
int32_t iCurSeqIntervalMaxPicHeight;
PWelsFillNeighborMbInfoIntra4x4Func pFillInfoCacheIntra4x4Func;
PWelsParseIntra4x4ModeFunc pParseIntra4x4ModeFunc;
PWelsParseIntra16x16ModeFunc pParseIntra16x16ModeFunc;
PWelsFillNeighborMbInfoIntra4x4Func pFillInfoCacheIntra4x4Func;
PWelsMapNeighToSample pMap4x4NeighToSampleFunc;
PWelsMap16NeighToSample pMap16x16NeighToSampleFunc;
//feedback whether or not have VCL in current AU, and the temporal ID
int32_t iFeedbackVclNalInAu;
int32_t iFeedbackTidInAu;
int32_t iFeedbackVclNalInAu;
int32_t iFeedbackTidInAu;
bool bAuReadyFlag; // true: one au is ready for decoding; false: default value
bool bAuReadyFlag; // true: one au is ready for decoding; false: default value
bool bPrintFrameErrorTraceFlag; //true: can print info for upper layer
int32_t iIgnoredErrorInfoPacketCount; //store the packet number with error decoding info
bool bPrintFrameErrorTraceFlag; //true: can print info for upper layer
int32_t iIgnoredErrorInfoPacketCount; //store the packet number with error decoding info
//trace handle
void* pTraceHandle;
void* pTraceHandle;
//Save the last nal header info
SNalUnitHeaderExt sLastNalHdrExt;
SSliceHeader sLastSliceHeader;
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;
// To support scaling list HP
uint16_t pDequant_coeff_buffer4x4[6][52][16];
uint16_t pDequant_coeff_buffer8x8[6][52][64];
uint16_t (*pDequant_coeff4x4[6])[16];// 4x4 sclaing list value pointer
uint16_t (*pDequant_coeff8x8[6])[64];//64 residual coeff ,with 6 kinds of residual type, 52 qp level
int iDequantCoeffPpsid;//When a new pps actived, reinitialised the scaling list value
bool bDequantCoeff4x4Init;
bool bSpsLatePps;
bool bUseScalingList;
} SWelsDecoderContext, *PWelsDecoderContext;
static inline void ResetActiveSPSForEachLayer (PWelsDecoderContext pCtx) {
for (int i = 0; i < MAX_LAYER_NUM; i++) {
pCtx->pActiveLayerSps[i] = NULL;
}
if (pCtx->iTotalNumMbRec == 0) {
for (int i = 0; i < MAX_LAYER_NUM; i++) {
pCtx->pActiveLayerSps[i] = NULL;
}
}
}
//#ifdef __cplusplus
//}
//#endif//__cplusplus
} // namespace WelsDec
#endif//WELS_DECODER_FRAMEWORK_H__

View File

@@ -153,11 +153,14 @@ void WelsDqLayerDecodeStart (PWelsDecoderContext pCtx, PNalUnit pCurNal, PSps pS
int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx);
void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
void DecodeFinishUpdate (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__

View File

@@ -104,6 +104,7 @@ ERR_INFO_INVALID_POC_TYPE,
ERR_INFO_INVALID_MB_SIZE_INFO,
ERR_INFO_REF_COUNT_OVERFLOW,
ERR_INFO_CROPPING_NO_SUPPORTED,
ERR_INFO_INVALID_CROPPING_DATA,
ERR_INFO_INVALID_SLICEGROUP,
ERR_INFO_INVALID_SLICEGROUP_MAP_TYPE,
ERR_INFO_INVALID_FRAME_NUM,
@@ -117,6 +118,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,
@@ -145,6 +147,13 @@ ERR_INFO_INVALID_I4x4_PRED_MODE,
ERR_INFO_INVALID_I16x16_PRED_MODE,
ERR_INFO_INVALID_I_CHROMA_PRED_MODE,
ERR_INFO_INVALID_LUMA_LOG2_WEIGHT_DENOM,
ERR_INFO_INVALID_CHROMA_LOG2_WEIGHT_DENOM,
ERR_INFO_INVALID_LUMA_WEIGHT,
ERR_INFO_INVALID_CHROMA_WEIGHT,
ERR_INFO_INVALID_LUMA_OFFSET,
ERR_INFO_INVALID_CHROMA_OFFSET,
ERR_INFO_UNSUPPORTED_NON_BASELINE,
ERR_INFO_UNSUPPORTED_FMOTYPE,
ERR_INFO_UNSUPPORTED_MBAFF,
@@ -154,6 +163,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 +190,11 @@ 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,
//for scaling list
ERR_SCALING_LIST_DELTA_SCALE,
};
//-----------------------------------------------------------------------------------------------------------

View File

@@ -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

View File

@@ -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

View File

@@ -1,90 +0,0 @@
/*!
* \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.
*
* memory alignment utilization
*/
#ifndef WELS_MEM_ALIGN_H__
#define WELS_MEM_ALIGN_H__
#include <stdlib.h>
#include <string.h>
#include "utils.h"
namespace WelsDec {
#ifdef __cplusplus
extern "C" {
#endif//__cplusplus
/*!
*************************************************************************************
* \brief malloc with zero filled utilization in Wels
*
* \param kuiSize size of memory block required
*
* \return allocated memory pointer exactly, failed in case of NULL return
*
* \note N/A
*************************************************************************************
*/
void* WelsMalloc (const uint32_t kuiSize, const char* kpTag);
/*!
*************************************************************************************
* \brief free utilization in Wels
*
* \param pPtr data pointer to be free.
* i.e, uint8_t *pPtr = actual data to be free, argv = &pPtr.
*
* \return NONE
*
* \note N/A
*************************************************************************************
*/
void WelsFree (void* pPtr, const char* kpTag);
#define WELS_SAFE_FREE(pPtr, pTag) if (pPtr) { WelsFree(pPtr, pTag); pPtr = NULL; }
/*
* memory operation routines
*/
#ifdef __cplusplus
}
#endif//__cplusplus
} // namespace WelsDec
#endif //WELS_MEM_ALIGN_H__

View File

@@ -57,7 +57,7 @@ union {
} sVclNal;
SPrefixNalUnit sPrefixNal;
} sNalData;
unsigned long long uiTimeStamp;
} SNalUnit, *PNalUnit;
///////////////////////////////////ACCESS Unit level///////////////////////////////////

View File

@@ -88,7 +88,11 @@ typedef struct TagSps {
bool bQpPrimeYZeroTransfBypassFlag;
bool bSeqScalingMatrixPresentFlag;
bool bSeqScalingListPresentFlag[12];
const SLevelLimits* pSLevelLimits;
//Add scaling list supporting
uint8_t iScalingList4x4[6][16];
uint8_t iScalingList8x8[6][64];
const SLevelLimits* pSLevelLimits;
} SSps, *PSps;
@@ -151,7 +155,7 @@ typedef struct TagPps {
int32_t iPicInitQp;
int32_t iPicInitQs;
int32_t iChromaQpIndexOffset;
int32_t iChromaQpIndexOffset[2];//cb,cr
bool bEntropyCodingModeFlag;
bool bPicOrderPresentFlag;
@@ -163,7 +167,12 @@ typedef struct TagPps {
bool bRedundantPicCntPresentFlag;
bool bWeightedPredFlag;
uint8_t uiWeightedBipredIdc;
bool bTransform_8x8_mode_flag;
//Add for scalinglist support
bool bPicScalingMatrixPresentFlag;
bool bPicScalingListPresentFlag[12];
uint8_t iScalingList4x4[6][16];
uint8_t iScalingList8x8[6][64];
} SPps, *PPps;
} // namespace WelsDec

View 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

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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__

View File

@@ -68,7 +68,7 @@ struct {
bool bLumaWeightFlag;
bool bChromaWeightFlag;
} sPredList[LIST_A];
} SPredWeightTabSyn;
} SPredWeightTabSyn,*PPredWeightTabSyn;
/* Decoded reference picture marking syntax, refer to Page 66 in JVT X201wcm */
typedef struct TagRefPicMarking {
@@ -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

View File

@@ -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,153 @@ 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
#define LUMA_DC_AC_INTRA 10
#define LUMA_DC_AC_INTER 11
#define CHROMA_DC_U_INTER 12
#define CHROMA_DC_V_INTER 13
#define CHROMA_AC_U_INTER 14
#define CHROMA_AC_V_INTER 15
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,
};
static inline void GetMbResProperty(int32_t * pMBproperty,int32_t* pResidualProperty,bool bCavlc)
{
switch(*pResidualProperty)
{
case CHROMA_AC_U:
*pMBproperty = 1;
*pResidualProperty = bCavlc ? CHROMA_AC : CHROMA_AC_U;
break;
case CHROMA_AC_V:
*pMBproperty = 2;
*pResidualProperty = bCavlc ? CHROMA_AC : CHROMA_AC_V;
break;
case LUMA_DC_AC_INTRA:
*pMBproperty = 0;
*pResidualProperty = LUMA_DC_AC;
break;
case CHROMA_DC_U:
*pMBproperty = 1;
*pResidualProperty = bCavlc ? CHROMA_DC : CHROMA_DC_U;
break;
case CHROMA_DC_V:
*pMBproperty = 2;
*pResidualProperty = bCavlc ? CHROMA_DC : CHROMA_DC_V;
break;
case I16_LUMA_AC:
*pMBproperty = 0;
break;
case I16_LUMA_DC:
*pMBproperty = 0;
break;
case LUMA_DC_AC_INTER:
*pMBproperty = 3;
*pResidualProperty = LUMA_DC_AC;
break;
case CHROMA_DC_U_INTER:
*pMBproperty = 4;
*pResidualProperty = bCavlc ? CHROMA_DC : CHROMA_DC_U;
break;
case CHROMA_DC_V_INTER:
*pMBproperty = 5;
*pResidualProperty = bCavlc ? CHROMA_DC : CHROMA_DC_V;
break;
case CHROMA_AC_U_INTER:
*pMBproperty = 4;
*pResidualProperty = bCavlc ? CHROMA_AC : CHROMA_AC_U;
break;
case CHROMA_AC_V_INTER:
*pMBproperty = 5;
*pResidualProperty = bCavlc ?CHROMA_AC:CHROMA_AC_V;
break;
}
}
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

View File

@@ -31,28 +31,10 @@
*/
//wels_const.h
#ifndef WELS_CONSTANCE_H__
#define WELS_CONSTANCE_H__
#ifndef WELS_CONST_H__
#define WELS_CONST_H__
// Miscellaneous sizing infos
#ifndef MAX_FNAME_LEN
#define MAX_FNAME_LEN 256 // maximal length of file name in char size
#endif//MAX_FNAME_LEN
#ifndef WELS_LOG_BUF_SIZE
#define WELS_LOG_BUF_SIZE 4096
#endif//WELS_LOG_BUF_SIZE
#ifndef MAX_TRACE_LOG_SIZE
#define MAX_TRACE_LOG_SIZE (50 * (1<<20)) // max trace log size: 50 MB, overwrite occur if log file size exceeds this size
#endif//MAX_TRACE_LOG_SIZE
/* MB width in pixels for specified colorspace I420 usually used in codec */
#define MB_WIDTH_LUMA 16
#define MB_WIDTH_CHROMA (MB_WIDTH_LUMA>>1)
/* MB height in pixels for specified colorspace I420 usually used in codec */
#define MB_HEIGHT_LUMA 16
#define MB_HEIGHT_CHROMA (MB_HEIGHT_LUMA>>1)
#include "wels_const_common.h"
/* Some list size */
#define MB_COEFF_LIST_SIZE (256+((MB_WIDTH_CHROMA*MB_HEIGHT_CHROMA)<<1))
@@ -95,5 +77,10 @@
#define MAX_BUFFERED_NUM 3 //mamixum stored number of AU|packet to prevent overwrite
#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__
#endif//WELS_CONST_H__

View File

@@ -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 "memory_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.
@@ -144,38 +146,50 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
if (! (IS_SEI_NAL (pNalUnitHeader->eNalUnitType) || IS_SPS_NAL (pNalUnitHeader->eNalUnitType)
|| pCtx->bSpsExistAheadFlag)) {
if (pCtx->bPrintFrameErrorTraceFlag) {
if (pCtx->bPrintFrameErrorTraceFlag && pCtx->iSpsErrorIgnored == 0) {
WelsLog (pLogCtx, WELS_LOG_WARNING,
"parse_nal(), no exist Sequence Parameter Sets ahead of sequence when try to decode NAL(type:%d).",
pNalUnitHeader->eNalUnitType);
} else {
pCtx->iSpsErrorIgnored++;
}
pCtx->sDecoderStatistics.iSpsNoExistNalNum++;
pCtx->iErrorCode = dsNoParamSets;
return NULL;
}
pCtx->iSpsErrorIgnored = 0;
if (! (IS_SEI_NAL (pNalUnitHeader->eNalUnitType) || IS_PARAM_SETS_NALS (pNalUnitHeader->eNalUnitType)
|| pCtx->bPpsExistAheadFlag)) {
if (pCtx->bPrintFrameErrorTraceFlag) {
if (pCtx->bPrintFrameErrorTraceFlag && pCtx->iPpsErrorIgnored == 0) {
WelsLog (pLogCtx, WELS_LOG_WARNING,
"parse_nal(), no exist Picture Parameter Sets ahead of sequence when try to decode NAL(type:%d).",
pNalUnitHeader->eNalUnitType);
} else {
pCtx->iPpsErrorIgnored++;
}
pCtx->sDecoderStatistics.iPpsNoExistNalNum++;
pCtx->iErrorCode = dsNoParamSets;
return NULL;
}
pCtx->iPpsErrorIgnored = 0;
if ((IS_VCL_NAL_AVC_BASE (pNalUnitHeader->eNalUnitType) && ! (pCtx->bSpsExistAheadFlag || pCtx->bPpsExistAheadFlag)) ||
(IS_NEW_INTRODUCED_SVC_NAL (pNalUnitHeader->eNalUnitType) && ! (pCtx->bSpsExistAheadFlag || pCtx->bSubspsExistAheadFlag
|| pCtx->bPpsExistAheadFlag))) {
if (pCtx->bPrintFrameErrorTraceFlag) {
if (pCtx->bPrintFrameErrorTraceFlag && pCtx->iSubSpsErrorIgnored == 0) {
WelsLog (pLogCtx, WELS_LOG_WARNING,
"ParseNalHeader(), no exist Parameter Sets ahead of sequence when try to decode slice(type:%d).",
pNalUnitHeader->eNalUnitType);
} else {
pCtx->iSubSpsErrorIgnored++;
}
pCtx->sDecoderStatistics.iSubSpsNoExistNalNum++;
pCtx->iErrorCode |= dsNoParamSets;
return NULL;
}
pCtx->iSubSpsErrorIgnored = 0;
switch (pNalUnitHeader->eNalUnitType) {
case NAL_UNIT_AU_DELIMITER:
case NAL_UNIT_SEI:
if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
@@ -185,6 +199,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 +242,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 +269,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 +283,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 +305,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 +316,52 @@ 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;
int32_t iTrailingZeroByte = 0;
while (pSrcNal[iSrcNalLen - iTrailingZeroByte - 1] == 0x0) //remove final trailing 0 bytes
iTrailingZeroByte++;
int32_t iActualLen = iSrcNalLen - iTrailingZeroByte;
pCurNal->sNalData.sVclNal.iNalLength = iActualLen - NAL_UNIT_HEADER_EXT_SIZE;
//unify start code as 0x0001
int32_t iCurrStartByte = 4; //4 for 0x0001, 3 for 0x001
if (pSrcNal[0] == 0x0 && pSrcNal[1] == 0x0 && pSrcNal[2] == 0x1) { //if 0x001
iCurrStartByte = 3;
pCurNal->sNalData.sVclNal.iNalLength++;
}
if (pCurNal->sNalHeaderExt.bIdrFlag) {
* (pSrcNal + iCurrStartByte) &= 0xE0;
* (pSrcNal + iCurrStartByte) |= 0x05;
} else {
* (pSrcNal + iCurrStartByte) &= 0xE0;
* (pSrcNal + iCurrStartByte) |= 0x01;
}
pSavedData->pCurPos[0] = pSavedData->pCurPos[1] = pSavedData->pCurPos[2] = 0x0;
pSavedData->pCurPos[3] = 0x1;
pSavedData->pCurPos[4] = * (pSrcNal + iCurrStartByte);
pSavedData->pCurPos += 5;
int32_t iOffset = iCurrStartByte + 1 + NAL_UNIT_HEADER_EXT_SIZE;
memcpy (pSavedData->pCurPos, pSrcNal + iOffset, iActualLen - iOffset);
pSavedData->pCurPos += iActualLen - iOffset;
}
} else {
if (pCtx->bParseOnly) {
pCurNal->sNalData.sVclNal.pNalPos = pSavedData->pCurPos;
int32_t iTrailingZeroByte = 0;
while (pSrcNal[iSrcNalLen - iTrailingZeroByte - 1] == 0x0) //remove final trailing 0 bytes
iTrailingZeroByte++;
int32_t iActualLen = iSrcNalLen - iTrailingZeroByte;
pCurNal->sNalData.sVclNal.iNalLength = iActualLen;
//unify start code as 0x0001
int32_t iStartDeltaByte = 0; //0 for 0x0001, 1 for 0x001
if (pSrcNal[0] == 0x0 && pSrcNal[1] == 0x0 && pSrcNal[2] == 0x1) { //if 0x001
pSavedData->pCurPos[0] = 0x0;
iStartDeltaByte = 1;
pCurNal->sNalData.sVclNal.iNalLength++;
}
memcpy (pSavedData->pCurPos + iStartDeltaByte, pSrcNal, iActualLen);
pSavedData->pCurPos += iStartDeltaByte + iActualLen;
}
if (NAL_UNIT_PREFIX == pCtx->sPrefixNal.sNalHeaderExt.sNalUnitHeader.eNalUnitType) {
if (pCtx->sPrefixNal.sNalData.sPrefixNal.bPrefixNalCorrectFlag) {
PrefetchNalHeaderExtSyntax (pCtx, pCurNal, &pCtx->sPrefixNal);
@@ -309,7 +375,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 +399,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 +459,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 +485,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 +573,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 +591,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 +613,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 +792,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 +835,41 @@ 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) {
int i = 0, iNum = (int32_t) pCtx->pAccessUnitList->uiAvailUnitsNum;
while (i < iNum) {
PNalUnit pNalUnit = pCtx->pAccessUnitList->pNalUnitsList[i];
if (pNalUnit->sNalData.sVclNal.bSliceHeaderExtFlag) { //ext data
PSps pNextUsedSps = pNalUnit->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
if (pNextUsedSps->iSpsId == pSps->iSpsId)
return true;
}
++i;
}
}
} else {
if (pSps->iMbWidth > 0 && pSps->iMbHeight > 0 && pCtx->bSpsAvailFlags[pSps->iSpsId]
&& pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
int i = 0, iNum = (int32_t) pCtx->pAccessUnitList->uiAvailUnitsNum;
while (i < iNum) {
PNalUnit pNalUnit = pCtx->pAccessUnitList->pNalUnitsList[i];
if (!pNalUnit->sNalData.sVclNal.bSliceHeaderExtFlag) { //non-ext data
PSps pNextUsedSps = pNalUnit->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
if (pNextUsedSps->iSpsId == pSps->iSpsId)
return true;
}
++i;
}
}
}
return false;
}
@@ -747,6 +881,8 @@ bool CheckSpsActive (PWelsDecoderContext pCtx, PSps pSps) {
#define PPS_PIC_INIT_QP_QS_MAX 51
#define PPS_CHROMA_QP_INDEX_OFFSET_MIN -12
#define PPS_CHROMA_QP_INDEX_OFFSET_MAX 12
#define SCALING_LIST_DELTA_SCALE_MAX 127
#define SCALING_LIST_DELTA_SCALE_MIN -128
/*!
*************************************************************************************
@@ -764,7 +900,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;
@@ -823,11 +960,19 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //chroma_format_idc
pSps->uiChromaFormatIdc = uiCode;
#ifdef DISABLE_HP_BRANCH_1_4
if (pSps->uiChromaFormatIdc != 1) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "ParseSps(): chroma_format_idc (%d) = 1 supported.",
pSps->uiChromaFormatIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
}
#endif
if (pSps->uiChromaFormatIdc > 1) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "ParseSps(): chroma_format_idc (%d) <=1 supported.",
pSps->uiChromaFormatIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
}// To support 4:0:0; 4:2:0
pSps->uiChromaArrayType = pSps->uiChromaFormatIdc;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //bit_depth_luma_minus8
if (uiCode != 0) {
@@ -848,11 +993,17 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //seq_scaling_matrix_present_flag
pSps->bSeqScalingMatrixPresentFlag = !!uiCode;
if (pSps->bSeqScalingMatrixPresentFlag) { // For high profile, it is not used in current application. FIXME
if (pSps->bSeqScalingMatrixPresentFlag) {// For high profile, it is not used in current application. FIXME
#ifndef DISABLE_HP_BRANCH_1_4
WELS_READ_VERIFY (ParseScalingList (pSps, pBs, 0, pSps->bSeqScalingListPresentFlag, pSps->iScalingList4x4,
pSps->iScalingList8x8));
//if exist, to parse scalinglist matrix value
#else
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"ParseSps(): seq_scaling_matrix_present_flag (%d). Feature not supported.",
pSps->bSeqScalingMatrixPresentFlag);
"ParseSps(): seq_scaling_matrix_present_flag (%d). Feature not supported.",
pSps->bSeqScalingMatrixPresentFlag);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_NON_BASELINE);
#endif
}
}
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //log2_max_frame_num_minus4
@@ -946,14 +1097,16 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_right_offset
pSps->sFrameCrop.iRightOffset = uiCode;
if ((pSps->sFrameCrop.iLeftOffset + pSps->sFrameCrop.iRightOffset) > ((int32_t)pSps->iMbWidth * 16 / 2)) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "frame_crop_left_offset + frame_crop_right_offset exceeds limits!");
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "frame_crop_left_offset + frame_crop_right_offset exceeds limits!");
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CROPPING_DATA);
}
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_top_offset
pSps->sFrameCrop.iTopOffset = uiCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //frame_crop_bottom_offset
pSps->sFrameCrop.iBottomOffset = uiCode;
if ((pSps->sFrameCrop.iTopOffset + pSps->sFrameCrop.iBottomOffset) > ((int32_t)pSps->iMbHeight * 16 / 2)) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "frame_crop_top_offset + frame_crop_right_offset exceeds limits!");
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "frame_crop_top_offset + frame_crop_right_offset exceeds limits!");
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CROPPING_DATA);
}
} else {
pSps->sFrameCrop.iLeftOffset = 0; // frame_crop_left_offset
@@ -964,6 +1117,90 @@ 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;
int32_t iTrailingZeroByte = 0;
while (pSrcNal[kSrcNalLen - iTrailingZeroByte - 1] == 0x0) //remove final trailing 0 bytes
iTrailingZeroByte++;
int32_t iActualLen = kSrcNalLen - iTrailingZeroByte;
pSpsBs->uiSpsBsLen = (uint16_t) iActualLen;
//unify start code as 0x0001
int32_t iStartDeltaByte = 0; //0 for 0x0001, 1 for 0x001
if (pSrcNal[0] == 0x0 && pSrcNal[1] == 0x0 && pSrcNal[2] == 0x1) { //if 0x001
pSpsBs->pSpsBsBuf[0] = 0x0; //add 0 to form 0x0001
iStartDeltaByte++;
pSpsBs->uiSpsBsLen++;
}
memcpy (pSpsBs->pSpsBsBuf + iStartDeltaByte, pSrcNal, iActualLen);
} 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*> (WelsMallocz (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) {
@@ -979,8 +1216,6 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
if (PRO_SCALABLE_BASELINE == uiProfileIdc || PRO_SCALABLE_HIGH == uiProfileIdc)
pCtx->bAvcBasedFlag = false;
else
pCtx->bAvcBasedFlag = true; // added for avc base pBs
*pPicWidth = pSps->iMbWidth << 4;
*pPicHeight = pSps->iMbHeight << 4;
@@ -990,7 +1225,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 +1284,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;
@@ -1121,13 +1357,21 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
pPps->bWeightedPredFlag = !!uiCode;
WELS_READ_VERIFY (BsGetBits (pBsAux, 2, &uiCode)); //weighted_bipred_idc
pPps->uiWeightedBipredIdc = uiCode;
#ifdef DISABLE_HP_BRANCH_1_4
if (pPps->bWeightedPredFlag || pPps->uiWeightedBipredIdc != 0) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"ParsePps(): weighted_pred_flag (%d) weighted_bipred_idc (%d) neither supported.\n",
pPps->bWeightedPredFlag, pPps->uiWeightedBipredIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP);
}
#else
if (pPps->uiWeightedBipredIdc != 0) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"ParsePps(): weighted_bipred_idc (%d) not supported.\n",
pPps->uiWeightedBipredIdc);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_UNSUPPORTED_WP);
}
#endif
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //pic_init_qp_minus26
pPps->iPicInitQp = PIC_INIT_QP_OFFSET + iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQp, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qp_minus26 + 26",
@@ -1136,16 +1380,40 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
pPps->iPicInitQs = PIC_INIT_QS_OFFSET + iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iPicInitQs, PPS_PIC_INIT_QP_QS_MIN, PPS_PIC_INIT_QP_QS_MAX, "pic_init_qs_minus26 + 26",
GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_PIC_INIT_QS));
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //chroma_qp_index_offset
pPps->iChromaQpIndexOffset = iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iChromaQpIndexOffset, PPS_CHROMA_QP_INDEX_OFFSET_MIN, PPS_CHROMA_QP_INDEX_OFFSET_MAX,
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //chroma_qp_index_offset,cb
pPps->iChromaQpIndexOffset[0] = iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iChromaQpIndexOffset[0], PPS_CHROMA_QP_INDEX_OFFSET_MIN, PPS_CHROMA_QP_INDEX_OFFSET_MAX,
"chroma_qp_index_offset", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET));
pPps->iChromaQpIndexOffset[1] = pPps->iChromaQpIndexOffset[0];//init cr qp offset
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //deblocking_filter_control_present_flag
pPps->bDeblockingFilterControlPresentFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //constrained_intra_pred_flag
pPps->bConstainedIntraPredFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //redundant_pic_cnt_present_flag
pPps->bRedundantPicCntPresentFlag = !!uiCode;
/*TODO: to judge whether going on to parse*/
//going on to parse high profile syntax, need fix me
#ifndef DISABLE_HP_BRANCH_1_4
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode));
pPps->bTransform_8x8_mode_flag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode));
pPps->bPicScalingMatrixPresentFlag = !!uiCode;
if (pPps->bPicScalingMatrixPresentFlag) {
if (pCtx->bSpsAvailFlags[pPps->iSpsId])
WELS_READ_VERIFY (ParseScalingList (&pCtx->sSpsBuffer[pPps->iSpsId], pBsAux, 1, pPps->bPicScalingListPresentFlag,
pPps->iScalingList4x4, pPps->iScalingList8x8));
else {
pCtx->bSpsLatePps = true;
WELS_READ_VERIFY (ParseScalingList (NULL, pBsAux, 1, pPps->bPicScalingListPresentFlag, pPps->iScalingList4x4,
pPps->iScalingList8x8));
}
}
//add second chroma qp parsing process
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode)); //chroma_qp_index_offset,cr
pPps->iChromaQpIndexOffset[1] = iCode;
WELS_CHECK_SE_BOTH_ERROR (pPps->iChromaQpIndexOffset[1], PPS_CHROMA_QP_INDEX_OFFSET_MIN, PPS_CHROMA_QP_INDEX_OFFSET_MAX,
"second_chroma_qp_index_offset", GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_CHROMA_QP_INDEX_OFFSET));
#endif
if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
PNalUnit pLastNalUnit = pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum - 1];
PPps pLastPps = pLastNalUnit->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps;
@@ -1163,6 +1431,27 @@ 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;
int32_t iTrailingZeroByte = 0;
while (pSrcNal[kSrcNalLen - iTrailingZeroByte - 1] == 0x0) //remove final trailing 0 bytes
iTrailingZeroByte++;
int32_t iActualLen = kSrcNalLen - iTrailingZeroByte;
pPpsBs->uiPpsBsLen = (uint16_t) iActualLen;
//unify start code as 0x0001
int32_t iStartDeltaByte = 0; //0 for 0x0001, 1 for 0x001
if (pSrcNal[0] == 0x0 && pSrcNal[1] == 0x0 && pSrcNal[2] == 0x1) { //if 0x001
pPpsBs->pPpsBsBuf[0] = 0x0; //add 0 to form 0x0001
iStartDeltaByte++;
pPpsBs->uiPpsBsLen++;
}
memcpy (pPpsBs->pPpsBsBuf + iStartDeltaByte, pSrcNal, iActualLen);
}
return ERR_NONE;
}
@@ -1184,6 +1473,113 @@ int32_t ParseSei (void* pSei, PBitStringAux pBsAux) { // reserved Sei_Msg type
return ERR_NONE;
}
/*
*************************************************************************************
* \brief to parse scalinglist message payload
*
* \param pps sps scaling list matrix message to be parsed output
* \param pBsAux bitstream reader auxiliary
*
* \return 0 - successed
* 1 - failed
*
* \note Call it in case scaling list matrix present at sps or pps level
*************************************************************************************
*/
int32_t SetScalingListValue (uint8_t* pScalingList, int iScalingListNum, bool* bUseDefaultScalingMatrixFlag,
PBitStringAux pBsAux) { // reserved Sei_Msg type
int iLastScale = 8;
int iNextScale = 8;
int iDeltaScale;
int32_t iCode;
for (int j = 0; j < iScalingListNum; j++) {
if (iNextScale != 0) {
WELS_READ_VERIFY (BsGetSe (pBsAux, &iCode));
WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, SCALING_LIST_DELTA_SCALE_MIN, SCALING_LIST_DELTA_SCALE_MAX, "DeltaScale",
ERR_SCALING_LIST_DELTA_SCALE);
iDeltaScale = iCode;
iNextScale = (iLastScale + iDeltaScale + 256) % 256;
*bUseDefaultScalingMatrixFlag = (j == 0 && iNextScale == 0);
if (*bUseDefaultScalingMatrixFlag)
break;
}
pScalingList[g_kuiZigzagScan[j]] = (iNextScale == 0) ? iLastScale : iNextScale;
iLastScale = pScalingList[g_kuiZigzagScan[j]];
}
return ERR_NONE;
}
int32_t ParseScalingList (PSps pSps, PBitStringAux pBs, bool bPPS, bool* pScalingListPresentFlag,
uint8_t (*iScalingList4x4)[16], uint8_t (*iScalingList8x8)[64]) {
uint32_t uiScalingListNum;
uint32_t uiCode;
int32_t iRetTmp;
bool bUseDefaultScalingMatrixFlag4x4 = false;
bool bUseDefaultScalingMatrixFlag8x8 = false;
bool bInit = false;
const uint8_t* defaultScaling[4];
if (pSps != NULL) {
uiScalingListNum = (pSps->uiChromaFormatIdc != 3) ? 8 : 12;
bInit = bPPS && pSps->bSeqScalingMatrixPresentFlag;
} else
uiScalingListNum = 12;
//Init default_scaling_list value for sps or pps
defaultScaling[0] = bInit ? pSps->iScalingList4x4[0] : g_kuiDequantScaling4x4Default[0];
defaultScaling[1] = bInit ? pSps->iScalingList4x4[3] : g_kuiDequantScaling4x4Default[1];
defaultScaling[2] = bInit ? pSps->iScalingList8x8[0] : g_kuiDequantScaling8x8Default[0];
defaultScaling[3] = bInit ? pSps->iScalingList8x8[1] : g_kuiDequantScaling8x8Default[1];
for (unsigned int i = 0; i < uiScalingListNum; i++) {
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
pScalingListPresentFlag[i] = !!uiCode;
if (!!uiCode) {
if (i < 6) {
iRetTmp = SetScalingListValue (iScalingList4x4[i], 16, &bUseDefaultScalingMatrixFlag4x4, pBs);
if (iRetTmp == ERR_NONE) {
if (bUseDefaultScalingMatrixFlag4x4) {
bUseDefaultScalingMatrixFlag4x4 = false;
memcpy (iScalingList4x4[i], g_kuiDequantScaling4x4Default[i / 3], sizeof (uint8_t) * 16);
}
} else
return iRetTmp;
} else {
SetScalingListValue (iScalingList8x8[i - 6], 64, &bUseDefaultScalingMatrixFlag8x8, pBs);
//if(iRetTmp == ERR_NONE)
//{
if (bUseDefaultScalingMatrixFlag8x8) {
bUseDefaultScalingMatrixFlag8x8 = false;
memcpy (iScalingList8x8[i - 6], g_kuiDequantScaling8x8Default[ (i - 6) & 1], sizeof (uint8_t) * 64);
}
// }
//else
// return iRetTmp;
}
} else {
if (i < 6) {
if ((i != 0) && (i != 3))
memcpy (iScalingList4x4[i], iScalingList4x4[i - 1], sizeof (uint8_t) * 16);
else
memcpy (iScalingList4x4[i], defaultScaling[i / 3], sizeof (uint8_t) * 16);
} else {
if ((i == 6) || (i == 7))
memcpy (iScalingList8x8[i - 6], defaultScaling[ (i & 1) + 2], sizeof (uint8_t) * 64);
else
memcpy (iScalingList8x8[i - 6], iScalingList8x8[ (i - 6) / 3], sizeof (uint8_t) * 64);
}
}
}
return ERR_NONE;
}
/*!
*************************************************************************************

View File

@@ -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

View 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;
}
}
}

View File

@@ -332,13 +332,33 @@ void FilteringEdgeChromaH (SDeblockingFilter* pFilter, uint8_t* pPixCb, uint8_t*
int32_t iAlpha;
int32_t iBeta;
ENFORCE_STACK_ALIGN_1D (int8_t, tc, 4, 16);
if (pFilter->iChromaQP[0] == pFilter->iChromaQP[1]) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[0], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
TC0_TBL_LOOKUP (tc, iIndexA, pBS, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Ver (pPixCb, pPixCr, iStride, iAlpha, iBeta, tc);
}
} else {
for (int i = 0; i < 2; i++) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[i], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
uint8_t* pPixCbCr = (i == 0) ? pPixCb : pPixCr;
TC0_TBL_LOOKUP (tc, iIndexA, pBS, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Ver2 (pPixCbCr, iStride, iAlpha, iBeta, tc);
}
}
if (iAlpha | iBeta) {
TC0_TBL_LOOKUP (tc, iIndexA, pBS, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Ver (pPixCb, pPixCr, iStride, iAlpha, iBeta, tc);
}
return;
}
@@ -348,13 +368,33 @@ void FilteringEdgeChromaV (SDeblockingFilter* pFilter, uint8_t* pPixCb, uint8_t*
int32_t iAlpha;
int32_t iBeta;
ENFORCE_STACK_ALIGN_1D (int8_t, tc, 4, 16);
if (pFilter->iChromaQP[0] == pFilter->iChromaQP[1]) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
TC0_TBL_LOOKUP (tc, iIndexA, pBS, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Hor (pPixCb, pPixCr, iStride, iAlpha, iBeta, tc);
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[0], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
TC0_TBL_LOOKUP (tc, iIndexA, pBS, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Hor (pPixCb, pPixCr, iStride, iAlpha, iBeta, tc);
}
} else {
for (int i = 0; i < 2; i++) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[i], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
uint8_t* pPixCbCr = (i == 0) ? pPixCb : pPixCr;
TC0_TBL_LOOKUP (tc, iIndexA, pBS, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Hor2 (pPixCbCr, iStride, iAlpha, iBeta, tc);
}
}
}
return;
}
@@ -364,12 +404,27 @@ void FilteringEdgeChromaIntraH (SDeblockingFilter* pFilter, uint8_t* pPixCb, uin
int32_t iIndexA;
int32_t iAlpha;
int32_t iBeta;
if (pFilter->iChromaQP[0] == pFilter->iChromaQP[1]) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[0], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
pFilter->pLoopf->pfChromaDeblockingEQ4Ver (pPixCb, pPixCr, iStride, iAlpha, iBeta);
if (iAlpha | iBeta) {
pFilter->pLoopf->pfChromaDeblockingEQ4Ver (pPixCb, pPixCr, iStride, iAlpha, iBeta);
}
} else {
for (int i = 0; i < 2; i++) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[i], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
uint8_t* pPixCbCr = (i == 0) ? pPixCb : pPixCr;
pFilter->pLoopf->pfChromaDeblockingEQ4Ver2 (pPixCbCr, iStride, iAlpha, iBeta);
}
}
}
return;
}
@@ -379,12 +434,29 @@ void FilteringEdgeChromaIntraV (SDeblockingFilter* pFilter, uint8_t* pPixCb, uin
int32_t iIndexA;
int32_t iAlpha;
int32_t iBeta;
if (pFilter->iChromaQP[0] == pFilter->iChromaQP[1]) { // QP of cb and cr are the same
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
pFilter->pLoopf->pfChromaDeblockingEQ4Hor (pPixCb, pPixCr, iStride, iAlpha, iBeta);
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[0], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
pFilter->pLoopf->pfChromaDeblockingEQ4Hor (pPixCb, pPixCr, iStride, iAlpha, iBeta);
}
} else {
for (int i = 0; i < 2; i++) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[i], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
uint8_t* pPixCbCr = (i == 0) ? pPixCb : pPixCr;
pFilter->pLoopf->pfChromaDeblockingEQ4Hor2 (pPixCbCr, iStride, iAlpha, iBeta);
}
}
}
return;
}
@@ -397,7 +469,8 @@ void DeblockingInterMb (PDqLayer pCurDqLayer, PDeblockingFilter pFilter, uint8_
int32_t iMbY = pCurDqLayer->iMbY;
int32_t iCurLumaQp = pCurDqLayer->pLumaQp[iMbXyIndex];
int32_t iCurChromaQp = pCurDqLayer->pChromaQp[iMbXyIndex];
//int32_t* iCurChromaQp = pCurDqLayer->pChromaQp[iMbXyIndex];
int8_t* pCurChromaQp = pCurDqLayer->pChromaQp[iMbXyIndex];
int32_t iLineSize = pFilter->iCsStride[0];
int32_t iLineSizeUV = pFilter->iCsStride[1];
@@ -406,11 +479,13 @@ void DeblockingInterMb (PDqLayer pCurDqLayer, PDeblockingFilter pFilter, uint8_
pDestCb = pFilter->pCsData[1] + ((iMbY * iLineSizeUV + iMbX) << 3);
pDestCr = pFilter->pCsData[2] + ((iMbY * iLineSizeUV + iMbX) << 3);
//Vertical margrin
if (iBoundryFlag & LEFT_FLAG_MASK) {
int32_t iLeftXyIndex = iMbXyIndex - 1;
pFilter->iLumaQP = (iCurLumaQp + pCurDqLayer->pLumaQp[iLeftXyIndex] + 1) >> 1;
pFilter->iChromaQP = (iCurChromaQp + pCurDqLayer->pChromaQp[iLeftXyIndex] + 1) >> 1;
for (int i = 0; i < 2; i++) {
pFilter->iChromaQP[i] = (pCurChromaQp[i] + pCurDqLayer->pChromaQp[iLeftXyIndex][i] + 1) >> 1;
}
if (nBS[0][0][0] == 0x04) {
FilteringEdgeLumaIntraV (pFilter, pDestY, iLineSize, NULL);
FilteringEdgeChromaIntraV (pFilter, pDestCb, pDestCr, iLineSizeUV, NULL);
@@ -423,7 +498,8 @@ void DeblockingInterMb (PDqLayer pCurDqLayer, PDeblockingFilter pFilter, uint8_
}
pFilter->iLumaQP = iCurLumaQp;
pFilter->iChromaQP = iCurChromaQp;
pFilter->iChromaQP[0] = pCurChromaQp[0];
pFilter->iChromaQP[1] = pCurChromaQp[1];
if (* (uint32_t*)nBS[0][1] != 0) {
FilteringEdgeLumaV (pFilter, &pDestY[1 << 2], iLineSize, nBS[0][1]);
@@ -441,7 +517,9 @@ void DeblockingInterMb (PDqLayer pCurDqLayer, PDeblockingFilter pFilter, uint8_
if (iBoundryFlag & TOP_FLAG_MASK) {
int32_t iTopXyIndex = iMbXyIndex - pCurDqLayer->iMbWidth;
pFilter->iLumaQP = (iCurLumaQp + pCurDqLayer->pLumaQp[iTopXyIndex] + 1) >> 1;
pFilter->iChromaQP = (iCurChromaQp + pCurDqLayer->pChromaQp[iTopXyIndex] + 1) >> 1;
for (int i = 0; i < 2; i++) {
pFilter->iChromaQP[i] = (pCurChromaQp[i] + pCurDqLayer->pChromaQp[iTopXyIndex][i] + 1) >> 1;
}
if (nBS[1][0][0] == 0x04) {
FilteringEdgeLumaIntraH (pFilter, pDestY, iLineSize, NULL);
@@ -455,7 +533,8 @@ void DeblockingInterMb (PDqLayer pCurDqLayer, PDeblockingFilter pFilter, uint8_
}
pFilter->iLumaQP = iCurLumaQp;
pFilter->iChromaQP = iCurChromaQp;
pFilter->iChromaQP[0] = pCurChromaQp[0];
pFilter->iChromaQP[1] = pCurChromaQp[1];
if (* (uint32_t*)nBS[1][1] != 0) {
FilteringEdgeLumaH (pFilter, &pDestY[ (1 << 2)*iLineSize], iLineSize, nBS[1][1]);
@@ -527,8 +606,10 @@ void FilteringEdgeChromaHV (PDqLayer pCurDqLayer, PDeblockingFilter pFilter, in
int32_t iMbWidth = pCurDqLayer->iMbWidth;
int32_t iLineSize = pFilter->iCsStride[1];
uint8_t* pDestCb, *pDestCr;
int32_t iCurQp;
uint8_t* pDestCb;
uint8_t* pDestCr;
//int32_t iCurQp;
int8_t* pCurQp;
int32_t iIndexA, iAlpha, iBeta;
ENFORCE_STACK_ALIGN_1D (int8_t, iTc, 4, 16);
@@ -536,33 +617,76 @@ void FilteringEdgeChromaHV (PDqLayer pCurDqLayer, PDeblockingFilter pFilter, in
pDestCb = pFilter->pCsData[1] + ((iMbY * iLineSize + iMbX) << 3);
pDestCr = pFilter->pCsData[2] + ((iMbY * iLineSize + iMbX) << 3);
iCurQp = pCurDqLayer->pChromaQp[iMbXyIndex];
pCurQp = pCurDqLayer->pChromaQp[iMbXyIndex];
* (uint32_t*)uiBSx4 = 0x03030303;
// chroma v
// chroma v
if (iBoundryFlag & LEFT_FLAG_MASK) {
pFilter->iChromaQP = (iCurQp + pCurDqLayer->pChromaQp[iMbXyIndex - 1] + 1) >> 1;
for (int i = 0; i < 2; i++) {
pFilter->iChromaQP[i] = (pCurQp[i] + pCurDqLayer->pChromaQp[iMbXyIndex - 1][i] + 1) >> 1;
}
FilteringEdgeChromaIntraV (pFilter, pDestCb, pDestCr, iLineSize, NULL);
}
pFilter->iChromaQP = iCurQp;
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
TC0_TBL_LOOKUP (iTc, iIndexA, uiBSx4, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Hor (&pDestCb[2 << 1], &pDestCr[2 << 1], iLineSize, iAlpha, iBeta, iTc);
pFilter->iChromaQP[0] = pCurQp[0];
pFilter->iChromaQP[1] = pCurQp[1];
if (pFilter->iChromaQP[0] == pFilter->iChromaQP[1]) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[0], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
TC0_TBL_LOOKUP (iTc, iIndexA, uiBSx4, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Hor (&pDestCb[2 << 1], &pDestCr[2 << 1], iLineSize, iAlpha, iBeta, iTc);
}
} else {
for (int i = 0; i < 2; i++) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[i], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
uint8_t* pDestCbCr = (i == 0) ? &pDestCb[2 << 1] : &pDestCr[2 << 1];
TC0_TBL_LOOKUP (iTc, iIndexA, uiBSx4, 1);
pFilter->pLoopf->pfChromaDeblockingLT4Hor2 (pDestCbCr, iLineSize, iAlpha, iBeta, iTc);
}
}
}
// chroma h
if (iBoundryFlag & TOP_FLAG_MASK) {
pFilter->iChromaQP = (iCurQp + pCurDqLayer->pChromaQp[iMbXyIndex - iMbWidth] + 1) >> 1;
for (int i = 0; i < 2; i++) {
pFilter->iChromaQP[i] = (pCurQp[i] + pCurDqLayer->pChromaQp[iMbXyIndex - iMbWidth][i] + 1) >> 1;
}
FilteringEdgeChromaIntraH (pFilter, pDestCb, pDestCr, iLineSize, NULL);
}
pFilter->iChromaQP = iCurQp;
if (iAlpha | iBeta) {
pFilter->pLoopf->pfChromaDeblockingLT4Ver (&pDestCb[ (2 << 1)*iLineSize], &pDestCr[ (2 << 1)*iLineSize], iLineSize,
iAlpha, iBeta, iTc);
pFilter->iChromaQP[0] = pCurQp[0];
pFilter->iChromaQP[1] = pCurQp[1];
if (pFilter->iChromaQP[0] == pFilter->iChromaQP[1]) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[0], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
pFilter->pLoopf->pfChromaDeblockingLT4Ver (&pDestCb[ (2 << 1)*iLineSize], &pDestCr[ (2 << 1)*iLineSize], iLineSize,
iAlpha, iBeta, iTc);
}
} else {
for (int i = 0; i < 2; i++) {
GET_ALPHA_BETA_FROM_QP (pFilter->iChromaQP[i], pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha,
iBeta);
if (iAlpha | iBeta) {
uint8_t* pDestCbCr = (i == 0) ? &pDestCb[ (2 << 1) * iLineSize] : &pDestCr[ (2 << 1) * iLineSize];
pFilter->pLoopf->pfChromaDeblockingLT4Ver2 (pDestCbCr, iLineSize,
iAlpha, iBeta, iTc);
}
}
}
}
@@ -706,6 +830,11 @@ void DeblockingInit (SDeblockingFunc* pFunc, int32_t iCpu) {
pFunc->pfChromaDeblockingLT4Hor = DeblockChromaLt4H_c;
pFunc->pfChromaDeblockingEQ4Hor = DeblockChromaEq4H_c;
pFunc->pfChromaDeblockingLT4Ver2 = DeblockChromaLt4V2_c;
pFunc->pfChromaDeblockingEQ4Ver2 = DeblockChromaEq4V2_c;
pFunc->pfChromaDeblockingLT4Hor2 = DeblockChromaLt4H2_c;
pFunc->pfChromaDeblockingEQ4Hor2 = DeblockChromaEq4H2_c;
#ifdef X86_ASM
if (iCpu & WELS_CPU_SSSE3) {
pFunc->pfLumaDeblockingLT4Ver = DeblockLumaLt4V_ssse3;

File diff suppressed because it is too large Load Diff

View File

@@ -51,7 +51,7 @@
#include "expand_pic.h"
#include "decode_slice.h"
#include "error_concealment.h"
#include "mem_align.h"
#include "memory_align.h"
namespace WelsDec {
@@ -67,34 +67,177 @@ static int32_t CreatePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, cons
return 1;
}
pPicBuf = (PPicBuff)WelsMalloc (sizeof (SPicBuff), "PPicBuff");
pPicBuf = (PPicBuff)WelsMallocz (sizeof (SPicBuff), "PPicBuff");
if (NULL == pPicBuf) {
return 1;
}
pPicBuf->ppPic = (PPicture*)WelsMalloc (kiSize * sizeof (PPicture), "PPicture*");
pPicBuf->ppPic = (PPicture*)WelsMallocz (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)WelsMallocz (sizeof (SPicBuff), "PPicBuff");
if (NULL == pPicNewBuf) {
return 1;
}
pPicNewBuf->ppPic = (PPicture*)WelsMallocz (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)WelsMallocz (sizeof (SPicBuff), "PPicBuff");
if (NULL == pPicNewBuf) {
return 1;
}
pPicNewBuf->ppPic = (PPicture*)WelsMallocz (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,9 +306,20 @@ 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_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
pCtx->pPreviousDecodedPictureInDpb = NULL;
pCtx->sDecoderStatistics.iAvgLumaQp = -1;
pCtx->bSpsLatePps = false;
pCtx->bUseScalingList = false;
pCtx->iSpsErrorIgnored = 0;
pCtx->iSubSpsErrorIgnored = 0;
pCtx->iPpsErrorIgnored = 0;
pCtx->iPPSInvalidNum = 0;
pCtx->iPPSLastInvalidId = -1;
pCtx->iSPSInvalidNum = 0;
pCtx->iSPSLastInvalidId = -1;
pCtx->iSubSPSInvalidNum = 0;
pCtx->iSubSPSLastInvalidId = -1;
}
/*
@@ -175,10 +332,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 +378,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 +423,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*) WelsMallocz (sizeof (SWelsCabacDecEngine), "pCtx->pCabacDecEngine");
WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, (NULL == pCtx->pCabacDecEngine))
return ERR_NONE;
}
@@ -266,8 +452,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");
}
/*!
@@ -278,7 +467,6 @@ int32_t WelsOpenDecoder (PWelsDecoderContext pCtx) {
//initial MC function pointer--
int iRet = ERR_NONE;
InitMcFunc (& (pCtx->sMcFunc), pCtx->uiCpuFlag);
InitErrorCon (pCtx);
InitExpandPictureFunc (& (pCtx->sExpandPicFunc), pCtx->uiCpuFlag);
AssignFuncPointerForRec (pCtx);
@@ -328,18 +516,24 @@ int32_t DecoderConfigParam (PWelsDecoderContext pCtx, const SDecodingParam* kpPa
if (NULL == pCtx || NULL == kpParam)
return 1;
pCtx->pParam = (SDecodingParam*)WelsMalloc (sizeof (SDecodingParam), "SDecodingParam");
pCtx->pParam = (SDecodingParam*)WelsMallocz (sizeof (SDecodingParam), "SDecodingParam");
if (NULL == pCtx->pParam)
return 1;
memcpy (pCtx->pParam, kpParam, sizeof (SDecodingParam));
pCtx->eOutputColorFormat = pCtx->pParam->eOutputColorFormat;
int32_t iRet = DecoderSetCsp (pCtx, pCtx->pParam->eOutputColorFormat);
if (iRet)
return iRet;
if (!pCtx->bParseOnly) {
int32_t iRet = DecoderSetCsp (pCtx, pCtx->pParam->eOutputColorFormat);
if (iRet)
return iRet;
}
pCtx->eErrorConMethod = pCtx->pParam->eEcActiveIdc;
if (pCtx->bParseOnly) //parse only, disable EC method
pCtx->eErrorConMethod = ERROR_CON_DISABLE;
InitErrorCon (pCtx);
if (VIDEO_BITSTREAM_SVC == pCtx->pParam->sVideoProperty.eVideoBsType ||
VIDEO_BITSTREAM_AVC == pCtx->pParam->sVideoProperty.eVideoBsType) {
pCtx->eVideoType = pCtx->pParam->sVideoProperty.eVideoBsType;
@@ -364,7 +558,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 +566,7 @@ int32_t WelsInitDecoder (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
// default
WelsDecoderDefaults (pCtx, pLogCtx);
pCtx->bParseOnly = bParseOnly;
// open decoder
return WelsOpenDecoder (pCtx);
}
@@ -417,9 +612,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 +643,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,28 +665,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)) {
if (pNalPayload) { //parse correct
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
}
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
ConstructAccessUnit (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);
DecodeFinishUpdate (pCtx);
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;
}
}
if (iRet) {
@@ -496,19 +697,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,26 +722,28 @@ 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
pRawData->pCurPos = pDstNal + iDstIdx + 4; //init, increase 4 reserved zero bytes, used to store the next NAL
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 ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
#ifdef LONG_TERM_REF
pCtx->bParamSetsLostFlag = true;
#else
pCtx->bReferenceLostAtT0Flag = true;
#endif
if ((pCtx->eErrorConMethod == ERROR_CON_DISABLE) || (dsOutOfMemory & pCtx->iErrorCode))
ResetParameterSetsState (pCtx);
return pCtx->iErrorCode;
if (pNalPayload) { //parse correct
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
}
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
}
}
DecodeFinishUpdate (pCtx);
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
#ifdef LONG_TERM_REF
pCtx->bParamSetsLostFlag = true;
#else
pCtx->bReferenceLostAtT0Flag = true;
#endif
return pCtx->iErrorCode;
}
if (iRet) {
iRet = 0;
@@ -553,12 +753,9 @@ 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
} 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
@@ -569,17 +766,16 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
}
DecodeFinishUpdate (pCtx);
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;
}
}
@@ -765,4 +961,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 = (int) ((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

View File

@@ -40,11 +40,10 @@
#include "expand_pic.h"
#include "decoder.h"
#include "decode_mb_aux.h"
#include "mem_align.h"
#include "memory_align.h"
#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,16 +65,89 @@ 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;
}
}
if (pCtx->bParseOnly) { //should exit for parse only to prevent access NULL pDstInfo
PAccessUnit pCurAu = pCtx->pAccessUnitList;
static bool bFirstIDR = true;
if (dsErrorFree == pCtx->iErrorCode) { //correct decoding, add to data buffer
SParserBsInfo* pParser = pCtx->pParserBsInfo;
SNalUnit* pCurNal = NULL;
int32_t iTotalNalLen = 0;
int32_t iNalLen = 0;
int32_t iNum = 0;
while (iNum < pParser->iNalNum) {
iTotalNalLen += pParser->iNalLenInByte[iNum++];
}
uint8_t* pDstBuf = pParser->pDstBuff + iTotalNalLen;
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
if (bFirstIDR) { //add required sps/pps
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;
pCtx->iNalLenInByte[pCtx->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;
bFirstIDR = false;
}
} else { //IDR required SPS, PPS
bFirstIDR = true;
}
//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;
}
if (pCtx->iTotalNumMbRec == kiTotalNumMbInCurLayer) { //frame complete
pCtx->iTotalNumMbRec = 0;
pCtx->bFramePending = false;
} else if (pCtx->iTotalNumMbRec != 0) { //frame incomplete
pCtx->bFramePending = true;
pCtx->pDec->bIsComplete = false;
pCtx->iErrorCode |= dsFramePending;
return -1;
//pCtx->pParserBsInfo->iNalNum = 0;
}
} else { //error
pCtx->pParserBsInfo->uiOutBsTimeStamp = 0;
pCtx->pParserBsInfo->iNalNum = 0;
pCtx->pParserBsInfo->iSpsWidthInPixel = 0;
pCtx->pParserBsInfo->iSpsHeightInPixel = 0;
return -1;
}
return 0;
}
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 +155,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 +177,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 +223,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 +230,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;
}
@@ -165,6 +243,78 @@ inline int32_t WelsDecodeConstructSlice (PWelsDecoderContext pCtx, PNalUnit pCu
return iRet;
}
int32_t ParsePredWeightedTable (PBitStringAux pBs, PSliceHeader pSh) {
uint32_t uiCode;
int32_t iList = 0;
int32_t iCode;
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
WELS_CHECK_SE_BOTH_ERROR_NOLOG (uiCode, 0, 7, "luma_log2_weight_denom",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_LOG2_WEIGHT_DENOM));
pSh->sPredWeightTable.uiLumaLog2WeightDenom = uiCode;
if (pSh->pSps->uiChromaArrayType != 0) {
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode));
WELS_CHECK_SE_BOTH_ERROR_NOLOG (uiCode, 0, 7, "chroma_log2_weight_denom",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_LOG2_WEIGHT_DENOM));
pSh->sPredWeightTable.uiChromaLog2WeightDenom = uiCode;
}
do {
for (int i = 0; i < pSh->uiRefCount[iList]; i++) {
//luma
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
if (!!uiCode) {
WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_weight",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_WEIGHT));
pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = iCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "luma_offset",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_LUMA_OFFSET));
pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = iCode;
} else {
pSh->sPredWeightTable.sPredList[iList].iLumaWeight[i] = 1 << (pSh->sPredWeightTable.uiLumaLog2WeightDenom);
pSh->sPredWeightTable.sPredList[iList].iLumaOffset[i] = 0;
}
//chroma
if (pSh->pSps->uiChromaArrayType == 0)
continue;
WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
if (!!uiCode) {
for (int j = 0; j < 2; j++) {
WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_weight",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_WEIGHT));
pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = iCode;
WELS_READ_VERIFY (BsGetSe (pBs, &iCode));
WELS_CHECK_SE_BOTH_ERROR_NOLOG (iCode, -128, 127, "chroma_offset",
GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_CHROMA_OFFSET));
pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = iCode;
}
} else {
for (int j = 0; j < 2; j++) {
pSh->sPredWeightTable.sPredList[iList].iChromaWeight[i][j] = 1 << (pSh->sPredWeightTable.uiChromaLog2WeightDenom);
pSh->sPredWeightTable.sPredList[iList].iChromaOffset[i][j] = 0;
}
}
}
++iList;
} while (iList < LIST_1);//TODO: SUPPORT LIST_A
return ERR_NONE;
}
/*
* Predeclared function routines ..
*/
@@ -308,12 +458,32 @@ int32_t InitBsBuffer (PWelsDecoderContext pCtx) {
return ERR_INFO_INVALID_PTR;
pCtx->iMaxBsBufferSizeInByte = MIN_ACCESS_UNIT_CAPACITY * MAX_BUFFERED_NUM;
if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc (pCtx->iMaxBsBufferSizeInByte,
if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMallocz (pCtx->iMaxBsBufferSizeInByte,
"pCtx->sRawData.pHead"))) == NULL) {
return ERR_INFO_OUT_OF_MEMORY;
}
pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead;
pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte;
if (pCtx->bParseOnly) {
pCtx->pParserBsInfo = static_cast<SParserBsInfo*> (WelsMallocz (sizeof (SParserBsInfo), "pCtx->pParserBsInfo"));
if (pCtx->pParserBsInfo == NULL) {
return ERR_INFO_OUT_OF_MEMORY;
}
memset (pCtx->pParserBsInfo, 0, sizeof (SParserBsInfo));
pCtx->pParserBsInfo->pDstBuff = static_cast<uint8_t*> (WelsMallocz (MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t),
"pCtx->pParserBsInfo->pDstBuff"));
if (pCtx->pParserBsInfo->pDstBuff == NULL) {
return ERR_INFO_OUT_OF_MEMORY;
}
memset (pCtx->pParserBsInfo->pDstBuff, 0, MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t));
if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (WelsMallocz (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;
}
@@ -323,7 +493,7 @@ int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) {
int32_t iExpandStepShift = 1;
int32_t iNewBuffLen = WELS_MAX ((kiSrcLen * MAX_BUFFERED_NUM), (pCtx->iMaxBsBufferSizeInByte << iExpandStepShift));
//allocate new bs buffer
uint8_t* pNewBsBuff = static_cast<uint8_t*> (WelsMalloc (iNewBuffLen, "pCtx->sRawData.pHead"));
uint8_t* pNewBsBuff = static_cast<uint8_t*> (WelsMallocz (iNewBuffLen, "pCtx->sRawData.pHead"));
if (pNewBsBuff == NULL)
return ERR_INFO_OUT_OF_MEMORY;
@@ -384,8 +554,6 @@ int32_t WelsInitMemory (PWelsDecoderContext pCtx) {
pCtx->uiTargetDqId = (uint8_t) - 1;
pCtx->bEndOfStreamFlag = false;
pCtx->iImgWidthInPixel = 0;
pCtx->iImgHeightInPixel = 0;
return ERR_NONE;
}
@@ -414,8 +582,24 @@ void WelsFreeMemory (PWelsDecoderContext pCtx) {
pCtx->sRawData.pEnd = NULL;
pCtx->sRawData.pStartPos = NULL;
pCtx->sRawData.pCurPos = NULL;
if (pCtx->bParseOnly) {
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;
if (pCtx->pParserBsInfo) {
if (pCtx->pParserBsInfo->pDstBuff) {
WelsFree (pCtx->pParserBsInfo->pDstBuff, "pCtx->pParserBsInfo->pDstBuff");
pCtx->pParserBsInfo->pDstBuff = NULL;
}
WelsFree (pCtx->pParserBsInfo, "pCtx->pParserBsInfo");
pCtx->pParserBsInfo = NULL;
}
}
}
/*
* DecodeNalHeaderExt
* Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT
@@ -451,6 +635,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
@@ -538,15 +723,21 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
//add check PPS available here
if (pCtx->bPpsAvailFlags[iPpsId] == false) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "PPS id is invalid!");
pCtx->sDecoderStatistics.iPpsReportErrorNum++;
if (pCtx->iPPSLastInvalidId != iPpsId) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "PPS id (%d) is invalid, previous id (%d) error ignored (%d)!", iPpsId,
pCtx->iPPSLastInvalidId, pCtx->iPPSInvalidNum);
pCtx->iPPSLastInvalidId = iPpsId;
pCtx->iPPSInvalidNum = 0;
} else {
pCtx->iPPSInvalidNum++;
}
pCtx->iErrorCode |= dsNoParamSets;
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);
}
pCtx->iPPSLastInvalidId = -1;
if (pCtx->iOverwriteFlags & OVERWRITE_PPS)
pPps = &pCtx->sPpsBuffer[MAX_PPS_COUNT];
else
pPps = &pCtx->sPpsBuffer[iPpsId];
pPps = &pCtx->sPpsBuffer[iPpsId];
if (pPps->uiNumSliceGroups == 0) {
WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
@@ -555,26 +746,38 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
}
if (kbExtensionFlag) {
if (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS)
pSubsetSps = &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT];
else
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
pSps = &pSubsetSps->sSps;
if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id is invalid!");
pCtx->sDecoderStatistics.iSubSpsReportErrorNum++;
if (pCtx->iSubSPSLastInvalidId != pPps->iSpsId) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "Sub SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,
pCtx->iSubSPSLastInvalidId, pCtx->iSubSPSInvalidNum);
pCtx->iSubSPSLastInvalidId = pPps->iSpsId;
pCtx->iSubSPSInvalidNum = 0;
} else {
pCtx->iSubSPSInvalidNum++;
}
pCtx->iErrorCode |= dsNoParamSets;
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
}
pCtx->iSubSPSLastInvalidId = -1;
} else {
if (pCtx->bSpsAvailFlags[pPps->iSpsId] == false) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id is invalid!");
pCtx->sDecoderStatistics.iSpsReportErrorNum++;
if (pCtx->iSPSLastInvalidId != pPps->iSpsId) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id (%d) is invalid, previous id (%d) error ignored (%d)!", pPps->iSpsId,
pCtx->iSPSLastInvalidId, pCtx->iSPSInvalidNum);
pCtx->iSPSLastInvalidId = pPps->iSpsId;
pCtx->iSPSInvalidNum = 0;
} else {
pCtx->iSPSInvalidNum++;
}
pCtx->iErrorCode |= dsNoParamSets;
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
}
if (pCtx->iOverwriteFlags & OVERWRITE_SPS)
pSps = &pCtx->sSpsBuffer[MAX_SPS_COUNT];
else
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
pCtx->iSPSLastInvalidId = -1;
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
}
pSliceHead->iPpsId = iPpsId;
pSliceHead->iSpsId = pPps->iSpsId;
@@ -584,6 +787,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");
@@ -681,6 +885,14 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
return iRet;
}
if (pPps->bWeightedPredFlag && (uiSliceType == P_SLICE)) {
iRet = ParsePredWeightedTable (pBs, pSliceHead);
if (iRet != ERR_NONE) {
WelsLog (pLogCtx, WELS_LOG_WARNING, "invalid weighted prediction syntaxs!");
return iRet;
}
}
if (kbExtensionFlag) {
if (pNalHeaderExt->iNoInterLayerPredFlag || pNalHeaderExt->uiQualityId > 0)
pSliceHeadExt->bBasePredWeightTableFlag = false;
@@ -707,8 +919,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 +1058,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 +1188,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;
@@ -1004,51 +1223,58 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid
UninitialDqLayersContext (pCtx);
do {
PDqLayer pDq = (PDqLayer)WelsMalloc (sizeof (SDqLayer), "PDqLayer");
PDqLayer pDq = (PDqLayer)WelsMallocz (sizeof (SDqLayer), "PDqLayer");
if (pDq == NULL)
return ERR_INFO_OUT_OF_MEMORY;
memset (pDq, 0, sizeof (SDqLayer));
pCtx->sMb.pMbType[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
pCtx->sMb.pMbType[i] = (int8_t*)WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pMbType[]");
pCtx->sMb.pMv[i][0] = (int16_t (*)[16][2])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
pCtx->sMb.pMv[i][0] = (int16_t (*)[16][2])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMv[][]");
pCtx->sMb.pRefIndex[i][0] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
pCtx->sMb.pRefIndex[i][0] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (
int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pRefIndex[][]");
pCtx->sMb.pLumaQp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
pCtx->sMb.pLumaQp[i] = (int8_t*)WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pLumaQp[]");
pCtx->sMb.pChromaQp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
pCtx->sMb.pChromaQp[i] = (int8_t (*)[2])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 2,
"pCtx->sMb.pChromaQp[]");
pCtx->sMb.pNzc[i] = (int8_t (*)[24])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
pCtx->sMb.pMvd[i][0] = (int16_t (*)[16][2])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]");
pCtx->sMb.pCbfDc[i] = (uint8_t*)WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint8_t),
"pCtx->sMb.pCbfDc[]");
pCtx->sMb.pNzc[i] = (int8_t (*)[24])WelsMallocz (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,
pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24,
"pCtx->sMb.pNzcRs[]");
pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (int16_t) * MB_COEFF_LIST_SIZE, "pCtx->sMb.pScaledTCoeff[]");
pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 8,
pCtx->sMb.pIntraPredMode[i] = (int8_t (*)[8])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t) * 8,
"pCtx->sMb.pIntraPredMode[]");
pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
pCtx->sMb.pIntra4x4FinalMode[i] = (int8_t (*)[MB_BLOCK4x4_NUM])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (int8_t) * MB_BLOCK4x4_NUM, "pCtx->sMb.pIntra4x4FinalMode[]");
pCtx->sMb.pChromaPredMode[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
pCtx->sMb.pChromaPredMode[i] = (int8_t*)WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pChromaPredMode[]");
pCtx->sMb.pCbp[i] = (int8_t*)WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
pCtx->sMb.pCbp[i] = (int8_t*)WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pCbp[]");
pCtx->sMb.pSubMbType[i] = (int8_t (*)[MB_PARTITION_SIZE])WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
pCtx->sMb.pSubMbType[i] = (int8_t (*)[MB_PARTITION_SIZE])WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight *
sizeof (
int8_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]");
pCtx->sMb.pSliceIdc[i] = (int32_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t),
pCtx->sMb.pSliceIdc[i] = (int32_t*) WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t),
"pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010
if (pCtx->sMb.pSliceIdc[i] != NULL)
memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
pCtx->sMb.pResidualPredFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
pCtx->sMb.pResidualPredFlag[i] = (int8_t*) WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t),
"pCtx->sMb.pResidualPredFlag[]");
//pCtx->sMb.pMotionPredFlag[i] = (uint8_t *) WelsMalloc(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(uint8_t), "pCtx->sMb.pMotionPredFlag[]");
pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
//pCtx->sMb.pMotionPredFlag[i] = (uint8_t *) WelsMallocz(pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof(uint8_t), "pCtx->sMb.pMotionPredFlag[]");
pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (
int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]");
pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool),
"pCtx->sMb.pMbCorrectlyDecodedFlag[]");
pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) WelsMallocz (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 +1283,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,15 +1296,17 @@ 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])
)
)
memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
pCtx->pDqLayersList[i] = pDq;
++ i;
} while (i < LAYER_NUM_EXCHANGEABLE);
pCtx->bInitialDqLayersMem = true;
pCtx->iPicWidthReq = kiMaxWidth;
pCtx->iPicHeightReq = kiMaxHeight;
@@ -1124,6 +1354,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 +1442,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;
@@ -1217,7 +1461,7 @@ void UninitialDqLayersContext (PWelsDecoderContext pCtx) {
void ResetCurrentAccessUnit (PWelsDecoderContext pCtx) {
PAccessUnit pCurAu = pCtx->pAccessUnitList;
pCurAu->uiStartPos = 0;
pCurAu->uiEndPos = 0;
pCurAu->bCompletedAuFlag = false;
if (pCurAu->uiActualUnitsNum > 0) {
@@ -1262,6 +1506,7 @@ void ForceResetCurrentAccessUnit (PAccessUnit pAu) {
else
pAu->uiAvailUnitsNum = 0;
pAu->uiActualUnitsNum = 0;
pAu->uiStartPos = 0;
pAu->uiEndPos = 0;
pAu->bCompletedAuFlag = false;
}
@@ -1272,6 +1517,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;
@@ -1627,6 +1884,22 @@ static void WriteBackActiveParameters (PWelsDecoderContext pCtx) {
}
pCtx->iOverwriteFlags = OVERWRITE_NONE;
}
/*
* DecodeFinishUpdate
* decoder finish decoding, update active parameter sets and new seq status
*
*/
void DecodeFinishUpdate (PWelsDecoderContext pCtx) {
pCtx->bNewSeqBegin = false;
WriteBackActiveParameters (pCtx);
pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
pCtx->bNextNewSeqBegin = false; // reset it
if (pCtx->bNewSeqBegin)
ResetActiveSPSForEachLayer (pCtx);
}
/*
* ConstructAccessUnit
* construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
@@ -1642,7 +1915,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 +1924,12 @@ 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;
pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
pCtx->bNextNewSeqBegin = false; // reset it
if (pCtx->bNewSeqBegin)
ResetActiveSPSForEachLayer (pCtx);
return iErr;
}
@@ -1670,17 +1947,10 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
}
}
iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo);
WelsDecodeAccessUnitEnd (pCtx);
pCtx->bNewSeqBegin = false;
WriteBackActiveParameters (pCtx);
pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
pCtx->bNextNewSeqBegin = false; // reset it
if (pCtx->bNewSeqBegin)
ResetActiveSPSForEachLayer (pCtx);
if (ERR_NONE != iErr) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "returned error from decoding:[0x%x]", iErr);
return iErr;
@@ -1720,6 +1990,14 @@ static inline void InitDqLayerInfo (PDqLayer pDqLayer, PLayerInfo pLayerInfo, PN
if (kuiQualityId == BASE_QUALITY_ID) {
pDqLayer->pRefPicListReordering = &pSh->pRefPicListReordering;
pDqLayer->pRefPicMarking = &pSh->sRefMarking;
if (pSh->pPps->bWeightedPredFlag) {
pDqLayer->bUseWeightPredictionFlag = true;
pDqLayer->pPredWeightTable = &pSh->sPredWeightTable;
} else
pDqLayer->bUseWeightPredictionFlag = false;
pDqLayer->pRefPicBaseMarking = &pShExt->sRefBasePicMarking;
}
@@ -1754,6 +2032,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 +2045,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.
@@ -1817,6 +2090,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
if (pCtx->pDec == NULL) {
pCtx->pDec = PrefetchPic (pCtx->pPicBuff[0]);
if (pCtx->iTotalNumMbRec != 0)
pCtx->iTotalNumMbRec = 0;
if (NULL == pCtx->pDec) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
@@ -1825,13 +2100,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 +2131,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 +2194,6 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
#else
pCtx->bReferenceLostAtT0Flag = true;
#endif
ResetParameterSetsState (pCtx);
return ERR_INFO_REFERENCE_PIC_LOST;
}
}
@@ -1919,12 +2202,15 @@ 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,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
"reference picture introduced by this frame is lost during transmission! uiTId: %d",
pNalCur->sNalHeaderExt.uiTemporalId);
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
if (pCtx->iTotalNumMbRec == 0)
pCtx->pDec = NULL;
return iRet;
}
}
@@ -1940,17 +2226,24 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
bAllRefComplete = false;
HandleReferenceLostL0 (pCtx, pNalCur);
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
if (pCtx->iTotalNumMbRec == 0)
pCtx->pDec = NULL;
return iRet;
}
}
if (bReconstructSlice) {
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)
@@ -1990,21 +2283,23 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
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) {
//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;
}
iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
if (iRet)
return iRet;
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) {
@@ -2012,11 +2307,12 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
return iRet;
}
}
ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel,
pCtx->pDec->iLinesize,
pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
pCtx->pDec = NULL;
if (!pCtx->bParseOnly)
ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel,
pCtx->pDec->iLinesize,
pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
}
pCtx->pDec = NULL; //after frame decoding, always set to NULL
}
// need update frame_num due current frame is well decoded
@@ -2030,36 +2326,59 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
PAccessUnit pAu = pCtx->pAccessUnitList;
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
if ((pCtx->iTotalNumMbRec != 0)
&& (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
&pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader))) {
//Do Error Concealment here
if (NeedErrorCon (pCtx)) { //should always be true!
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
ImplementErrorCon (pCtx);
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
MarkECFrameAsRef (pCtx);
}
} else {
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo))
return false;
}
pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
if (pCtx->bLastHasMmco5)
pCtx->iPrevFrameNum = 0;
bool bAuBoundaryFlag = false;
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) { //VCL data, AU list should have data
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
bAuBoundaryFlag = (pCtx->iTotalNumMbRec != 0)
&& (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
&pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader));
} else { //non VCL
if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_AU_DELIMITER) {
bAuBoundaryFlag = true;
} else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SEI) {
bAuBoundaryFlag = true;
} else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SPS) {
bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_SPS);
} else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SUBSET_SPS) {
bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS);
} else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_PPS) {
bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_PPS);
}
if (bAuBoundaryFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) { //Construct remaining data first
ConstructAccessUnit (pCtx, ppDst, pDstInfo);
}
}
//Do Error Concealment here
if (bAuBoundaryFlag && (pCtx->iTotalNumMbRec != 0) && NeedErrorCon (pCtx)) { //AU ready but frame not completely reconed
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
ImplementErrorCon (pCtx);
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
MarkECFrameAsRef (pCtx);
}
} else if (pCtx->bParseOnly) { //clear parse only internal data status
pCtx->pParserBsInfo->iNalNum = 0;
} else {
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;
}
return ERR_NONE;
}
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx) {
bool CheckRefPicturesComplete (PWelsDecoderContext pCtx) {
// Multi Reference, RefIdx may differ
bool bAllRefComplete = true;
int32_t iRealMbIdx;

View File

@@ -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,
@@ -84,12 +134,21 @@ const uint8_t g_kuiIntra4x4CbpTable[48] = {
8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41 //47
};
const uint8_t g_kuiIntra4x4CbpTable400[16] = {
15, 0, 7, 11, 13, 14, 3, 5, 10, 12, 1, 2, 4, 8, 6, 9
};
const uint8_t g_kuiInterCbpTable[48] = {
0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13, //15
14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46, //31
17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41 //47
};
const uint8_t g_kuiInterCbpTable400[16] = {
0, 1, 2, 4, 8, 3, 5, 10, 12, 15, 7, 11, 13, 14, 6, 9
};
const uint8_t g_kuiLeadingZeroTable[256] = {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,

View File

@@ -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,10 +121,11 @@ 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
pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;;
pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;
pSrcData = pSrcPic->pData[0] + iMbY * 16 * iSrcStride + iMbX * 16;
pCtx->sCopyFunc.pCopyLumaFunc (pDstData, iDstStride, pSrcData, iSrcStride);
//U 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.

View File

@@ -39,7 +39,7 @@
*/
#include "fmo.h"
#include "mem_align.h"
#include "memory_align.h"
namespace WelsDec {
@@ -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;
@@ -133,7 +133,7 @@ static inline int32_t FmoGenerateSliceGroup (PFmo pFmo, const PPps kpPps, const
WelsFree (pFmo->pMbAllocMap, "_fmo->pMbAllocMap");
pFmo->pMbAllocMap = (uint8_t*)WelsMalloc (iNumMb * sizeof (uint8_t), "_fmo->pMbAllocMap");
pFmo->pMbAllocMap = (uint8_t*)WelsMallocz (iNumMb * sizeof (uint8_t), "_fmo->pMbAllocMap");
WELS_VERIFY_RETURN_IF (1, (NULL == pFmo->pMbAllocMap)) // out of memory
pFmo->iCountMbNum = iNumMb;

View File

@@ -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

View File

@@ -1,100 +0,0 @@
/*!
* \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.
*
*/
#include "mem_align.h"
namespace WelsDec {
//#define MEMORY_CHECK
#ifdef MEMORY_CHECK
WelsFileHandle* pMemCheckMalloc = NULL;
WelsFileHandle* pMemCheckFree = NULL;
int32_t iCountMalloc = 0;
#endif
//
void* WelsMalloc (const uint32_t kuiSize, const char* kpTag) {
const int32_t kiSizeVoidPtr = sizeof (void**);
const int32_t kiSizeInt = sizeof (int32_t);
const int32_t kiAlignBytes = 15;
uint8_t* pBuf = (uint8_t*) malloc (kuiSize + kiAlignBytes + kiSizeVoidPtr + kiSizeInt);
uint8_t* pAlignBuf;
#ifdef MEMORY_CHECK
if (pMemCheckMalloc == NULL) {
pMemCheckMalloc = WelsFopen ("mem_check_malloc.txt", "at+");
pMemCheckFree = WelsFopen ("mem_check_free.txt", "at+");
}
if (kpTag != NULL) {
if (pMemCheckMalloc != NULL) {
fprintf (pMemCheckMalloc, "0x%x, size: %d , malloc %s\n", (void*)pBuf,
(kuiSize + kiAlignBytes + kiSizeVoidPtr + kiSizeInt), kpTag);
}
if (pMemCheckMalloc != NULL) {
fflush (pMemCheckMalloc);
}
}
#endif
if (NULL == pBuf)
return NULL;
// to fill zero values
memset (pBuf, 0, kuiSize + kiAlignBytes + kiSizeVoidPtr + kiSizeInt);
pAlignBuf = pBuf + kiAlignBytes + kiSizeVoidPtr + kiSizeInt;
pAlignBuf -= (uintptr_t) pAlignBuf & kiAlignBytes;
* ((void**) (pAlignBuf - kiSizeVoidPtr)) = pBuf;
* ((int32_t*) (pAlignBuf - (kiSizeVoidPtr + kiSizeInt))) = kuiSize;
return (pAlignBuf);
}
/////////////////////////////////////////////////////////////////////////////
void WelsFree (void* pPtr, const char* kpTag) {
if (pPtr) {
#ifdef MEMORY_CHECK
if (NULL != pMemCheckFree && kpTag != NULL) {
fprintf (pMemCheckFree, "0x%x, free %s\n", (void*) (* (((void**) pPtr) - 1)), kpTag);
fflush (pMemCheckFree);
}
#endif
free (* (((void**) pPtr) - 1));
}
}
/////////////////////////////////////////////////////////////////////////////
} // namespace WelsDec

View File

@@ -39,7 +39,7 @@
*
*****************************************************************************/
#include "memmgr_nal_unit.h"
#include "mem_align.h"
#include "memory_align.h"
namespace WelsDec {
@@ -58,7 +58,7 @@ int32_t MemInitNalList (PAccessUnit* ppAu, const uint32_t kuiSize) {
MemFreeNalList (ppAu);
}
pBase = (uint8_t*)WelsMalloc (kuiCountSize, "Access Unit");
pBase = (uint8_t*)WelsMallocz (kuiCountSize, "Access Unit");
if (pBase == NULL)
return 1;
pPtr = pBase;
@@ -75,7 +75,8 @@ int32_t MemInitNalList (PAccessUnit* ppAu, const uint32_t kuiSize) {
(*ppAu)->uiCountUnitsNum = kuiSize;
(*ppAu)->uiAvailUnitsNum = 0;
(*ppAu)->uiActualUnitsNum = 0;
(*ppAu)->uiEndPos = 0;
(*ppAu)->uiStartPos = 0;
(*ppAu)->uiEndPos = 0;
(*ppAu)->bCompletedAuFlag = false;
return 0;

View File

@@ -0,0 +1,933 @@
/*!
* \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;
if (pCtx->pSps->uiChromaFormatIdc == 0)//monochroma
return ERR_NONE;
//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;
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};
int32_t iMbResProperty = 0;
GetMbResProperty (&iMbResProperty, &iResProperty, false);
const uint16_t* pDeQuantMul = (pCtx->bUseScalingList) ? pCtx->pDequant_coeff4x4[iMbResProperty][uiQp] :
g_kuiDequantCoeff[uiQp];
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]] = pCtx->bUseScalingList ? (pSignificantMap[j] * pDeQuantMul[0]) >> 4 :
(pSignificantMap[j] * pDeQuantMul[0]);
++j;
} while (j < 16);
} else { //luma ac, chroma ac
do {
if (pSignificantMap[j] != 0)
sTCoeff[pScanTable[j]] = pCtx->bUseScalingList ? (pSignificantMap[j] * pDeQuantMul[pScanTable[j]] >> 4) :
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] = pCurLayer->pChromaQp[iMbXy][1] = 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;
}
}

View File

@@ -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,7 +236,140 @@ void WelsFillCacheConstrain0Intra4x4 (PNeighAvail pNeighAvail, uint8_t* pNonZero
}
}
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) {
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;
@@ -298,7 +432,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 +439,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 +451,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 +462,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 +488,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) && \
@@ -670,7 +797,13 @@ int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCach
int32_t iLevel[16], iZerosLeft, iCoeffNum;
int32_t iRun[16];
int32_t iCurNonZeroCacheIdx, i;
const uint16_t* kpDequantCoeff = g_kuiDequantCoeff[uiQp];
int32_t iMbResProperty = 0;
GetMbResProperty (&iMbResProperty, &iResidualProperty, 1);
const uint16_t* kpDequantCoeff = pCtx->bUseScalingList ? pCtx->pDequant_coeff4x4[iMbResProperty][uiQp] :
g_kuiDequantCoeff[uiQp];
int8_t nA, nB, nC;
uint8_t uiTotalCoeff, uiTrailingOnes;
int32_t iUsedBits = 0;
@@ -739,7 +872,7 @@ int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCach
int32_t j;
iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
j = kpZigzagTable[ iCoeffNum ];
pTCoeff[j] = iLevel[i] * kpDequantCoeff[0];
pTCoeff[j] = pCtx->bUseScalingList ? (iLevel[i] * kpDequantCoeff[0]) >> 4 : (iLevel[i] * kpDequantCoeff[0]);
}
} else if (iResidualProperty == I16_LUMA_DC) { //DC coefficent, only call in Intra_16x16, base_mode_flag = 0
for (i = uiTotalCoeff - 1; i >= 0; --i) { //FIXME merge into rundecode?
@@ -753,223 +886,13 @@ int32_t WelsResidualBlockCavlc (SVlcTable* pVlcTable, uint8_t* pNonZeroCountCach
int32_t j;
iCoeffNum += iRun[i] + 1; //FIXME add 1 earlier ?
j = kpZigzagTable[ iCoeffNum ];
pTCoeff[j] = iLevel[i] * kpDequantCoeff[j & 0x07];
pTCoeff[j] = pCtx->bUseScalingList ? (iLevel[i] * kpDequantCoeff[j]) >> 4 : (iLevel[i] * kpDequantCoeff[j & 0x07]);
}
}
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 +926,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 +934,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 +966,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 +974,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 +1002,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 +1010,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 +1070,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 +1078,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];

View File

@@ -40,7 +40,7 @@
#include "pic_queue.h"
#include "decoder_context.h"
#include "codec_def.h"
#include "mem_align.h"
#include "memory_align.h"
namespace WelsDec {
@@ -69,7 +69,7 @@ PPicture AllocPicture (PWelsDecoderContext pCtx, const int32_t kiPicWidth, const
int32_t iLumaSize = 0;
int32_t iChromaSize = 0;
pPic = (PPicture) WelsMalloc (sizeof (SPicture), "PPicture");
pPic = (PPicture) WelsMallocz (sizeof (SPicture), "PPicture");
WELS_VERIFY_RETURN_IF (NULL, NULL == pPic);
memset (pPic, 0, sizeof (SPicture));
@@ -81,21 +81,26 @@ 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)));
WELS_VERIFY_RETURN_PROC_IF (NULL, NULL == pPic->pBuffer[0], FreePicture (pPic));
pPic->iLinesize[0] = iPicWidth;
pPic->iLinesize[1] = pPic->iLinesize[2] = iPicChromaWidth;
pPic->pBuffer[1] = pPic->pBuffer[0] + iLumaSize;
pPic->pBuffer[2] = pPic->pBuffer[1] + iChromaSize;
pPic->pData[0] = pPic->pBuffer[0] + (1 + pPic->iLinesize[0]) * PADDING_LENGTH;
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);
if (pCtx->bParseOnly) {
pPic->pBuffer[0] = pPic->pBuffer[1] = pPic->pBuffer[2] = NULL;
pPic->pData[0] = pPic->pData[1] = pPic->pData[2] = NULL;
pPic->iLinesize[0] = iPicWidth;
pPic->iLinesize[1] = pPic->iLinesize[2] = iPicChromaWidth;
} else {
pPic->pBuffer[0] = static_cast<uint8_t*> (WelsMallocz (iLumaSize /* luma */
+ (iChromaSize << 1) /* Cb,Cr */, "_pic->buffer[0]"));
WELS_VERIFY_RETURN_PROC_IF (NULL, NULL == pPic->pBuffer[0], FreePicture (pPic));
memset (pPic->pBuffer[0], 128, (iLumaSize + (iChromaSize << 1)));
pPic->iLinesize[0] = iPicWidth;
pPic->iLinesize[1] = pPic->iLinesize[2] = iPicChromaWidth;
pPic->pBuffer[1] = pPic->pBuffer[0] + iLumaSize;
pPic->pBuffer[2] = pPic->pBuffer[1] + iChromaSize;
pPic->pData[0] = pPic->pBuffer[0] + (1 + pPic->iLinesize[0]) * PADDING_LENGTH;
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;

View File

@@ -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,
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;
void BaseMC (sMCRefMember* pMCRefMem, int32_t iXOffset, int32_t iYOffset, SMcFunc* pMCFunc,
int32_t iBlkWidth, int32_t iBlkHeight, int16_t iMVs[2]) {
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,60 +204,84 @@ 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;
}
void WeightPrediction (PDqLayer pCurDqLayer, sMCRefMember* pMCRefMem, int32_t iRefIdx, int32_t iBlkWidth,
int32_t iBlkHeight) {
int32_t iLog2denom, iWoc, iOoc;
int32_t iPredTemp, iLineStride;
int32_t iPixel = 0;
uint8_t* pDst;
//luma
iLog2denom = pCurDqLayer->pPredWeightTable->uiLumaLog2WeightDenom;
iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaWeight[iRefIdx];
iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iLumaOffset[iRefIdx];
iLineStride = pMCRefMem->iDstLineLuma;
for (int i = 0; i < iBlkHeight; i++) {
for (int j = 0; j < iBlkWidth; j++) {
iPixel = j + i * (iLineStride);
if (iLog2denom >= 1) {
iPredTemp = ((pMCRefMem->pDstY[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
} else {
iPredTemp = pMCRefMem->pDstY[iPixel] * iWoc + iOoc;
pMCRefMem->pDstY[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
}
}
}
#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);
//UV
iBlkWidth = iBlkWidth >> 2;
iBlkHeight = iBlkHeight >> 2;
iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
iLineStride = pMCRefMem->iDstLineChroma;
for (int i = 0; i < 2; i++) {
//iLog2denom = pCurDqLayer->pPredWeightTable->uiChromaLog2WeightDenom;
iWoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaWeight[iRefIdx][i];
iOoc = pCurDqLayer->pPredWeightTable->sPredList[LIST_0].iChromaOffset[iRefIdx][i];
pDst = i ? pMCRefMem->pDstV : pMCRefMem->pDstU;
//iLineStride = pMCRefMem->iDstLineChroma;
for (int i = 0; i < iBlkHeight ; i++) {
for (int j = 0; j < iBlkWidth; j++) {
iPixel = j + i * (iLineStride);
if (iLog2denom >= 1) {
iPredTemp = ((pDst[iPixel] * iWoc + (1 << (iLog2denom - 1))) >> iLog2denom) + iOoc;
pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
} else {
iPredTemp = pDst[iPixel] * iWoc + iOoc;
pDst[iPixel] = WELS_CLIP3 (iPredTemp, 0, 255);
}
}
}
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) {
sMCRefMember pMCRefMem;
PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
@@ -317,6 +310,9 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
pMCRefMem.iDstLineLuma = iDstLineLuma;
pMCRefMem.iDstLineChroma = iDstLineChroma;
int32_t iRefIndex = 0;
switch (iMBType) {
case MB_TYPE_SKIP:
case MB_TYPE_16x16:
@@ -324,6 +320,11 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 16);
}
break;
case MB_TYPE_16x8:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
@@ -331,6 +332,11 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);
}
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][8][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][8][1];
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8);
@@ -338,12 +344,21 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);
pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY + 8, pMCFunc, 16, 8, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][8];
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 16, 8);
}
break;
case MB_TYPE_8x16:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0);
BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);
}
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][2][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][2][1];
@@ -352,6 +367,11 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
pMCRefMem.pDstU = pPredCb + 4;
pMCRefMem.pDstV = pPredCr + 4;
BaseMC (&pMCRefMem, iMBOffsetX + 8, iMBOffsetY, pMCFunc, 8, 16, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][2];
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 16);
}
break;
case MB_TYPE_8x8:
case MB_TYPE_8x8_REF0: {
@@ -367,6 +387,7 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx);
iRefIndex = pCurDqLayer->bUseWeightPredictionFlag ? pCurDqLayer->pRefIndex[0][iMBXY][iIIdx] : 0;
pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;
pDstU = pPredCb + (iBlk8X >> 1) + (iBlk8Y >> 1) * iDstLineChroma;
@@ -379,11 +400,21 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 8, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 8);
}
break;
case SUB_MB_TYPE_8x4:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 8, 4, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);
}
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 4][1];
@@ -391,11 +422,21 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
pMCRefMem.pDstU += (iDstLineChroma << 1);
pMCRefMem.pDstV += (iDstLineChroma << 1);
BaseMC (&pMCRefMem, iXOffset, iYOffset + 4, pMCFunc, 8, 4, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 8, 4);
}
break;
case SUB_MB_TYPE_4x8:
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx][1];
BaseMC (&pMCRefMem, iXOffset, iYOffset, pMCFunc, 4, 8, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);
}
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + 1][1];
@@ -403,6 +444,11 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
pMCRefMem.pDstU += 2;
pMCRefMem.pDstV += 2;
BaseMC (&pMCRefMem, iXOffset + 4, iYOffset, pMCFunc, 4, 8, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 8);
}
break;
case SUB_MB_TYPE_4x4: {
for (j = 0; j < 4; j++) {
@@ -420,6 +466,11 @@ void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDec
iMVs[0] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][0];
iMVs[1] = pCurDqLayer->pMv[0][iMBXY][iIIdx + iJIdx][1];
BaseMC (&pMCRefMem, iXOffset + iBlk4X, iYOffset + iBlk4Y, pMCFunc, 4, 4, iMVs);
if (pCurDqLayer->bUseWeightPredictionFlag) {
WeightPrediction (pCurDqLayer, &pMCRefMem, iRefIndex, 4, 4);
}
}
}
break;
@@ -464,88 +515,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

View File

@@ -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

View File

@@ -259,6 +259,13 @@ WELS_EXTERN WelsDecoderI16x16LumaPredPlane_sse2
pmullw xmm7, xmm6
psubw xmm7, xmm0
; Indicate that xmm2 is fully initialized. Its actual value doesn't
; matter in SUMW_HORIZON below, but after being used in LOAD_COLUMN above,
; valgrind thinks that xmm2 contains uninitalized data (if the columns outside
; of the left are uninitialized, such as in DecUT_IntraPrediction), which taints
; r2d below, even if actually isn't based on the uninitialized data.
pxor xmm2, xmm2
SUMW_HORIZON xmm7,xmm0,xmm2
movd r2d, xmm7 ; V
movsx r2, r2w

View File

@@ -81,6 +81,11 @@ virtual DECODING_STATE EXTAPI DecodeFrame (const unsigned char* kpSrc,
int& iWidth,
int& iHeight);
virtual DECODING_STATE EXTAPI DecodeFrameNoDelay (const unsigned char* kpSrc,
const int kiSrcLen,
unsigned char** ppDst,
SBufferInfo* pDstInfo);
virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* kpSrc,
const int kiSrcLen,
unsigned char** ppDst,
@@ -104,7 +109,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

View File

@@ -44,7 +44,7 @@
#include "welsCodecTrace.h"
#include "codec_def.h"
#include "typedefs.h"
#include "mem_align.h"
#include "memory_align.h"
#include "utils.h"
#include "version.h"
@@ -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);
m_pDecContext = (PWelsDecoderContext)WelsMalloc (sizeof (SWelsDecoderContext), "m_pDecContext");
if (m_pDecContext) //free
UninitDecoder();
m_pDecContext = (PWelsDecoderContext)WelsMallocz (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);
}
/*
@@ -254,6 +258,11 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
return dsInitialOptExpected;
if (eOptID == DECODER_OPTION_DATAFORMAT) { // Set color space of decoding output frame
if (m_pDecContext->bParseOnly) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
"CWelsDecoder::SetOption for data format meaningless for parseonly.");
return cmResultSuccess;
}
if (pOption == NULL)
return cmInitParaError;
@@ -274,8 +283,14 @@ 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;
if ((m_pDecContext->bParseOnly) && (m_pDecContext->eErrorConMethod != ERROR_CON_DISABLE)) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);
return cmInitParaError;
}
InitErrorCon (m_pDecContext);
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
@@ -301,8 +316,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,11 +378,38 @@ 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;
}
DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc,
const int kiSrcLen,
unsigned char** ppDst,
SBufferInfo* pDstInfo) {
int iRet;
SBufferInfo sTmpBufferInfo;
iRet = (int) DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);
memcpy (&sTmpBufferInfo, pDstInfo, sizeof (SBufferInfo));
iRet |= DecodeFrame2 (NULL, 0, ppDst, pDstInfo);
if ((pDstInfo->iBufferStatus == 0) && (sTmpBufferInfo.iBufferStatus == 1)) {
memcpy (pDstInfo, &sTmpBufferInfo, sizeof (SBufferInfo));
}
return (DECODING_STATE) iRet;
}
DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
const int kiSrcLen,
unsigned char** ppDst,
@@ -389,11 +436,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 +452,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 +467,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 +479,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 +496,103 @@ 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->eErrorConMethod = ERROR_CON_DISABLE; //add protection to disable EC here.
if (!m_pDecContext->bFramePending) { //frame complete
m_pDecContext->pParserBsInfo->iNalNum = 0;
memset (m_pDecContext->pParserBsInfo->iNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
}
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);
if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {
memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
}
m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
return (DECODING_STATE) m_pDecContext->iErrorCode;
}

View File

@@ -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\
@@ -12,10 +13,9 @@ DECODER_CPP_SRCS=\
$(DECODER_SRCDIR)/core/src/fmo.cpp\
$(DECODER_SRCDIR)/core/src/get_intra_predictor.cpp\
$(DECODER_SRCDIR)/core/src/manage_dec_ref.cpp\
$(DECODER_SRCDIR)/core/src/mc.cpp\
$(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\

View File

@@ -139,16 +139,5 @@ $(TargetPath)
#endif//MB_TYPES_CHECK
#endif//MB_TYPES_INFO_OUTPUT
// NOTE: please do not clean below lines even comment, turn on for potential memory leak verify and memory usage monitor etc.
//#define MEMORY_CHECK
#define MEMORY_MONITOR
#ifdef MEMORY_CHECK
#ifndef MEMORY_MONITOR
#define MEMORY_MONITOR
#endif//MEMORY_MONITOR
#endif//MEMORY_CHECK
#endif // AS264_COMMON_H_

View File

@@ -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,bool bSVCBaselayer);
/*!
* \brief initialize subset pSps based on configurable parameters in svc
@@ -120,7 +121,8 @@ int32_t WelsInitSps (SWelsSPS* pSps, SSpatialLayerConfig* pLayerParam, SSpatialL
int32_t WelsInitSubsetSps (SSubsetSps* pSubsetSps, 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 pPps based on configurable parameters and pSps(subset pSps) in svc
@@ -138,7 +140,29 @@ int32_t WelsInitPps (SWelsPPS* pPps,
SSubsetSps* pSubsetSps,
const uint32_t kuiPpsId,
const bool kbDeblockingFilterPresentFlag,
const bool kbUsingSubsetSps);
int32_t WelsCheckRefFrameLimitation (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
const bool kbUsingSubsetSps,
const bool kbEntropyCodingModeFlag);
int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
int32_t WelsAdjustLevel (SSpatialLayerConfig* pSpatialLayer);
/*!
* \brief check if the current parameter can found a presenting sps
* \param pParam the current encoding paramter in SWelsSvcCodingParam
* \param kbUseSubsetSps bool
* \param iDlayerIndex int, the index of current D layer
* \param iDlayerCount int, the number of total D layer
* \param pSpsArray array of all the stored SPSs
* \param pSubsetArray array of all the stored Subset-SPSs
* \return 0 - successful
* -1 - cannot find existing SPS for current encoder parameter
*/
int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
const int32_t iDlayerCount, const int32_t iSpsNumInUse,
SWelsSPS* pSpsArray,
SSubsetSps* pSubsetArray,
bool bSVCBaselayer);
}
#endif//WELS_ACCESS_UNIT_PARSER_H__

View File

@@ -65,12 +65,10 @@ typedef struct TagDeblockingFilter {
extern "C" {
#endif//__cplusplus
#if defined(HAVE_NEON)
void WelsNonZeroCount_neon (int8_t* pNonZeroCount);
void DeblockingBSCalcEnc_neon (int8_t* pNzc, SMVUnitXY* pMv, int32_t iBoundryFlag, int32_t iMbStride,
uint8_t (*pBS)[4][4]);
#endif
#if defined(HAVE_NEON_AARCH64)
void WelsNonZeroCount_AArch64_neon (int8_t* pNonZeroCount);
void DeblockingBSCalcEnc_AArch64_neon (int8_t* pNzc, SMVUnitXY* pMv, int32_t iBoundryFlag, int32_t iMbStride,
uint8_t (*pBS)[4][4]);
#endif
@@ -79,7 +77,6 @@ void DeblockingBSCalcEnc_AArch64_neon (int8_t* pNzc, SMVUnitXY* pMv, int32_t iBo
#endif//__cplusplus
void DeblockingInit (DeblockingFunc* pFunc, int32_t iCpu);
void WelsNonZeroCount_c (int8_t* pNonZeroCount);
void WelsBlockFuncInit (PSetNoneZeroCountZeroFunc* pfSetNZCZero, int32_t iCpu);
void PerformDeblockingFilter (sWelsEncCtx* pEnc);

View File

@@ -48,7 +48,7 @@ namespace WelsEnc {
* \param pEncCtx sWelsEncCtx*
* \return successful - 0; otherwise none 0 for failed
*/
int32_t RequestMemorySvc (sWelsEncCtx** ppCtx);
int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList);
/*!
* \brief free memory in SVC core encoder
@@ -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)

Some files were not shown because too many files have changed in this diff Show More