Compare commits

..

188 Commits

Author SHA1 Message Date
ruil2
825ce5dcd9 Merge pull request #1576 from sijchen/fix_doc
update doc for updated struct
2014-12-01 12:20:30 +08:00
Sijia Chen
6f9624790c update doc for updated struct 2014-11-30 19:36:29 -08:00
ruil2
ca0ed2a067 Merge pull request #1461 from sijchen/v1.2_release1
Update version.h and API doc and release note for v1.2
2014-10-29 09:23:43 +08:00
Sijia Chen
be97ccb45b update version.h and API doc and release note for v1.2 2014-10-28 13:40:13 +08:00
sijchen
6e56e80a8a Merge pull request #1453 from sijchen/v1.2sync
Sync from master in preparation of v1.2
2014-10-27 08:41:32 +08:00
Sijia Chen
4f7602e268 Squashed commit of the following:
commit 2dbb757d30
Merge: 34cb0d6 6a2a4ef
Author: ruil2 <ruil2@cisco.com>
Date:   Fri Oct 24 15:18:55 2014 +0800

    Merge pull request #1451 from sijchen/for_format

    Fixes and change naming

commit 34cb0d60aa
Merge: 468fce0 f0c6891
Author: sijchen <sijchen@cisco.com>
Date:   Fri Oct 24 14:41:51 2014 +0800

    Merge pull request #1450 from mstorsjo/avoid-warnings

    Add casts to avoid warnings about comparison between signed and unsigned

commit 6a2a4efef6
Author: Sijia Chen <sijchen@cisco.com>
Date:   Fri Oct 24 14:39:50 2014 +0800

    fix names to keep consistent of style
    improve UT to cover more cases under GetStatistics

commit ea9b80adb3
Author: Sijia Chen <sijchen@cisco.com>
Date:   Fri Oct 24 14:12:53 2014 +0800

    fix a wrong range clip

commit 468fce0887
Merge: ac290d6 50fd617
Author: sijchen <sijchen@cisco.com>
Date:   Fri Oct 24 14:12:40 2014 +0800

    Merge pull request #1448 from sijchen/for_format

    roll back the file which is mis-formatted by astyle

commit f0c6891627
Author: Martin Storsjö <martin@martin.st>
Date:   Fri Oct 24 09:05:32 2014 +0300

    Add casts to avoid warnings about comparison between signed and unsigned

commit 50fd617e86
Author: Sijia Chen <sijchen@cisco.com>
Date:   Fri Oct 24 13:04:35 2014 +0800

    roll back the file which is mis-formatted by astyle

commit ac290d65c7
Merge: dcdcc7f 3cce92e
Author: ruil2 <ruil2@cisco.com>
Date:   Fri Oct 24 12:50:07 2014 +0800

    Merge pull request #1446 from sijchen/for_format

    [Encoder] fix a small range of slice idx
2014-10-24 18:15:41 +08:00
ruil2
d6ff4304fa Merge pull request #1447 from sijchen/for_format
Sync from master in preparation of v1.2
2014-10-24 12:49:56 +08:00
Sijia Chen
3cce92ea19 fix a small range of slice idx 2014-10-24 12:28:59 +08:00
huili2
dcdcc7f3b8 Merge pull request #1443 from dongzha/AddUTSwitch
add UT for sim-SVC layer switch
2014-10-24 10:21:36 +08:00
sijchen
273e1227a5 Merge pull request #1440 from shihuade/APIUTV1.4
fix bug in set option return value
2014-10-24 09:00:56 +08:00
sijchen
43c62d06eb Merge pull request #1439 from sijchen/for_format
[Reformat] format cpp files for next release
2014-10-24 09:00:36 +08:00
sijchen
5d6b20119a Merge pull request #1442 from mstorsjo/android-pthread-setname
Only use pthread_setname_np on Android >= 9 (2.3)
2014-10-24 09:00:09 +08:00
Ethan Hugg
a594ddf3e7 Merge pull request #1441 from mstorsjo/avoid-warnings
Add casts to avoid warnings about comparison between signed and unsigned
2014-10-23 09:07:19 -07:00
Martin Storsjö
0a3d4c4ebc Only use pthread_setname_np on Android >= 9 (2.3)
Older versions of Android don't have this function.
2014-10-23 15:36:40 +03:00
Martin Storsjö
57aae73d4c Add casts to avoid warnings about comparison between signed and unsigned 2014-10-23 14:20:38 +03:00
huili2
94a1d4426e Merge pull request #1437 from sijchen/after_review2
[Encoder] add a thread name for easier profiling
2014-10-23 18:03:24 +08:00
huili2
23b5a61153 Merge pull request #1429 from sijchen/add_statistics1
[Encoder] add EncoderStatistics
2014-10-23 18:02:23 +08:00
sijchen
33e67427ab Merge pull request #1438 from huili2/EC_crashfix
fix crash bug of sps/pps
2014-10-23 18:01:20 +08:00
Sijia Chen
4e89e71e8f reformat cpp files for unit tests 2014-10-23 17:54:33 +08:00
huashi
8d5863a170 fix bug in set option return value 2014-10-23 17:51:35 +08:00
Sijia Chen
97298de90a reformat cpp files for next release 2014-10-23 17:50:50 +08:00
huili2
3c4279cdd8 fix crash bug of sps/pps 2014-10-23 02:36:08 -07:00
sijchen
452fb868c7 Merge pull request #1432 from mstorsjo/rename-makefiles
Remove the "platform-" prefix from common shared makefiles
2014-10-23 16:40:22 +08:00
Sijia Chen
41720f8df5 add a thread name for easier profiling 2014-10-23 16:38:05 +08:00
dong zhang
769c38d4c4 add UT for sim-SVC switch 2014-10-23 15:50:43 +08:00
Ethan Hugg
195d13612c Merge pull request #1430 from mstorsjo/make-param-reorder
Set LDFLAGS after the object files in shared library linking commands
2014-10-22 09:04:12 -07:00
zhilwang
6c4f0d7d85 Merge pull request #1431 from mstorsjo/msvc-unify-nasm
Unify nasm commands in MSVC project files
2014-10-22 17:09:47 +08:00
Martin Storsjö
e415c3fe70 Remove the "platform-" prefix from common shared makefiles
This makes it clearer which ones actually are real platforms
(chosen automatically or explicitly via "make ARCH=foo") and which
ones just are shared helpers.
2014-10-22 10:18:53 +03:00
Martin Storsjö
b17e9bb320 Make nasm commands in vcproj files consistent
Some commands had different spacing than others, and commands
for some files had accidentally missed a few parameters.
2014-10-22 10:14:22 +03:00
Martin Storsjö
7720f2cc5d Add literal CRLF at the end of nasm commands that are missing them
These are added by MSVC as soon as the file is touched anyway.

This avoids stray changes to the files if the files are resaved
from within the IDE.
2014-10-22 10:14:08 +03:00
Martin Storsjö
88b7a62f98 Set LDFLAGS after the object files in shared library linking commands
This makes sure that the built libopenh264.so actually links to
libpthread.so.
2014-10-22 09:43:53 +03:00
Sijia Chen
a765197b73 add interface and basic implementaion and UT for EncoderStatistics 2014-10-22 11:35:17 +08:00
ruil2
d720122a37 Merge pull request #1426 from sijchen/fix_paramtranscode1
[Encoder] add clip in ParamTranscode for input para checking
2014-10-21 17:23:57 +08:00
Sijia Chen
cbe7891300 add clip in ParamTranscode for input para checking 2014-10-21 16:00:46 +08:00
ruil2
5762cbb8fc Merge pull request #1419 from sijchen/fix_sm4_mt
[Encoder] improve the logic of locking in the function
2014-10-17 16:32:40 +08:00
HaiboZhu
1a78f69f2f Merge pull request #1418 from huili2/EC_option_bugfix
ec disable bug fix
2014-10-17 10:09:39 +08:00
sijchen
d1a3bd3d33 Merge pull request #1416 from ruil2/fix
modify trace level and fix potential issues
2014-10-16 15:21:12 +08:00
ruil2
89454f0cf9 modify trace level and fix potential issues 2014-10-16 14:57:15 +08:00
huili2
9a0d56da97 Merge pull request #1412 from daniel-j-h/clang_cleanup
Clang's -Weverything and Static Analyzer's reports
2014-10-16 14:24:58 +08:00
huili2
d74c0f6ae6 Merge pull request #1414 from HaiboZhu/LTR_EC
Add picture bIsComplete flag to reflect the status of decoder
2014-10-16 14:22:43 +08:00
Haibo Zhu
9d182ee515 Add picture bIsComplete flag to reflect the status of decoder
Modify the output error status and add some some judgement
2014-10-15 11:36:24 -07:00
Sijia Chen
2479abf5c0 improve the logic of locking in the function 2014-10-15 17:46:59 +08:00
huili2
869c567f04 ec disable bug fix 2014-10-15 02:41:44 -07:00
Daniel J. Hofmann
cdb7e5da61 Removed accidentally committed vim swapfile 2014-10-15 09:12:19 +02:00
Daniel J. Hofmann
46ee46c186 Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete' 2014-10-14 23:57:54 +02:00
Daniel J. Hofmann
d9e0f2b023 Wtautological-undefined-compare 2014-10-14 23:36:14 +02:00
Daniel J. Hofmann
39d725c113 Wnewline-eof 2014-10-14 23:23:50 +02:00
Daniel J. Hofmann
cab92a3e36 Wheader-hygiene 2014-10-14 23:11:59 +02:00
Daniel J. Hofmann
ba535bda4d Wextra-semi 2014-10-14 22:56:57 +02:00
Daniel J. Hofmann
2ff61475d6 Wc++11-extra-semi 2014-10-14 22:21:06 +02:00
Daniel J. Hofmann
1e62aafcde Wc++11-extensions 2014-10-14 22:20:10 +02:00
Daniel J. Hofmann
4fc27714bd Wc++11-compat-reserved-user-defined-literal 2014-10-14 22:16:42 +02:00
Ethan Hugg
3ad4d9070e Merge pull request #1410 from dabenham/master
Update RELEASES
2014-10-13 11:04:05 -07:00
dabenham
024ac63f15 Update RELEASES
Removed links to iOS binaries.
2014-10-13 10:59:56 -07:00
huili2
614e898b67 Merge pull request #1408 from HaiboZhu/Add_UT_Deblocking
Fix bugs WelsDeblockingFilterSlice UT when random value is 0
2014-10-10 17:24:36 +08:00
Ethan Hugg
3885bd8f0e Merge pull request #1406 from mstorsjo/fix-warnings
Fix compiler warnings about comparison between signed and unsigned

Fix bugs WelsDeblockingFilterSlice UT when random value is 0
2014-10-09 19:51:58 -07:00
Ethan Hugg
b425450bc1 Merge pull request #1406 from mstorsjo/fix-warnings
Fix compiler warnings about comparison between signed and unsigned
2014-10-09 08:28:09 -07:00
Martin Storsjö
ad247a9a4a Fix compiler warnings about comparison between signed and unsigned 2014-10-09 11:58:23 +03:00
huili2
f9bab05b3a Merge pull request #1402 from HaiboZhu/Add_UT_Deblocking
Add ut deblocking
2014-10-09 09:04:55 +08:00
Ethan Hugg
52419bd13e Merge pull request #1400 from mstorsjo/warning-fix
Fix compiler warnings
2014-10-02 12:26:45 -07:00
ruil2
8c8cd50c96 Merge pull request #1403 from sijchen/fr_setting_fix1
[Encoder] Add checking of frame rate and temporal layer setting
2014-09-30 21:40:31 +08:00
Sijia Chen
68fed53687 add checking of frame rate and temporal layer setting for encoder input param
Reviewed at https://rbcommons.com/s/OpenH264/r/836/
2014-09-30 17:54:24 +08:00
Haibo Zhu
b7c54242a9 Modify the random value range which only for debug
Modify the CLIP3 macros to match the CLIP3(value, min, max)
Add partly UT cases into it which related to function call
Modify the typo for WELS_NEON
Add partly UT cases into it which related to Bs calculation
Update Windows VS project
2014-09-30 01:36:18 -07:00
Haibo Zhu
04c2a7ac5c Add CLIP3 and using ASSERT_FALSE macros 2014-09-30 01:36:18 -07:00
Haibo Zhu
27a21edcc9 Modify the targets.mk 2014-09-30 01:36:18 -07:00
Haibo Zhu
3593f2e3e7 Add partly UT code for deblocking filter 2014-09-30 01:36:18 -07:00
HaiboZhu
007fb47004 Merge pull request #1399 from huili2/ParseOnlyAPI
add API only for decode parser
2014-09-30 14:51:49 +08:00
Martin Storsjö
0affe66f93 Remove unused variables 2014-09-30 08:57:29 +03:00
Martin Storsjö
311272d341 Use the right log format for printing 64 bit integers 2014-09-30 08:56:40 +03:00
huili2
efdefdba28 add API only for decode parser for HW decoding support 2014-09-29 19:14:58 -07:00
dongzha
a3a0effc88 Merge pull request #1398 from shihuade/APIUT_V1
refator for API test--prepareEncDecParam and EncodeOneFrame
2014-09-30 10:05:31 +08:00
shihuade
d875d923f8 refator for API test--prepareEncDecParam and EncodeOneFrame 2014-09-29 19:58:43 +08:00
ruil2
6b1630cc90 Merge pull request #1396 from lyao2/rc_trace2
add debug info for RC max bitrate control test
2014-09-29 17:09:28 +08:00
lyao2
3904c025cb add debug info for RC max bitrate control test 2014-09-29 15:41:03 +08:00
dongzha
72df20000b Merge pull request #1391 from sijchen/modi_stra34
[Encoder] Fix a warning and refactor
2014-09-29 08:34:44 +08:00
dongzha
fd8d41dbb9 Merge pull request #1392 from dongzha/addMissedFileInVSUT
add missed files in VS UT solution
2014-09-29 08:33:35 +08:00
dongzha
07fa3d1898 add missed files in VS UT solution 2014-09-28 15:20:47 +08:00
Sijia Chen
6673a5f71e 1, fix a value in preprocess to avoid warning in UT
2, refactor to wrap the operation to m_pSpatialPic into WelsPreprocess
2014-09-28 13:12:16 +08:00
ruil2
e4b373a800 Merge pull request #1390 from sijchen/modi_stra25
[Encoder Screen] Add basic strategy for lossy+no LTR route (still in progress)
2014-09-26 17:11:49 +08:00
Sijia Chen
cf2cf9efd9 add basic strategy for lossy+no LTR route 2014-09-26 16:40:19 +08:00
ruil2
6ae38da3ab Merge pull request #1389 from zhilwang/issue-fix
Fix crash issue due to commit 8945348.
2014-09-26 11:43:34 +08:00
zhiliang wang
19c02bdfa8 Fix crash issue due to commit 8945348. 2014-09-26 11:16:13 +08:00
ruil2
bab0bf18f8 Merge pull request #1387 from dongzha/MoveDoubleInSCCRC
remove double in SCC rc
2014-09-25 16:53:46 +08:00
huili2
8945348c87 Merge pull request #1385 from ruil2/function
enable ARM assembly for SampleSad16x16
2014-09-25 15:04:46 +08:00
ruil2
ed341048de refine common moudle for part of intra prediction function 2014-09-25 14:03:11 +08:00
ruil2
73d27e9776 Merge pull request #1386 from huili2/UT_bugfix_dataformat
bug fix for dataformat UT
2014-09-25 13:05:25 +08:00
ruil2
bef3d87f34 Merge pull request #1384 from sijchen/add_para21
[Encoder] Add a new reading para
2014-09-25 12:45:38 +08:00
dong zhang
9f20c727d1 remove double in SCC rc 2014-09-25 11:09:35 +08:00
huili2
810d20a59d bug fix for dataformat UT 2014-09-24 18:04:24 -07:00
sijchen
d0f9b218f4 Merge pull request #1383 from ruil2/rc_refine
refine scc rc
2014-09-24 16:31:49 +08:00
ruil2
ffebbdb9b2 enable ARM assembly for SampleSad16x16 2014-09-24 15:59:36 +08:00
ruil2
4e57a46ca5 Merge pull request #1382 from huili2/dataformat_bugfix
add protection for decoder and data format
2014-09-24 13:47:02 +08:00
ruil2
c618cb1eaf refine scc rc 2014-09-24 09:54:01 +08:00
huili2
a3bdf4ffc9 Merge pull request #1378 from sijchen/ref_refac22
[Encoder] Refactor a function for further strategy adjustment
2014-09-24 08:59:02 +08:00
Sijia Chen
147c9052b8 add reading of the new option 2014-09-23 18:04:24 +08:00
ruil2
cfbf32b3fb Merge pull request #1381 from mstorsjo/silence-warnings
Silence warnings with gcc in GetOptionTid_AVC_NOPREFIX
2014-09-23 17:21:54 +08:00
huili2
f8d2ae42ef add protection for decoder and data format 2014-09-23 00:29:23 -07:00
Martin Storsjö
a59a989d9b Silence warnings with gcc in GetOptionTid_AVC_NOPREFIX 2014-09-23 09:39:18 +03:00
HaiboZhu
06e56ecdd8 Merge pull request #1380 from huili2/ec_option_free
add freely setoption for EC_idc and UT
2014-09-22 15:51:19 +08:00
huili2
f6fb459a7f add freely setoption for EC_idc and UT 2014-09-21 21:51:48 -07:00
sijchen
fd8db0451e Merge pull request #1377 from ruil2/scc_rc_1
add scc rate control
2014-09-19 17:08:48 +08:00
Sijia Chen
ee2f87dbbc refactor a function for further strategy adjustment 2014-09-19 16:17:04 +08:00
ruil2
17df23c2eb Merge pull request #1375 from sijchen/ref_refac11
[Encoder] Use function pointer for pEndofUpdateRefList
2014-09-19 16:01:14 +08:00
ruil2
480ff5acc2 Merge pull request #1374 from sijchen/ref_refac41
[Encoder UT] Add parameter and one case in UT
2014-09-19 16:00:44 +08:00
ruil2
66e38cc9ed add scc rate control 2014-09-19 15:56:49 +08:00
Sijia Chen
c480ffdad5 use function pointer as refactoring for further strategy adjustment 2014-09-19 14:48:45 +08:00
Sijia Chen
84ca659f06 add parameter and one case in UT 2014-09-19 14:46:02 +08:00
ruil2
25cad576b3 Merge pull request #1372 from huili2/remove_release111
remove release note for internal v1.1.1
2014-09-18 17:27:13 +08:00
huili2
f5b9d920ff Merge pull request #1369 from ruil2/console
set timestamp for each input frame to preparing for scc rate control
2014-09-18 14:46:28 +08:00
sijchen
64fa8a6b60 Merge pull request #1371 from ruil2/win_project
update interface definition
2014-09-18 14:38:58 +08:00
ruil2
ac2de4cbab Merge pull request #1370 from dongzha/addAPIUTTid
Add Tid/Trace API UT and Fix a bug when set NULL trace
2014-09-18 14:29:26 +08:00
ruil2
3ba0a9956a update interface definition 2014-09-18 14:20:16 +08:00
huili2
c4a446b43a Merge pull request #1367 from ruil2/rename
rename namespace and funciton name to avoid conflicts with old library
2014-09-18 13:23:27 +08:00
ruil2
880bf2d621 set timestamp for each input frame to preparing for scc rate control 2014-09-18 12:12:15 +08:00
ruil2
1d37250301 Merge pull request #1368 from sijchen/remove_dul2
[Encoder] Remove duplicate constant macro and modify the num_ref check accordingly
2014-09-18 09:12:41 +08:00
Sijia Chen
7e71714863 add a missed line in last commit 2014-09-17 18:13:43 +08:00
Sijia Chen
05684744c9 remove duplicate constant macro and modify the num_ref check accordingly 2014-09-17 18:10:27 +08:00
ruil2
3ff145e839 rename namespace and funciton name to avoid conflicts with old library 2014-09-17 15:50:59 +08:00
ruil2
25b723c413 Merge pull request #1366 from lyao2/refine_frameskip2
fix skipframe count error
2014-09-17 15:19:40 +08:00
lyao2
ca96def4ff fix skipframe count error 2014-09-17 14:26:05 +08:00
dongzha
c213c6ba30 1. add Tid API UT
2. add Trace UT
3. Fix a crash issue when set NULL trace
2014-09-17 09:26:54 +08:00
dongzha
8538b22f23 Merge pull request #1359 from mstorsjo/cleanup-simplification
Simplify code by getting rid of unnecesary SafeDelete/SafeFree macros
2014-09-17 08:49:24 +08:00
dongzha
399ca33284 Merge pull request #1356 from ruil2/memory
refine memory tag in order to trace issues related memory
2014-09-17 08:46:02 +08:00
Ethan Hugg
4e54fd191b Merge pull request #1361 from mstorsjo/avoid-comparing-uninitialized
Make sure uiIDRPicId is initialized within EncodeDecodeTest
2014-09-16 08:39:22 -07:00
Ethan Hugg
19dcff8616 Merge pull request #1360 from mstorsjo/use-correct-delete
Use the correct version of delete within a unit test
2014-09-16 08:38:20 -07:00
Ethan Hugg
68e92f9eb6 Merge pull request #1358 from mstorsjo/remove-unused-macro
Remove an unused macro
2014-09-16 08:36:22 -07:00
Ethan Hugg
5c67f368c3 Merge pull request #1357 from mstorsjo/silence-warnings
Fix build warnings with gcc in EncodeDecodeTest
2014-09-16 08:35:39 -07:00
Martin Storsjö
a6cc71208e Make sure uiIDRPicId is initialized within EncodeDecodeTest
This fixes valgrind warnings about comparison with uninitialized
values.
2014-09-16 11:59:09 +03:00
Martin Storsjö
58eba54e8c Use the correct version of delete within a unit test
This fixes valgrind warnings when running this test. The mismatched
delete could also potentially have caused memory corruption issues
while running the tests.
2014-09-16 11:57:24 +03:00
Martin Storsjö
9d9c609aab Remove some now unused macros 2014-09-16 11:53:19 +03:00
Martin Storsjö
958113073f Simplify code by calling WelsFree directly instead of using a helper function
This makes the code simpler and clearer. It's not necessary to use the
_SafeFree helper macro in neither of the case - in one case the
pointer is overwritten immediately, in the other case it's witihin
the destructor where the pointer won't ever be read again.
2014-09-16 11:53:19 +03:00
Martin Storsjö
37ae6505d4 Use delete instead of the _SafeDelete macro
Since this is the destructor of the class, the member variables
won't be read afterwards, and setting the pointers to NULL afterwards
is redundant.
2014-09-16 11:53:19 +03:00
Martin Storsjö
c5091e73be Remove unnecesary use of _SafeDelete
It is not necessary to check whether a pointer is NULL before
deleting it, "delete NULL" is explicitly ok.

The deleted pointer is a local variable here, so setting it to
NULL after deleting isn't necessary in these cases either.
2014-09-16 11:53:19 +03:00
Martin Storsjö
8eafdfa598 Remove an unused macro 2014-09-16 11:52:06 +03:00
Martin Storsjö
e7cd53e81b Fix build warnings with gcc in EncodeDecodeTest
Avoid a comparison between signed and unsigned integers, and avoid
a warning about a variable which is set but not used.
2014-09-16 10:10:57 +03:00
dongzha
f8d5f93b16 Merge pull request #1355 from syureyi/clean
Clean
2014-09-16 09:58:27 +08:00
huili2
48f203929e remove release note for internal v1.1.1 2014-09-15 18:54:48 -07:00
ruil2
b85a09163f refine memory tag in order to trace issues related memory 2014-09-16 09:49:44 +08:00
HaiboZhu
49ce86c78a Merge pull request #1354 from lyao2/fix_qualitymode_bug2
Fix bug RC_QUALITY_MODE not works as expected
2014-09-15 15:55:26 +08:00
lyao2
72862118f9 Fix bug RC_QUALITY_MODE not works as expected 2014-09-15 15:31:20 +08:00
lyao2
631ca210a8 Fix bug RC_QUALITY_MODE not works as expected 2014-09-15 13:21:29 +08:00
huili2
b51ff51387 Merge pull request #1350 from lyao2/ut_interface2
add encoder Interface additional option set test
2014-09-15 09:15:28 +08:00
huili2
4001551027 Merge pull request #1349 from dongzha/AddAPIUTEncoder_Decoder
add encoder/decoder api test for LTR and EC flag
2014-09-15 09:15:08 +08:00
ruil2
458cc6b4fd Merge pull request #1351 from lyao2/bitrate_mode
enlarge QP range when skipframeflag off on BitRate mode
2014-09-12 16:09:37 +08:00
lyao2
522aa4457a enlarge QP range when skipframeflag off on BitRate mode 2014-09-12 14:45:08 +08:00
dongzha
311f7006fd 1. add encoder-engine-decoder API UT for: IDR request, LTR request
2. add decoder api UT for EC: Disable/Enable EC
3. Fix a decoder bug when EC is disabled
   itoltalMbDec should be set to zero when encouter a new sequence/picture, even   when EC is disabled.
2014-09-12 11:12:59 +08:00
zhuiling
9913b73cb1 improve py and mk 2014-09-12 10:30:56 +08:00
zhuiling
9e7a19291c improve py 2014-09-12 10:29:07 +08:00
zhuiling
0fe477625c improve py, and change mk according to mk 2014-09-12 10:25:46 +08:00
zhuiling
6b64efbf92 improve py 2014-09-12 09:59:46 +08:00
zhuiling
235f6e3474 improve py 2014-09-12 09:56:51 +08:00
zhuiling
77552551f7 py improvement according to Martin's sugesstion 2014-09-12 09:39:14 +08:00
lyao2
679cc4ac6c Merge pull request #1346 from ruil2/ltr_limit
using default value for LTR.
2014-09-11 13:02:02 +08:00
ruil2
c6a136c742 using default value for LTR. 2014-09-11 10:32:46 +08:00
ruil2
1a394d1432 Merge pull request #1343 from huili2/ec_disable_set
disable EC SetOption
2014-09-10 15:15:49 +08:00
dongzha
bffbde9f45 Merge pull request #1342 from ruil2/update_pic
update spatial picture when abnormal exit
2014-09-10 13:38:18 +08:00
huili2
84848bb7d3 disable EC SetOption 2014-09-09 20:12:01 -07:00
ruil2
bb43c1c9a9 update spatial picture when abnormal exit 2014-09-10 09:45:32 +08:00
ruil2
f003fa1fe6 Merge pull request #1341 from sijchen/enable_ltr01
[Encoder] fix a LTR range problem when LTR num is larger than 2
2014-09-10 08:51:44 +08:00
ruil2
1df4cd43cc Merge pull request #1338 from sijchen/add_setoption
[Encoder] remove unsupported lines in cfg to avoid misleading
2014-09-09 15:38:26 +08:00
Sijia Chen
6f553c9742 remove unused lines 2014-09-09 15:09:07 +08:00
Sijia Chen
79157ce632 fix a LTR range problem when LTR num is larger than 2 2014-09-09 15:05:57 +08:00
Sijia Chen
a6df69c305 remove unsupported lines in cfg to avoid misleading 2014-09-09 14:20:27 +08:00
zhuiling
a1dbf6ab13 make clean without OS ARCH except android platform 2014-09-05 16:38:28 +08:00
dongzha
ef590de0dc Merge pull request #1335 from lyao2/fixppsbug
fix pps caused death loop issue
2014-09-05 14:18:16 +08:00
huili2
684c42536d Merge pull request #1330 from ruil2/delivery_status
modify delivery status interface
2014-09-05 13:32:52 +08:00
lyao2
881667a533 fix pps caused death loop issue 2014-09-05 13:28:13 +08:00
ruil2
4fc144b698 Merge pull request #1333 from huili2/print_ver_master
modify version info in enc/dec
2014-09-05 13:23:49 +08:00
huili2
1b1ea2b9ef modify version info in enc/dec 2014-09-04 21:55:06 -07:00
ruil2
d63172db9b Merge pull request #1331 from sijchen/add_setoption
[Encoder] add setoption of 'isLosslessLink' for further strategy tuning
2014-09-05 12:49:25 +08:00
ruil2
2f041c7a4b modify delivery status interface 2014-09-05 10:57:51 +08:00
huili2
43dc6f01e1 Merge pull request #1322 from ruil2/MinCr_waring
add MinCr checking and output warings if the MinCr isn't met
2014-09-05 09:39:56 +08:00
sijchen
61926f208c add a setoption for further setting 2014-09-04 14:24:14 +08:00
ruil2
199d19a785 Merge pull request #1328 from lyao2/fix_maxbitrate
fix bug that iMaxSpatialBitrate is not correct assigned
2014-09-04 13:06:24 +08:00
lyao2
7c95ccc6a7 update SHA1Table 2014-09-04 11:07:35 +08:00
lyao2
f2437f24b9 fix bug that iMaxSpatialBitrate is not correct assigned 2014-09-03 17:40:19 +08:00
huili2
c287a9109f Merge pull request #1324 from ruil2/ltr_check_update
add UT for LTR setopton and fix crash issue
2014-09-03 15:51:23 +08:00
dongzha
3735cfc1bd Merge pull request #1323 from huili2/ps_ne_deal
when sps/pps non exist, return dsNoParamSets
2014-09-03 13:56:56 +08:00
dongzha
315d9315c4 Merge pull request #1325 from huili2/ps_ne_deal_v1.1.1
when sps/pps non exist, return dsNoParamSets
2014-09-03 13:56:30 +08:00
ruil2
7e8cde055f add UT for LTR setopton and fix crash issue 2014-09-03 13:28:14 +08:00
huili2
d98fd57252 when sps/pps non exist, return dsNoParamSets 2014-09-02 22:06:05 -07:00
ruil2
4ece8efaed add MinCr checking and output warings if the MinCr isn't met 2014-09-03 10:41:54 +08:00
dongzha
cef43e30fe Merge pull request #1321 from ruil2/ltr_check
avoid LTR reference frames overflow
2014-09-02 15:50:04 +08:00
lyao2
15124b1258 fix bug 2014-09-02 13:41:00 +08:00
ruil2
b5a01efa96 avoid LTR reference frames overflow 2014-09-02 10:23:03 +08:00
lyao2
aa7eb5fd09 code refine 2014-09-02 09:21:31 +08:00
lyao2
849a730608 refine code 2014-09-01 17:49:59 +08:00
lyao2
24bd0b74ae add additional option set test 2014-09-01 16:35:32 +08:00
132 changed files with 13710 additions and 9754 deletions

View File

@@ -136,7 +136,7 @@ clean:
ifeq (android,$(OS))
clean: clean_Android
endif
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(LIBRARIES) $(BINARIES)
$(QUIET)rm -f $(OBJS) $(OBJS:.$(OBJ)=.d) $(OBJS:.$(OBJ)=.obj) $(LIBRARIES) $(BINARIES) *.lib *.a *.dylib *.dll *.so
gmp-bootstrap:
if [ ! -d gmp-api ] ; then git clone https://github.com/mozilla/gmp-api gmp-api ; fi
@@ -191,7 +191,7 @@ $(LIBPREFIX)$(PROJECT_NAME).$(LIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROC
$(LIBPREFIX)$(PROJECT_NAME).$(SHAREDLIBSUFFIX): $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
$(QUIET)rm -f $@
$(QUIET_CXX)$(CXX) $(SHARED) $(LDFLAGS) $(CXX_LINK_O) $+ $(SHLDFLAGS)
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(SHLDFLAGS)
ifeq ($(HAVE_GMP_API),Yes)
plugin: $(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX)
@@ -204,7 +204,7 @@ endif
$(LIBPREFIX)$(MODULE_NAME).$(SHAREDLIBSUFFIX): $(MODULE_OBJS) $(ENCODER_OBJS) $(DECODER_OBJS) $(PROCESSING_OBJS) $(COMMON_OBJS)
$(QUIET)rm -f $@
$(QUIET_CXX)$(CXX) $(SHARED) $(LDFLAGS) $(CXX_LINK_O) $+ $(SHLDFLAGS) $(MODULE_LDFLAGS)
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(SHLDFLAGS) $(MODULE_LDFLAGS)
install-headers:
mkdir -p $(PREFIX)/include/wels
@@ -241,7 +241,7 @@ $(LIBPREFIX)ut.$(LIBSUFFIX): $(DECODER_UNITTEST_OBJS) $(ENCODER_UNITTEST_OBJS) $
LIBRARIES +=$(LIBPREFIX)ut.$(SHAREDLIBSUFFIX)
$(LIBPREFIX)ut.$(SHAREDLIBSUFFIX): $(DECODER_UNITTEST_OBJS) $(ENCODER_UNITTEST_OBJS) $(PROCESSING_UNITTEST_OBJS) $(API_TEST_OBJS) $(COMMON_UNITTEST_OBJS) $(CODEC_UNITTEST_DEPS)
$(QUIET)rm -f $@
$(QUIET_CXX)$(CXX) $(SHARED) $(LDFLAGS) $(CXX_LINK_O) $+ $(CODEC_UNITTEST_LDFLAGS)
$(QUIET_CXX)$(CXX) $(SHARED) $(CXX_LINK_O) $+ $(LDFLAGS) $(CODEC_UNITTEST_LDFLAGS)
binaries: codec_unittest$(EXEEXT)
BINARIES += codec_unittest$(EXEEXT)

BIN
OpenH264_API_v1.2.0.docx Normal file

Binary file not shown.

View File

@@ -1,19 +1,15 @@
Releases
-----------
v1.1.1
- Modify some APIs
- Add WelsGetDecoderCapability for SDP negotiation usage
- Add RC_BUFFERBASED_MODE for screen content RC
- Add SLTRConfig for SetOption in encoder
- Add ENCODER_OPTION_COMPLEXITY/ECOMPLEXITY_MODE in TagEncParamExt
- Remove uiFrameToBeCoded in TagEncParamExt
- Remove iInputCsp in TagEncParamBase/TagEncParamExt
- Modify iOutputColorFormat as eOutputColorFormat
- Modify uiEcActiveFlag as eEcActiveIdc
- Rename ENCOCER_LTR_MARKING_PERIOD to ENCODER_LTR_MARKING_PERIOD
- Improve the encoding speed of screen content encoding including ARM and X86
- fix some bugs
v1.2.0
------
- Add and modify encoder APIs related to rate control and screen content encoding
- Remove PauseFrame in encoder APIs
- Improve rate control and compression ratio for screen content encoding
- Improve error concealment algorithm
- Improve validation of input parameters
- Add ARM64 assembly
- bug fixes
-----------
v1.1.0
@@ -30,11 +26,19 @@ Binaries
These binary releases are distributed under this license:
http://www.openh264.org/BINARY_LICENSE.txt
v1.2.0
------
http://ciscobinary.openh264.org/libopenh264-1.2.0-android19.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.2.0-linux32.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.2.0-linux64.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.2.0-osx32.dylib.bz2
http://ciscobinary.openh264.org/libopenh264-1.2.0-osx64.dylib.bz2
http://ciscobinary.openh264.org/openh264-1.2.0-win32msvc.dll.bz2
http://ciscobinary.openh264.org/openh264-1.2.0-win64msvc.dll.bz2
v1.1.0
------
http://ciscobinary.openh264.org/libopenh264-1.1.0-android19.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.1.0-ios32.a.bz2
http://ciscobinary.openh264.org/libopenh264-1.1.0-ios64.a.bz2
http://ciscobinary.openh264.org/libopenh264-1.1.0-linux32.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.1.0-linux64.so.bz2
http://ciscobinary.openh264.org/libopenh264-1.1.0-osx32.dylib.bz2

View File

@@ -1,5 +1,5 @@
ifneq ($(filter %86 x86_64, $(ARCH)),)
include $(SRC_PATH)build/platform-x86-common.mk
include $(SRC_PATH)build/x86-common.mk
endif
ifneq ($(filter-out arm64, $(filter arm%, $(ARCH))),)
ifeq ($(USE_ASM), Yes)

View File

@@ -5,6 +5,7 @@ GTEST_CPP_SRCS=\
GTEST_OBJS += $(GTEST_CPP_SRCS:.cc=.$(OBJ))
OBJS += $(GTEST_OBJS)
$(GTEST_SRCDIR)/%.$(OBJ): $(GTEST_SRCDIR)/%.cc
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(GTEST_CFLAGS) $(GTEST_INCLUDES) -c $(CXX_O) $<

View File

@@ -134,37 +134,42 @@ if len(cfiles) > 0:
for cfile in cfiles:
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, cfile))
f.write("\n")
f.write("%s_OBJS += $(%s_C_SRCS:.c=.$(OBJ))\n\n"%(PREFIX, PREFIX))
f.write("%s_OBJS += $(%s_C_SRCS:.c=.$(OBJ))\n"%(PREFIX, PREFIX))
if len(asm) > 0:
f.write("ifeq ($(ASM_ARCH), x86)\n")
f.write("%s_ASM_SRCS=\\\n"%(PREFIX))
for c in asm:
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, c))
f.write("\n")
f.write("%s_OBJS += $(%s_ASM_SRCS:.asm=.$(OBJ))\n"%(PREFIX, PREFIX))
f.write("endif\n\n")
f.write("%s_OBJSASM += $(%s_ASM_SRCS:.asm=.$(OBJ))\n"%(PREFIX, PREFIX))
f.write("ifeq ($(ASM_ARCH), x86)\n")
f.write("%s_OBJS += $(%s_OBJSASM)\n"%(PREFIX,PREFIX))
f.write("endif\n")
f.write("OBJS += $(%s_OBJSASM)\n\n"%(PREFIX))
if len(armfiles) > 0:
f.write("ifeq ($(ASM_ARCH), arm)\n")
f.write("%s_ASM_ARM_SRCS=\\\n"%(PREFIX))
for c in armfiles:
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, c))
f.write("\n")
f.write("%s_OBJS += $(%s_ASM_ARM_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
f.write("endif\n\n")
f.write("%s_OBJSARM += $(%s_ASM_ARM_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
f.write("ifeq ($(ASM_ARCH), arm)\n")
f.write("%s_OBJS += $(%s_OBJSARM)\n"%(PREFIX,PREFIX))
f.write("endif\n")
f.write("OBJS += $(%s_OBJSARM)\n\n"%(PREFIX))
if len(arm64files) > 0:
f.write("ifeq ($(ASM_ARCH), arm64)\n")
f.write("%s_ASM_ARM64_SRCS=\\\n"%(PREFIX))
for c in arm64files:
f.write("\t$(%s_SRCDIR)/%s\\\n"%(PREFIX, c))
f.write("\n")
f.write("%s_OBJS += $(%s_ASM_ARM64_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
f.write("endif\n\n")
f.write("OBJS += $(%s_OBJS)\n"%PREFIX)
f.write("%s_OBJSARM64 += $(%s_ASM_ARM64_SRCS:.S=.$(OBJ))\n"%(PREFIX, PREFIX))
f.write("ifeq ($(ASM_ARCH), arm64)\n")
f.write("%s_OBJS += $(%s_OBJSARM64)\n"%(PREFIX,PREFIX))
f.write("endif\n")
f.write("OBJS += $(%s_OBJSARM64)\n\n"%(PREFIX))
f.write("OBJS += $(%s_OBJS)\n\n"%(PREFIX))
write_cpp_rule_pattern(f)
if len(cfiles) > 0:

View File

@@ -1,4 +1,4 @@
include $(SRC_PATH)build/platform-arch.mk
include $(SRC_PATH)build/arch.mk
ifeq ($(ASM_ARCH), x86)
ifeq ($(ENABLE64BIT), Yes)
ASMFLAGS += -f win64

View File

@@ -1,5 +1,5 @@
ARCH = arm
include $(SRC_PATH)build/platform-arch.mk
include $(SRC_PATH)build/arch.mk
SHAREDLIBSUFFIX = so
NDKLEVEL = 12
ifeq ($(ARCH), arm)

View File

@@ -1,4 +1,4 @@
include $(SRC_PATH)build/platform-arch.mk
include $(SRC_PATH)build/arch.mk
SHAREDLIBSUFFIX = dylib
SHARED = -dynamiclib
CFLAGS += -Wall -fPIC -MMD -MP

View File

@@ -1,4 +1,4 @@
include $(SRC_PATH)build/platform-arch.mk
include $(SRC_PATH)build/arch.mk
SHAREDLIBSUFFIX = so
CFLAGS += -fPIC
LDFLAGS += -lpthread

View File

@@ -1,4 +1,4 @@
include $(SRC_PATH)build/platform-arch.mk
include $(SRC_PATH)build/arch.mk
SHAREDLIBSUFFIX = so
CFLAGS += -Wall -fno-strict-aliasing -fPIC -MMD -MP
LDFLAGS += -lpthread

View File

@@ -1,4 +1,4 @@
include $(SRC_PATH)build/platform-x86-common.mk
include $(SRC_PATH)build/x86-common.mk
SHAREDLIBSUFFIX = dll
CFLAGS += -MMD -MP
LDFLAGS +=

View File

@@ -1,5 +1,5 @@
ARCH = arm
include $(SRC_PATH)build/platform-msvc-common.mk
include $(SRC_PATH)build/msvc-common.mk
CFLAGS_OPT += -MD
CFLAGS_DEBUG += -MDd
CFLAGS += -DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP

View File

@@ -1,4 +1,4 @@
include $(SRC_PATH)build/platform-msvc-common.mk
include $(SRC_PATH)build/msvc-common.mk
LDFLAGS += user32.lib
CFLAGS_OPT += -MT
CFLAGS_DEBUG += -MTd -Gm

View File

@@ -106,6 +106,14 @@ class ISVCDecoder {
unsigned char** ppDst,
SBufferInfo* pDstInfo) = 0;
/*
* This function parse input bitstream only, and rewrite possible SVC syntax to AVC syntax
* return: 0 - success; otherwise -failed;
*/
virtual DECODING_STATE EXTAPI DecodeParser (const unsigned char* pSrc,
const int iSrcLen,
SParserBsInfo* pDstInfo) = 0;
/*
* this API does not work for now!! This is for future use to support non-I420 color format output.
*/
@@ -169,6 +177,10 @@ DECODING_STATE (*DecodeFrame2) (ISVCDecoder*, const unsigned char* pSrc,
unsigned char** ppDst,
SBufferInfo* pDstInfo);
DECODING_STATE (*DecodeParser) (ISVCDecoder*, const unsigned char* pSrc,
const int iSrcLen,
SParserBsInfo* pDstInfo);
DECODING_STATE (*DecodeFrameEx) (ISVCDecoder*, const unsigned char* pSrc,
const int iSrcLen,
unsigned char* pDst,

View File

@@ -102,6 +102,12 @@ typedef enum {
ENCODER_OPTION_TRACE_LEVEL,
ENCODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
ENCODER_OPTION_TRACE_CALLBACK_CONTEXT,
ENCODER_OPTION_GET_STATISTICS, //read only
ENCODER_OPTION_STATISTICS_LOG_INTERVAL, // log interval in milliseconds
// advanced algorithmetic settings
ENCODER_OPTION_IS_LOSSLESS_LINK
} ENCODER_OPTION;
/* Option types introduced in decoder application */
@@ -119,13 +125,15 @@ typedef enum {
DECODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
DECODER_OPTION_TRACE_CALLBACK_CONTEXT,
DECODER_OPTION_GET_STATISTICS
} DECODER_OPTION;
//enuerate the types of error concealment methods
typedef enum {
ERROR_CON_DISABLE = 0,
ERROR_CON_FRAME_COPY,
ERROR_CON_SLICE_COPY,
ERROR_CON_SLICE_COPY
} ERROR_CON_IDC;
typedef enum { //feedback that whether or not have VCL NAL in current AU
@@ -145,14 +153,14 @@ typedef enum {
SPATIAL_LAYER_1 = 1,
SPATIAL_LAYER_2 = 2,
SPATIAL_LAYER_3 = 3,
SPATIAL_LAYER_ALL = 4,
SPATIAL_LAYER_ALL = 4
} LAYER_NUM;
//enumerate the type of video bitstream which is provided to decoder
typedef enum {
VIDEO_BITSTREAM_AVC = 0,
VIDEO_BITSTREAM_SVC = 1,
VIDEO_BITSTREAM_DEFAULT = VIDEO_BITSTREAM_SVC,
VIDEO_BITSTREAM_DEFAULT = VIDEO_BITSTREAM_SVC
} VIDEO_BITSTREAM_TYPE;
typedef enum {
@@ -161,7 +169,7 @@ typedef enum {
IDR_RECOVERY_REQUEST = 2,
NO_LTR_MARKING_FEEDBACK = 3,
LTR_MARKING_SUCCESS = 4,
LTR_MARKING_FAILED = 5,
LTR_MARKING_FAILED = 5
} KEY_FRAME_REQUEST_TYPE;
typedef struct {
@@ -179,7 +187,7 @@ typedef struct {
typedef struct {
bool bEnableLongTermReference; // 1: on, 0: off
int iLTRRefNum;
int iLTRRefNum; //TODO: not supported to set it arbitrary yet
} SLTRConfig;
typedef struct {
unsigned int
@@ -201,9 +209,8 @@ typedef enum {
typedef enum {
RC_QUALITY_MODE = 0, //Quality mode
RC_BITRATE_MODE = 1, //Bitrate mode
RC_LOW_BW_MODE = 2, //bitrate limited mode
RC_BUFFERBASED_MODE = 3,//no bitrate control,only using buffer status,adjust the video quality
RC_OFF_MODE = -1, // rate control off mode
RC_BUFFERBASED_MODE = 2,//no bitrate control,only using buffer status,adjust the video quality
RC_OFF_MODE = -1 // rate control off mode
} RC_MODES;
typedef enum {
@@ -218,7 +225,7 @@ typedef enum {
PRO_CAVLC444 = 244,
PRO_SCALABLE_BASELINE = 83,
PRO_SCALABLE_HIGH = 86,
PRO_SCALABLE_HIGH = 86
} EProfileIdc;
typedef enum {
@@ -275,13 +282,13 @@ typedef struct {
typedef enum {
CAMERA_VIDEO_REAL_TIME, //camera video signal
SCREEN_CONTENT_REAL_TIME,//screen content signal
SCREEN_CONTENT_REAL_TIME //screen content signal
} EUsageType;
typedef enum {
LOW_COMPLEXITY, //the lowest compleixty,the fastest speed,
MEDIUM_COMPLEXITY, //medium complexity, medium speed,medium quality
HIGH_COMPLEXITY, //high complexity, lowest speed, high quality
HIGH_COMPLEXITY //high complexity, lowest speed, high quality
} ECOMPLEXITY_MODE;
// TODO: Refine the parameters definition.
// SVC Encoding Parameters
@@ -330,7 +337,7 @@ typedef struct TagEncParamExt {
/*LTR settings*/
bool bEnableLongTermReference; // 1: on, 0: off
int iLTRRefNum;
int iLTRRefNum; //TODO: not supported to set it arbitrary yet
unsigned int iLtrMarkPeriod;
/* multi-thread settings*/
@@ -347,6 +354,9 @@ typedef struct TagEncParamExt {
bool bEnableAdaptiveQuant; // adaptive quantization control
bool bEnableFrameCroppingFlag;// enable frame cropping flag: TRUE always in application
bool bEnableSceneChangeDetect;
/*LTR advanced setting*/
bool bIsLosslessLink;
} SEncParamExt;
//Define a new struct to show the property of video bitstream.
@@ -442,4 +452,46 @@ typedef struct TagDecoderCapability {
bool bRedPicCap;
} SDecoderCapability;
typedef struct TagParserBsInfo {
int iNalNum; //total NAL number in current AU
int iNalLenInByte [MAX_NAL_UNITS_IN_LAYER]; //each nal length
unsigned char* pDstBuff; //outputted dst buffer for parsed bitstream
int iSpsWidthInPixel; //required SPS width info
int iSpsHeightInPixel; //required SPS height info
} SParserBsInfo, PParserBsInfo;
typedef struct TagVideoEncoderStatistics {
unsigned int uiWidth; // the width of encoded frame
unsigned int uiHeight; // the height of encoded frame
//following standard, will be 16x aligned, if there are multiple spatial, this is of the highest
float fAverageFrameSpeedInMs; // Average_Encoding_Time
// rate control related
float fAverageFrameRate; // the average frame rate in, calculate since encoding starts, supposed that the input timestamp is in unit of ms
float fLatestFrameRate; // the frame rate in, in the last second, supposed that the input timestamp is in unit of ms (? useful for checking BR, but is it easy to calculate?
unsigned int uiBitRate; // sendrate in Bits per second, calculated within the set time-window
unsigned int uiInputFrameCount; // number of frames
unsigned int uiSkippedFrameCount; // number of frames
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
unsigned int uiIDRReqNum; // number of IDR requests
unsigned int uiIDRSentNum; // number of actual IDRs sent
unsigned int uiLTRSentNum; // number of LTR sent/marked
} SEncoderStatistics; // in building, coming soon
typedef struct TagVideoDecoderStatistics {
unsigned int uiWidth; // the width of encode/decode frame
unsigned int uiHeight; // the height of encode/decode frame
float fAverageFrameSpeedInMs; // Average_Decoding_Time
unsigned int uiDecodedFrameCount; // number of frames
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
unsigned int
uiAvgEcRatio; // when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
unsigned int uiIDRReqNum; // number of actual IDR request
unsigned int uiLTRReqNum; // number of actual LTR request
unsigned int uiIDRRecvNum; // number of actual IDR received
} SDecoderStatistics; // in building, coming soon
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__

View File

@@ -63,7 +63,7 @@ typedef enum {
videoFrameTypeI, /* I frame type */
videoFrameTypeP, /* P frame type */
videoFrameTypeSkip, /* Skip the frame based encoder kernel */
videoFrameTypeIPMixed, /* Frame type introduced I and P slices are mixing */
videoFrameTypeIPMixed /* Frame type introduced I and P slices are mixing */
} EVideoFrameType;
typedef enum {
@@ -72,7 +72,7 @@ typedef enum {
cmUnkonwReason,
cmMallocMemeError, /*Malloc a memory error*/
cmInitExpected, /*Initial action is expected*/
cmUnsupportedData,
cmUnsupportedData
} CM_RETURN;
/* nal unit type */
@@ -93,7 +93,7 @@ enum ENalPriority {
NAL_PRIORITY_DISPOSABLE = 0,
NAL_PRIORITY_LOW = 1,
NAL_PRIORITY_HIGH = 2,
NAL_PRIORITY_HIGHEST = 3,
NAL_PRIORITY_HIGHEST = 3
};
#define IS_PARAMETER_SET_NAL(eNalRefIdc, eNalType) \
@@ -116,7 +116,7 @@ enum {
ET_IR_R3 = 0x10, // Intra Refresh in predifined 10% MB
ET_FEC_HALF = 0x20, // Forward Error Correction in 50% redundency mode
ET_FEC_FULL = 0x40, // Forward Error Correction in 100% redundency mode
ET_RFS = 0x80, // Reference Frame Selection
ET_RFS = 0x80 // Reference Frame Selection
};
/* information of coded Slice(=NAL)(s) */

View File

@@ -25,6 +25,9 @@
F5AC94FF193EB7D800F58154 /* deblocking_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */; };
F5B8D82D190757290037849A /* mc_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5B8D82C190757290037849A /* mc_aarch64_neon.S */; };
F5BB0BB8196BB5960072D50D /* copy_mb_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */; };
F791965419D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F791965319D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S */; };
F791965619D3B8A600F60C6B /* intra_pred_common_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F791965519D3B8A600F60C6B /* intra_pred_common_neon.S */; };
F791965919D3BE2200F60C6B /* intra_pred_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F791965819D3BE2200F60C6B /* intra_pred_common.cpp */; };
FAABAA1818E9354A00D4186F /* sad_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAABAA1718E9354A00D4186F /* sad_common.cpp */; };
/* End PBXBuildFile section */
@@ -74,6 +77,10 @@
F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = deblocking_aarch64_neon.S; path = arm64/deblocking_aarch64_neon.S; sourceTree = "<group>"; };
F5B8D82C190757290037849A /* mc_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = mc_aarch64_neon.S; path = arm64/mc_aarch64_neon.S; sourceTree = "<group>"; };
F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = copy_mb_aarch64_neon.S; path = arm64/copy_mb_aarch64_neon.S; sourceTree = "<group>"; };
F791965319D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = intra_pred_common_aarch64_neon.S; path = arm64/intra_pred_common_aarch64_neon.S; sourceTree = "<group>"; };
F791965519D3B8A600F60C6B /* intra_pred_common_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = intra_pred_common_neon.S; sourceTree = "<group>"; };
F791965719D3BA9300F60C6B /* intra_pred_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intra_pred_common.h; sourceTree = "<group>"; };
F791965819D3BE2200F60C6B /* intra_pred_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = intra_pred_common.cpp; sourceTree = "<group>"; };
FAABAA1618E9353F00D4186F /* sad_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sad_common.h; sourceTree = "<group>"; };
FAABAA1718E9354A00D4186F /* sad_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sad_common.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -93,6 +100,7 @@
4C3406B118D96EA600DFA14A /* arm */ = {
isa = PBXGroup;
children = (
F791965519D3B8A600F60C6B /* intra_pred_common_neon.S */,
4CC61F0818FF6B4B00E56EAB /* copy_mb_neon.S */,
4C3406B218D96EA600DFA14A /* arm_arch_common_macro.S */,
4C3406B318D96EA600DFA14A /* deblocking_neon.S */,
@@ -105,6 +113,7 @@
4C3406B618D96EA600DFA14A /* inc */ = {
isa = PBXGroup;
children = (
F791965719D3BA9300F60C6B /* intra_pred_common.h */,
F0B204F718FD23B6005DA23F /* copy_mb.h */,
FAABAA1618E9353F00D4186F /* sad_common.h */,
4C3406B718D96EA600DFA14A /* cpu.h */,
@@ -126,6 +135,7 @@
4C3406C318D96EA600DFA14A /* src */ = {
isa = PBXGroup;
children = (
F791965819D3BE2200F60C6B /* intra_pred_common.cpp */,
5BA8F2BF19603F5F00011CE4 /* common_tables.cpp */,
F0B204F818FD23BF005DA23F /* copy_mb.cpp */,
FAABAA1718E9354A00D4186F /* sad_common.cpp */,
@@ -179,6 +189,7 @@
F556A81D1906669F00E156A8 /* arm64 */ = {
isa = PBXGroup;
children = (
F791965319D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S */,
F5BB0BB7196BB5960072D50D /* copy_mb_aarch64_neon.S */,
F5AC94FE193EB7D800F58154 /* deblocking_aarch64_neon.S */,
F5B8D82C190757290037849A /* mc_aarch64_neon.S */,
@@ -244,12 +255,15 @@
F556A8241906673900E156A8 /* arm_arch64_common_macro.S in Sources */,
F5AC94FF193EB7D800F58154 /* deblocking_aarch64_neon.S in Sources */,
4C3406CE18D96EA600DFA14A /* crt_util_safe_x.cpp in Sources */,
F791965919D3BE2200F60C6B /* intra_pred_common.cpp in Sources */,
4C3406CF18D96EA600DFA14A /* deblocking_common.cpp in Sources */,
5BA8F2C019603F5F00011CE4 /* common_tables.cpp in Sources */,
F791965419D3B89D00F60C6B /* intra_pred_common_aarch64_neon.S in Sources */,
4C3406D118D96EA600DFA14A /* WelsThreadLib.cpp in Sources */,
4C3406CC18D96EA600DFA14A /* mc_neon.S in Sources */,
F5BB0BB8196BB5960072D50D /* copy_mb_aarch64_neon.S in Sources */,
4C3406CB18D96EA600DFA14A /* expand_picture_neon.S in Sources */,
F791965619D3B8A600F60C6B /* intra_pred_common_neon.S in Sources */,
4CC61F0918FF6B4B00E56EAB /* copy_mb_neon.S in Sources */,
53C1C9BC193F0FB000404D8F /* expand_pic.cpp in Sources */,
4C3406CD18D96EA600DFA14A /* cpu.cpp in Sources */,

View File

@@ -17,7 +17,6 @@
549947E2196A3FB400BA3D87 /* pixel_sad_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 549947AE196A3FB400BA3D87 /* pixel_sad_neon.S */; };
549947E3196A3FB400BA3D87 /* vaa_calc_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 549947AF196A3FB400BA3D87 /* vaa_calc_neon.S */; };
549947E4196A3FB400BA3D87 /* BackgroundDetection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947B1196A3FB400BA3D87 /* BackgroundDetection.cpp */; };
549947E5196A3FB400BA3D87 /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947B4196A3FB400BA3D87 /* common.cpp */; };
549947E6196A3FB400BA3D87 /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947B6196A3FB400BA3D87 /* memory.cpp */; };
549947E7196A3FB400BA3D87 /* WelsFrameWork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947BB196A3FB400BA3D87 /* WelsFrameWork.cpp */; };
549947E8196A3FB400BA3D87 /* WelsFrameWorkEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947BD196A3FB400BA3D87 /* WelsFrameWorkEx.cpp */; };
@@ -34,6 +33,7 @@
549947F3196A3FB400BA3D87 /* vaacalcfuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947D8196A3FB400BA3D87 /* vaacalcfuncs.cpp */; };
549947F4196A3FB400BA3D87 /* vaacalculation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 549947D9196A3FB400BA3D87 /* vaacalculation.cpp */; };
6C749B78197E2A2000A111F9 /* adaptive_quantization_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C749B77197E2A2000A111F9 /* adaptive_quantization_aarch64_neon.S */; };
F791965B19D3BF6B00F60C6B /* intra_pred_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F791965A19D3BF6B00F60C6B /* intra_pred_common.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -64,7 +64,6 @@
549947AF196A3FB400BA3D87 /* vaa_calc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = vaa_calc_neon.S; sourceTree = "<group>"; };
549947B1196A3FB400BA3D87 /* BackgroundDetection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackgroundDetection.cpp; sourceTree = "<group>"; };
549947B2196A3FB400BA3D87 /* BackgroundDetection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackgroundDetection.h; sourceTree = "<group>"; };
549947B4196A3FB400BA3D87 /* common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = common.cpp; sourceTree = "<group>"; };
549947B5196A3FB400BA3D87 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
549947B6196A3FB400BA3D87 /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = "<group>"; };
549947B7196A3FB400BA3D87 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
@@ -97,6 +96,7 @@
549947D9196A3FB400BA3D87 /* vaacalculation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vaacalculation.cpp; sourceTree = "<group>"; };
549947DA196A3FB400BA3D87 /* vaacalculation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vaacalculation.h; sourceTree = "<group>"; };
6C749B77197E2A2000A111F9 /* adaptive_quantization_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = adaptive_quantization_aarch64_neon.S; path = arm64/adaptive_quantization_aarch64_neon.S; sourceTree = "<group>"; };
F791965A19D3BF6B00F60C6B /* intra_pred_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = intra_pred_common.cpp; path = ../../../common/src/intra_pred_common.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -210,7 +210,7 @@
549947B3196A3FB400BA3D87 /* common */ = {
isa = PBXGroup;
children = (
549947B4196A3FB400BA3D87 /* common.cpp */,
F791965A19D3BF6B00F60C6B /* intra_pred_common.cpp */,
549947B5196A3FB400BA3D87 /* common.h */,
549947B6196A3FB400BA3D87 /* memory.cpp */,
549947B7196A3FB400BA3D87 /* memory.h */,
@@ -351,7 +351,6 @@
549947E9196A3FB400BA3D87 /* ComplexityAnalysis.cpp in Sources */,
549947E3196A3FB400BA3D87 /* vaa_calc_neon.S in Sources */,
549947EE196A3FB400BA3D87 /* imagerotate.cpp in Sources */,
549947E5196A3FB400BA3D87 /* common.cpp in Sources */,
549947EA196A3FB400BA3D87 /* denoise.cpp in Sources */,
549947E7196A3FB400BA3D87 /* WelsFrameWork.cpp in Sources */,
549947F1196A3FB400BA3D87 /* ScrollDetection.cpp in Sources */,
@@ -367,6 +366,7 @@
4CC6094F197E009D00BE8B8B /* down_sample_aarch64_neon.S in Sources */,
4CC6095A1980F34F00BE8B8B /* vaa_calc_aarch64_neon.S in Sources */,
549947F2196A3FB400BA3D87 /* ScrollDetectionFuncs.cpp in Sources */,
F791965B19D3BF6B00F60C6B /* intra_pred_common.cpp in Sources */,
549947EF196A3FB400BA3D87 /* imagerotatefuncs.cpp in Sources */,
549947DF196A3FB400BA3D87 /* AdaptiveQuantization.cpp in Sources */,
549947EC196A3FB400BA3D87 /* downsample.cpp in Sources */,

View File

@@ -381,6 +381,10 @@
RelativePath="..\..\..\encoder\core\src\get_intra_predictor.cpp"
>
</File>
<File
RelativePath="..\..\..\common\src\intra_pred_common.cpp"
>
</File>
<File
RelativePath="..\..\..\encoder\core\src\mc.cpp"
>
@@ -727,7 +731,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -745,7 +749,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -767,7 +771,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -959,6 +963,46 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\common\x86\intra_pred_com.asm"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\encoder\core\x86\matrix_transpose.asm"
>
@@ -1327,7 +1371,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -1345,7 +1389,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>

View File

@@ -0,0 +1,83 @@
/*!
* \copy
* Copyright (c) 2013, Cisco Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifdef HAVE_NEON
.text
#include "arm_arch_common_macro.S"
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredV_neon
//Get the top line data to 'q0'
sub r3, r1, r2
vldm r3, {d0, d1}
//mov r2, #16
mov r3, #4
//Set the top line to the each line of MB(16*16)
loop_0_get_i16x16_luma_pred_v:
vst1.8 {d0,d1}, [r0]!
vst1.8 {d0,d1}, [r0]!
vst1.8 {d0,d1}, [r0]!
vst1.8 {d0,d1}, [r0]!
subs r3, #1
bne loop_0_get_i16x16_luma_pred_v
WELS_ASM_FUNC_END
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredH_neon
//stmdb sp!, {r4, lr}
sub r1, r1, #1
mov r3, #4
loop_0_get_i16x16_luma_pred_h:
//Get one byte data from left side
vld1.8 {d0[],d1[]}, [r1], r2
vld1.8 {d2[],d3[]}, [r1], r2
vld1.8 {d4[],d5[]}, [r1], r2
vld1.8 {d6[],d7[]}, [r1], r2
//Set the line of MB using the left side byte data
vst1.8 {d0,d1}, [r0]!
//add r0, #16
vst1.8 {d2,d3}, [r0]!
//add r0, #16
vst1.8 {d4,d5}, [r0]!
//add r0, #16
vst1.8 {d6,d7}, [r0]!
//add r0, #16
subs r3, #1
bne loop_0_get_i16x16_luma_pred_h
WELS_ASM_FUNC_END
#endif

View File

@@ -0,0 +1,55 @@
/*!
* \copy
* Copyright (c) 2013, Cisco Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifdef HAVE_NEON_AARCH64
.text
#include "arm_arch64_common_macro.S"
//for Luma 16x16
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredV_AArch64_neon
sub x3, x1, x2
ld1 {v0.16b}, [x3]
.rept 16
st1 {v0.16b}, [x0], 16
.endr
WELS_ASM_AARCH64_FUNC_END
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredH_AArch64_neon
sub x3, x1, #1
.rept 16
ld1r {v0.16b}, [x3], x2
st1 {v0.16b}, [x0], 16
.endr
WELS_ASM_AARCH64_FUNC_END
#endif

View File

@@ -117,6 +117,8 @@ WELS_THREAD_ERROR_CODE WelsMultipleEventsWaitAllBlocking (uint32_t nCount, WE
WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
void* arg, WELS_THREAD_ATTR attr);
WELS_THREAD_ERROR_CODE WelsThreadSetName (const char* thread_name);
WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread);
WELS_THREAD_HANDLE WelsThreadSelf();

View File

@@ -0,0 +1,76 @@
/*!
* \copy
* Copyright (c) 2009-2013, Cisco Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* \file intra_pred_common.h
*
* \brief interfaces for intra predictor about 16x16.
*
* \date 4/2/2014 Created
*
*************************************************************************************
*/
#ifndef INTRA_PRED_COMMON_H
#define INTRA_PRED_COMMON_H
#include "typedefs.h"
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
#if defined(__cplusplus)
extern "C" {
#endif//__cplusplus
#if defined(X86_ASM)
//for intra-prediction ASM functions
void WelsI16x16LumaPredV_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
#endif//X86_ASM
#if defined(HAVE_NEON)
void WelsI16x16LumaPredV_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
#endif//HAVE_NEON
#if defined(HAVE_NEON_AARCH64)
void WelsI16x16LumaPredV_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
#endif//HAVE_NEON_AARCH64
#if defined(__cplusplus)
}
#endif//__cplusplus
#endif//

View File

@@ -1,6 +1,6 @@
#ifndef VERSION_H
#define VERSION_H
#define VERSION_NUMBER "openh264 default: 1.1"
#define VERSION_NUMBER "openh264 default: 1.2"
#endif // VERSION_H

View File

@@ -155,7 +155,7 @@ enum EWelsSliceType {
UNKNOWN_SLICE = 5
};
/* SSlice Types in scalable extension */ ;
/* SSlice Types in scalable extension */
enum ESliceTypeExt {
EP_SLICE = 0, // EP_SLICE: 0, 5
EB_SLICE = 1, // EB_SLICE: 1, 6

View File

@@ -58,6 +58,9 @@
#ifdef ANDROID_NDK
#include <cpu-features.h>
#endif
#ifdef __ANDROID__
#include <android/api-level.h>
#endif
#include "WelsThreadLib.h"
#include <stdio.h>
@@ -195,6 +198,12 @@ WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_
return WELS_THREAD_ERROR_OK;
}
WELS_THREAD_ERROR_CODE WelsThreadSetName (const char* thread_name) {
// do nothing
return WELS_THREAD_ERROR_OK;
}
WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
WaitForSingleObject (thread, INFINITE);
CloseHandle (thread);
@@ -242,6 +251,17 @@ WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_
return err;
}
WELS_THREAD_ERROR_CODE WelsThreadSetName (const char* thread_name) {
#ifdef APPLE_IOS
pthread_setname_np(thread_name);
#endif
#if defined(__ANDROID__) && __ANDROID_API__ >= 9
pthread_setname_np(pthread_self(), thread_name);
#endif
// do nothing
return WELS_THREAD_ERROR_OK;
}
WELS_THREAD_ERROR_CODE WelsThreadJoin (WELS_THREAD_HANDLE thread) {
return pthread_join (thread, NULL);
}

View File

@@ -1,6 +1,6 @@
/*!
* \copy
* Copyright (c) 2013, Cisco Systems
* Copyright (c) 2009-2013, Cisco Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,12 +28,21 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* \file get_intra_predictor.c
*
* \brief implementation for get intra predictor about 16x16, 4x4, chroma.
*
* \date 4/2/2009 Created
* 9/14/2009 C level based optimization with high performance gained.
* [const, using ST32/ST64 to replace memset, memcpy and memmove etc.]
*
*************************************************************************************
*/
#include "common.h"
#include "ls_defines.h"
#include "cpu_core.h"
#include "intra_pred_common.h"
WELSVP_NAMESPACE_BEGIN
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
uint8_t i = 15;
@@ -66,4 +75,3 @@ void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStrid
} while (i-- > 0);
}
WELSVP_NAMESPACE_END

View File

@@ -136,4 +136,4 @@ void WelsSampleSadFour4x4_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSamp
* (pSad + 1) = WelsSampleSad4x4_c (iSample1, iStride1, (iSample2 + iStride2), iStride2);
* (pSad + 2) = WelsSampleSad4x4_c (iSample1, iStride1, (iSample2 - 1), iStride2);
* (pSad + 3) = WelsSampleSad4x4_c (iSample1, iStride1, (iSample2 + 1), iStride2);
}
}

View File

@@ -68,7 +68,7 @@ void WelsLog (SLogContext* logCtx, int32_t iLevel, const char* kpFmt, ...) {
WelsSnprintf (pTraceTag, MAX_LOG_SIZE, "[OpenH264] Detail:");
break;
}
WelsStrcat(pTraceTag,MAX_LOG_SIZE,kpFmt);
WelsStrcat (pTraceTag, MAX_LOG_SIZE, kpFmt);
va_start (vl, kpFmt);
logCtx->pfLog (logCtx->pLogCtx, iLevel, pTraceTag, vl);
va_end (vl);

View File

@@ -78,8 +78,9 @@ void welsCodecTrace::CodecTrace (const int32_t iLevel, const char* Str_Format, v
char pBuf[MAX_LOG_SIZE] = {0};
WelsVsnprintf (pBuf, MAX_LOG_SIZE, Str_Format, vl); // confirmed_safe_unsafe_usage
m_fpTrace (m_pTraceCtx, iLevel, pBuf);
if (m_fpTrace) {
m_fpTrace (m_pTraceCtx, iLevel, pBuf);
}
}
void welsCodecTrace::SetTraceLevel (const int32_t iLevel) {

View File

@@ -6,6 +6,7 @@ COMMON_CPP_SRCS=\
$(COMMON_SRCDIR)/src/crt_util_safe_x.cpp\
$(COMMON_SRCDIR)/src/deblocking_common.cpp\
$(COMMON_SRCDIR)/src/expand_pic.cpp\
$(COMMON_SRCDIR)/src/intra_pred_common.cpp\
$(COMMON_SRCDIR)/src/sad_common.cpp\
$(COMMON_SRCDIR)/src/utils.cpp\
$(COMMON_SRCDIR)/src/welsCodecTrace.cpp\
@@ -13,41 +14,51 @@ COMMON_CPP_SRCS=\
COMMON_OBJS += $(COMMON_CPP_SRCS:.cpp=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
COMMON_ASM_SRCS=\
$(COMMON_SRCDIR)/x86/cpuid.asm\
$(COMMON_SRCDIR)/x86/deblock.asm\
$(COMMON_SRCDIR)/x86/expand_picture.asm\
$(COMMON_SRCDIR)/x86/intra_pred_com.asm\
$(COMMON_SRCDIR)/x86/mb_copy.asm\
$(COMMON_SRCDIR)/x86/mc_chroma.asm\
$(COMMON_SRCDIR)/x86/mc_luma.asm\
$(COMMON_SRCDIR)/x86/satd_sad.asm\
$(COMMON_SRCDIR)/x86/vaa.asm\
COMMON_OBJS += $(COMMON_ASM_SRCS:.asm=.$(OBJ))
COMMON_OBJSASM += $(COMMON_ASM_SRCS:.asm=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
COMMON_OBJS += $(COMMON_OBJSASM)
endif
OBJS += $(COMMON_OBJSASM)
ifeq ($(ASM_ARCH), arm)
COMMON_ASM_ARM_SRCS=\
$(COMMON_SRCDIR)/arm/copy_mb_neon.S\
$(COMMON_SRCDIR)/arm/deblocking_neon.S\
$(COMMON_SRCDIR)/arm/expand_picture_neon.S\
$(COMMON_SRCDIR)/arm/intra_pred_common_neon.S\
$(COMMON_SRCDIR)/arm/mc_neon.S\
COMMON_OBJS += $(COMMON_ASM_ARM_SRCS:.S=.$(OBJ))
COMMON_OBJSARM += $(COMMON_ASM_ARM_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm)
COMMON_OBJS += $(COMMON_OBJSARM)
endif
OBJS += $(COMMON_OBJSARM)
ifeq ($(ASM_ARCH), arm64)
COMMON_ASM_ARM64_SRCS=\
$(COMMON_SRCDIR)/arm64/copy_mb_aarch64_neon.S\
$(COMMON_SRCDIR)/arm64/deblocking_aarch64_neon.S\
$(COMMON_SRCDIR)/arm64/expand_picture_aarch64_neon.S\
$(COMMON_SRCDIR)/arm64/intra_pred_common_aarch64_neon.S\
$(COMMON_SRCDIR)/arm64/mc_aarch64_neon.S\
COMMON_OBJS += $(COMMON_ASM_ARM64_SRCS:.S=.$(OBJ))
COMMON_OBJSARM64 += $(COMMON_ASM_ARM64_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm64)
COMMON_OBJS += $(COMMON_OBJSARM64)
endif
OBJS += $(COMMON_OBJSARM64)
OBJS += $(COMMON_OBJS)
$(COMMON_SRCDIR)/%.$(OBJ): $(COMMON_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(COMMON_CFLAGS) $(COMMON_INCLUDES) -c $(CXX_O) $<

View File

@@ -0,0 +1,117 @@
;*!
;* \copy
;* Copyright (c) 2009-2013, Cisco Systems
;* All rights reserved.
;*
;* Redistribution and use in source and binary forms, with or without
;* modification, are permitted provided that the following conditions
;* are met:
;*
;* * Redistributions of source code must retain the above copyright
;* notice, this list of conditions and the following disclaimer.
;*
;* * Redistributions in binary form must reproduce the above copyright
;* notice, this list of conditions and the following disclaimer in
;* the documentation and/or other materials provided with the
;* distribution.
;*
;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
;* POSSIBILITY OF SUCH DAMAGE.
;*
;*
;* intra_pred_common.asm
;*
;* Abstract
;* sse2 function for intra predict operations
;*
;* History
;* 18/09/2009 Created
;*
;*
;*************************************************************************/
%include "asm_inc.asm"
;***********************************************************************
; Code
;***********************************************************************
SECTION .text
;***********************************************************************
; void WelsI16x16LumaPredH_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
;***********************************************************************
%macro SSE2_PRED_H_16X16_ONE_LINE 0
add r0, 16
add r1, r2
movzx r3, byte [r1]
SSE2_Copy16Times xmm0, r3d
movdqa [r0], xmm0
%endmacro
WELS_EXTERN WelsI16x16LumaPredH_sse2
push r3
%assign push_num 1
LOAD_3_PARA
SIGN_EXTENSION r2, r2d
dec r1
movzx r3, byte [r1]
SSE2_Copy16Times xmm0, r3d
movdqa [r0], xmm0
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
pop r3
ret
;***********************************************************************
; void WelsI16x16LumaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
;***********************************************************************
WELS_EXTERN WelsI16x16LumaPredV_sse2
%assign push_num 0
LOAD_3_PARA
SIGN_EXTENSION r2, r2d
sub r1, r2
movdqa xmm0, [r1]
movdqa [r0], xmm0
movdqa [r0+10h], xmm0
movdqa [r0+20h], xmm0
movdqa [r0+30h], xmm0
movdqa [r0+40h], xmm0
movdqa [r0+50h], xmm0
movdqa [r0+60h], xmm0
movdqa [r0+70h], xmm0
movdqa [r0+80h], xmm0
movdqa [r0+90h], xmm0
movdqa [r0+160], xmm0
movdqa [r0+176], xmm0
movdqa [r0+192], xmm0
movdqa [r0+208], xmm0
movdqa [r0+224], xmm0
movdqa [r0+240], xmm0
ret

View File

@@ -42,26 +42,25 @@
#include <stdlib.h>
#include <string>
using namespace std;
class CReadConfig {
public:
CReadConfig();
CReadConfig (const char* pConfigFileName);
CReadConfig (const string& pConfigFileName);
CReadConfig (const std::string& pConfigFileName);
virtual ~CReadConfig();
void Openf (const char* strFile);
long ReadLine (string* strVal, const int iValSize = 4);
long ReadLine (std::string* strVal, const int iValSize = 4);
const bool EndOfFile();
const int GetLines();
const bool ExistFile();
const string& GetFileName();
const std::string& GetFileName();
private:
FILE* m_pCfgFile;
string m_strCfgFileName;
std::string m_strCfgFileName;
unsigned int m_iLines;
};

View File

@@ -58,7 +58,7 @@ CReadConfig::CReadConfig (const char* kpConfigFileName)
}
}
CReadConfig::CReadConfig (const string& kpConfigFileName)
CReadConfig::CReadConfig (const std::string& kpConfigFileName)
: m_pCfgFile (0)
, m_strCfgFileName (kpConfigFileName)
, m_iLines (0) {
@@ -81,11 +81,11 @@ void CReadConfig::Openf (const char* kpStrFile) {
}
}
long CReadConfig::ReadLine (string* pVal, const int kiValSize/* = 4*/) {
long CReadConfig::ReadLine (std::string* pVal, const int kiValSize/* = 4*/) {
if (m_pCfgFile == NULL || pVal == NULL || kiValSize <= 1)
return 0;
string* strTags = &pVal[0];
std::string* strTags = &pVal[0];
int nTagNum = 0, n = 0;
bool bCommentFlag = false;
@@ -134,6 +134,6 @@ const bool CReadConfig::ExistFile() {
return (m_pCfgFile != NULL);
}
const string& CReadConfig::GetFileName() {
const std::string& CReadConfig::GetFileName() {
return m_strCfgFileName;
}

View File

@@ -5,6 +5,7 @@ CONSOLE_COMMON_CPP_SRCS=\
CONSOLE_COMMON_OBJS += $(CONSOLE_COMMON_CPP_SRCS:.cpp=.$(OBJ))
OBJS += $(CONSOLE_COMMON_OBJS)
$(CONSOLE_COMMON_SRCDIR)/%.$(OBJ): $(CONSOLE_COMMON_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(CONSOLE_COMMON_CFLAGS) $(CONSOLE_COMMON_INCLUDES) -c $(CXX_O) $<

View File

@@ -6,6 +6,7 @@ H264DEC_CPP_SRCS=\
H264DEC_OBJS += $(H264DEC_CPP_SRCS:.cpp=.$(OBJ))
OBJS += $(H264DEC_OBJS)
$(H264DEC_SRCDIR)/%.$(OBJ): $(H264DEC_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(H264DEC_CFLAGS) $(H264DEC_INCLUDES) -c $(CXX_O) $<

View File

@@ -294,6 +294,8 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
pSvcParam.iLTRRefNum = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("LtrMarkPeriod") == 0) {
pSvcParam.iLtrMarkPeriod = (uint32_t)atoi (strTag[1].c_str());
} else if (strTag[0].compare ("LosslessLink") == 0) {
pSvcParam.bIsLosslessLink = atoi (strTag[1].c_str()) ? true : false;
} else if (strTag[0].compare ("NumLayers") == 0) {
pSvcParam.iSpatialLayerNum = (int8_t)atoi (strTag[1].c_str());
if (pSvcParam.iSpatialLayerNum > MAX_DEPENDENCY_LAYER || pSvcParam.iSpatialLayerNum <= 0) {
@@ -382,7 +384,7 @@ void PrintHelp() {
int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamExt& pSvcParam, SFilesSet& sFileSet) {
char* pCommand = NULL;
SLayerPEncCtx sLayerCtx[3];
SLayerPEncCtx sLayerCtx[MAX_SPATIAL_LAYER_NUM];
int n = 0;
string str_ ("SlicesAssign");
@@ -805,10 +807,10 @@ int ProcessEncoding (ISVCEncoder* pPtrEnc, int argc, char** argv, bool bConfigFi
break;
// To encoder this frame
iStart = WelsTime();
pSrcPic->uiTimeStamp = WELS_ROUND (iFrameIdx * (1000 / sSvcParam.fMaxFrameRate));
int iEncFrames = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
iTotal += WelsTime() - iStart;
// fixed issue in case dismatch source picture introduced by frame skipped, 1/12/2010
++ iFrameIdx;
if (videoFrameTypeSkip == sFbi.eFrameType) {
continue;
}
@@ -859,7 +861,6 @@ int ProcessEncoding (ISVCEncoder* pPtrEnc, int argc, char** argv, bool bConfigFi
fprintf (stderr, "EncodeFrame(), ret: %d, frame index: %d.\n", iEncFrames, iFrameIdx);
}
++ iFrameIdx;
}
if (iActualFrameEncodedCount > 0) {
@@ -891,7 +892,7 @@ INSIDE_MEM_FREE:
pFileYUV = NULL;
}
if (pYUV) {
delete pYUV;
delete[] pYUV;
pYUV = NULL;
}
if (pSrcPic) {

View File

@@ -5,6 +5,7 @@ H264ENC_CPP_SRCS=\
H264ENC_OBJS += $(H264ENC_CPP_SRCS:.cpp=.$(OBJ))
OBJS += $(H264ENC_OBJS)
$(H264ENC_SRCDIR)/%.$(OBJ): $(H264ENC_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(H264ENC_CFLAGS) $(H264ENC_INCLUDES) -c $(CXX_O) $<

View File

@@ -316,7 +316,6 @@ int32_t iFeedbackVclNalInAu;
int32_t iFeedbackTidInAu;
bool bAuReadyFlag; // true: one au is ready for decoding; false: default value
bool bDecErrorConedFlag; //true: current decoder is error coned
bool bPrintFrameErrorTraceFlag; //true: can print info for upper layer
int32_t iIgnoredErrorInfoPacketCount; //store the packet number with error decoding info

View File

@@ -144,8 +144,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
/*
* Check if frame is completed and EC is required
*/
bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** pDst, SBufferInfo* pDstInfo);
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** pDst, SBufferInfo* pDstInfo);
/*
* Prepare current dq layer context initialization.
*/
@@ -158,6 +157,7 @@ void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
void ForceResetCurrentAccessUnit (PAccessUnit pAu);
void ForceClearCurrentNal (PAccessUnit pAu);
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx); // Check whether all ref pictures are complete
} // namespace WelsDec
#endif//WELS_DECODER_CORE_H__

View File

@@ -48,7 +48,7 @@ ERR_INVALID_PARAMETERS = 1,
ERR_MALLOC_FAILED = 2,
ERR_API_FAILED = 3,
ERR_BOUND = 31,
ERR_BOUND = 31
} EWelsErr;
/*
@@ -68,7 +68,7 @@ ERR_LEVEL_PREFIX_NAL,
ERR_LEVEL_PARAM_SETS,
ERR_LEVEL_SLICE_HEADER,
ERR_LEVEL_SLICE_DATA,
ERR_LEVEL_MB_DATA,
ERR_LEVEL_MB_DATA
};
//-----------------------------------------------------------------------------------------------------------
@@ -180,7 +180,7 @@ EER_INFO_INVALID_MMCO_LONG2UNUSED,
ERR_INFO_INVALID_MMCO_SHOART2LONG,
ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW,
ERR_INFO_INVALID_MMCO_REF_NUM_NOT_ENOUGH,
ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX,
ERR_INFO_INVALID_MMCO_LONG_TERM_IDX_EXCEED_MAX
};
//-----------------------------------------------------------------------------------------------------------

View File

@@ -63,6 +63,7 @@ bool bIsLongRef; // long term reference frame flag //for ref pic management
uint8_t uiRefCount;
bool bAvailableFlag; // indicate whether it is available in this picture memory block.
bool bIsComplete; // indicate whether current picture is complete, not from EC
/*******************************for future use****************************/
uint8_t uiTemporalId;
uint8_t uiSpatialId;

View File

@@ -60,7 +60,7 @@ PRO_HIGH444 = 144,
PRO_CAVLC444 = 244,
PRO_SCALABLE_BASELINE = 83,
PRO_SCALABLE_HIGH = 86,
PRO_SCALABLE_HIGH = 86
};
/* Picture Size */
@@ -83,7 +83,7 @@ MB_LEFT = 0x01, // A
MB_TOP = 0x02, // B
MB_TOPRIGHT = 0x04, // C
MB_TOPLEFT = 0x08, // D,
MB_PRIVATE = 0x10,
MB_PRIVATE = 0x10
};
/* MB Type & Sub-MB Type */
typedef int32_t MbType;

View File

@@ -419,7 +419,7 @@ int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNal
}
if (iUsedBits > pBs->iBits) { //When BS incomplete, as long as find it, SHOULD stop decoding to avoid mosaic or crash.
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"WelsDecodeSlice()::::pBs incomplete, iUsedBits:%"PRId64" > pBs->iBits:%d, MUST stop decoding.",
"WelsDecodeSlice()::::pBs incomplete, iUsedBits:%" PRId64" > pBs->iBits:%d, MUST stop decoding.",
(int64_t) iUsedBits, pBs->iBits);
return -1;
}
@@ -1065,9 +1065,9 @@ void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) {
#endif
#ifdef HAVE_NEON_AARCH64
if (iCpu & WELS_CPU_NEON) {
pFunc->pWelsSetNonZeroCountFunc = SetNonZeroCount_AArch64_neon;
}
if (iCpu & WELS_CPU_NEON) {
pFunc->pWelsSetNonZeroCountFunc = SetNonZeroCount_AArch64_neon;
}
#endif
}

View File

@@ -273,10 +273,12 @@ void WelsFreeMem (PWelsDecoderContext pCtx) {
/*!
* \brief Open decoder
*/
void WelsOpenDecoder (PWelsDecoderContext pCtx) {
int32_t WelsOpenDecoder (PWelsDecoderContext pCtx) {
// function pointers
//initial MC function pointer--
int iRet = ERR_NONE;
InitMcFunc (& (pCtx->sMcFunc), pCtx->uiCpuFlag);
InitErrorCon (pCtx);
InitExpandPictureFunc (& (pCtx->sExpandPicFunc), pCtx->uiCpuFlag);
AssignFuncPointerForRec (pCtx);
@@ -285,8 +287,9 @@ void WelsOpenDecoder (PWelsDecoderContext pCtx) {
InitVlcTable (&pCtx->sVlcTable);
// startup memory
if (ERR_NONE != WelsInitMemory (pCtx))
return;
iRet = WelsInitMemory (pCtx);
if (ERR_NONE != iRet)
return iRet;
#ifdef LONG_TERM_REF
pCtx->bParamSetsLostFlag = true;
@@ -294,9 +297,9 @@ void WelsOpenDecoder (PWelsDecoderContext pCtx) {
pCtx->bReferenceLostAtT0Flag = true; // should be true to waiting IDR at incoming AU bits following, 6/4/2010
#endif //LONG_TERM_REF
pCtx->bNewSeqBegin = true;
pCtx->bDecErrorConedFlag = false; //default: decoder normal status
pCtx->bPrintFrameErrorTraceFlag = true;
pCtx->iIgnoredErrorInfoPacketCount = 0;
return iRet;
}
/*!
@@ -332,6 +335,9 @@ int32_t DecoderConfigParam (PWelsDecoderContext pCtx, const SDecodingParam* kpPa
memcpy (pCtx->pParam, kpParam, sizeof (SDecodingParam));
pCtx->eOutputColorFormat = pCtx->pParam->eOutputColorFormat;
int32_t iRet = DecoderSetCsp (pCtx, pCtx->pParam->eOutputColorFormat);
if (iRet)
return iRet;
pCtx->eErrorConMethod = pCtx->pParam->eEcActiveIdc;
if (VIDEO_BITSTREAM_SVC == pCtx->pParam->sVideoProperty.eVideoBsType ||
@@ -367,10 +373,7 @@ int32_t WelsInitDecoder (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
WelsDecoderDefaults (pCtx, pLogCtx);
// open decoder
WelsOpenDecoder (pCtx);
return ERR_NONE;
return WelsOpenDecoder (pCtx);
}
/*!
@@ -462,8 +465,8 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
iConsumedBytes = 0;
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
if ((pCtx->eErrorConMethod != ERROR_CON_DISABLE) && (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1))) {
CheckAndDoEC (pCtx, ppDst, pDstBufInfo);
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
}
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
@@ -522,8 +525,8 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
iConsumedBytes = 0;
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
if ((pCtx->eErrorConMethod != ERROR_CON_DISABLE) && (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1))) {
CheckAndDoEC (pCtx, ppDst, pDstBufInfo);
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
}
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
@@ -595,9 +598,12 @@ int32_t DecoderSetCsp (PWelsDecoderContext pCtx, const int32_t kiColorFormat) {
}
//For now, support only videoFormatI420!
if (kiColorFormat != (int32_t) videoFormatI420) {
if (kiColorFormat == (int32_t) videoFormatInternal) {
pCtx->pParam->eOutputColorFormat = pCtx->eOutputColorFormat = videoFormatI420;
} else if (kiColorFormat != (int32_t) videoFormatI420) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Support I420 output only for now! Change to I420...");
pCtx->pParam->eOutputColorFormat = pCtx->eOutputColorFormat = videoFormatI420;
return cmUnsupportedData;
}
return 0;

View File

@@ -82,7 +82,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
return -1;
} else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
&& (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done
pCtx->bDecErrorConedFlag = false;
pCtx->pDec->bIsComplete = true;
}
pCtx->iTotalNumMbRec = 0;
@@ -104,10 +104,12 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
pDstInfo->iBufferStatus = 1;
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete
pDstInfo->iBufferStatus = (int32_t) bFrameCompleteFlag;
pDstInfo->iBufferStatus = (int32_t) (bFrameCompleteFlag
&& pPic->bIsComplete); // When EC disable, ECed picture not output
if (!bFrameCompleteFlag) {
pCtx->iErrorCode |= dsBitstreamError;
if (pDstInfo->iBufferStatus == 0) {
if (!bFrameCompleteFlag)
pCtx->iErrorCode |= dsBitstreamError;
return -1;
}
@@ -541,7 +543,10 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);
}
pPps = &pCtx->sPpsBuffer[iPpsId];
if (pCtx->iOverwriteFlags & OVERWRITE_PPS)
pPps = &pCtx->sPpsBuffer[MAX_PPS_COUNT];
else
pPps = &pCtx->sPpsBuffer[iPpsId];
if (pPps->uiNumSliceGroups == 0) {
WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
@@ -550,7 +555,10 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
}
if (kbExtensionFlag) {
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
if (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS)
pSubsetSps = &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT];
else
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
pSps = &pSubsetSps->sSps;
if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id is invalid!");
@@ -563,7 +571,10 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
pCtx->iErrorCode |= dsNoParamSets;
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
}
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
if (pCtx->iOverwriteFlags & OVERWRITE_SPS)
pSps = &pCtx->sSpsBuffer[MAX_SPS_COUNT];
else
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
}
pSliceHead->iPpsId = iPpsId;
pSliceHead->iSpsId = pPps->iSpsId;
@@ -1657,7 +1668,6 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr);
return iErr;
}
InitErrorCon (pCtx); //Do EC initialization here, for sequence start
}
@@ -1781,6 +1791,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
int32_t iPpsId = 0;
int32_t iRet = ERR_NONE;
bool bAllRefComplete = true; // Assume default all ref picutres are complete
const uint8_t kuiTargetLayerDqId = GetTargetDqId (pCtx->uiTargetDqId, pCtx->pParam);
const uint8_t kuiDependencyIdMax = (kuiTargetLayerDqId & 0x7F) >> 4;
int16_t iLastIdD = -1, iLastIdQ = -1;
@@ -1890,6 +1902,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
"referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d", pCtx->iPrevFrameNum,
pSh->iFrameNum);
bAllRefComplete = false;
pCtx->iErrorCode |= dsRefLost;
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
#ifdef LONG_TERM_REF
@@ -1906,6 +1919,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID) {
iRet = InitRefPicList (pCtx, uiNalRefIdc, pSh->iPicOrderCntLsb);
if (iRet) {
bAllRefComplete = false; // RPLR error, set ref pictures complete flag false
HandleReferenceLost (pCtx, pNalCur);
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"reference picture introduced by this frame is lost during transmission! uiTId: %d",
@@ -1923,6 +1937,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"DecodeCurrentAccessUnit() failed (%d) in frame: %d uiDId: %d uiQId: %d",
iRet, pSh->iFrameNum, iCurrIdD, iCurrIdQ);
bAllRefComplete = false;
HandleReferenceLostL0 (pCtx, pNalCur);
if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
return iRet;
@@ -1930,9 +1945,13 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
}
if (bReconstructSlice) {
if (WelsDecodeConstructSlice (pCtx, pNalCur)) {
pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false
return -1;
}
}
if (bAllRefComplete && (pCtx->sRefPic.uiRefCount[LIST_0] > 0 || pCtx->eSliceType != I_SLICE)) {
bAllRefComplete &= bCheckRefPicturesComplete (pCtx);
}
}
#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
fprintf (stderr, "cur_frame : %d iCurrIdD : %d\n ",
@@ -1955,6 +1974,12 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
break;
}
// Set the current dec picture complete flag. The flag will be reset when current picture need do ErrorCon.
pCtx->pDec->bIsComplete = bAllRefComplete;
if (!pCtx->pDec->bIsComplete) { // Ref pictures ECed, result in ECed
pCtx->iErrorCode |= dsDataErrorConcealed;
}
// A dq layer decoded here
#if defined (_DEBUG) && !defined (CODEC_FOR_TESTBED)
#undef fprintf
@@ -1966,9 +1991,11 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
if (dq_cur->uiLayerDqId == kuiTargetLayerDqId) {
if (!pCtx->bInstantDecFlag) {
//Do error concealment here
if (NeedErrorCon (pCtx)) {
if ((NeedErrorCon (pCtx)) && (pCtx->eErrorConMethod != ERROR_CON_DISABLE)) {
ImplementErrorCon (pCtx);
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
}
}
@@ -2001,7 +2028,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
return ERR_NONE;
}
bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
PAccessUnit pAu = pCtx->pAccessUnitList;
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
if ((pCtx->iTotalNumMbRec != 0)
@@ -2009,12 +2036,20 @@ bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstI
&pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader))) {
//Do Error Concealment here
if (NeedErrorCon (pCtx)) { //should always be true!
ImplementErrorCon (pCtx);
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
MarkECFrameAsRef (pCtx);
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
ImplementErrorCon (pCtx);
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
MarkECFrameAsRef (pCtx);
}
} else {
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo))
return false;
}
pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
if (pCtx->bLastHasMmco5)
@@ -2024,4 +2059,41 @@ bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstI
return ERR_NONE;
}
bool bCheckRefPicturesComplete (PWelsDecoderContext pCtx) {
// Multi Reference, RefIdx may differ
bool bAllRefComplete = true;
int32_t iRealMbIdx;
for (int32_t iMbIdx = 0; bAllRefComplete
&& iMbIdx < pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.iTotalMbInCurSlice; iMbIdx++) {
iRealMbIdx = pCtx->pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.iFirstMbInSlice + iMbIdx;
switch (pCtx->pCurDqLayer->pMbType[iRealMbIdx]) {
case MB_TYPE_SKIP:
case MB_TYPE_16x16:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
break;
case MB_TYPE_16x8:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
break;
case MB_TYPE_8x16:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
break;
case MB_TYPE_8x8:
case MB_TYPE_8x8_REF0:
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][0] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][2] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][8] ]->bIsComplete;
bAllRefComplete &= pCtx->sRefPic.pRefList[ LIST_0 ][ pCtx->pCurDqLayer->pRefIndex[0][iRealMbIdx][10] ]->bIsComplete;
break;
default:
break;
}
}
return bAllRefComplete;
}
} // namespace WelsDec

View File

@@ -189,7 +189,7 @@ void ImplementErrorCon (PWelsDecoderContext pCtx) {
DoErrorConSliceCopy (pCtx);
} //TODO add other EC methods here in the future
pCtx->iErrorCode |= dsDataErrorConcealed;
pCtx->bDecErrorConedFlag = true;
pCtx->pDec->bIsComplete = false; // Set complete flag to false after do EC.
}
} // namespace WelsDec

View File

@@ -73,6 +73,7 @@ static void SetUnRef (PPicture pRef) {
pRef->uiTemporalId = -1;
pRef->uiSpatialId = -1;
pRef->iSpsId = -1;
pRef->bIsComplete = false;
}
}
@@ -115,6 +116,9 @@ int32_t WelsInitRefList (PWelsDecoderContext pCtx, int32_t iPoc) {
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
PPicture pRef = PrefetchPic (pCtx->pPicBuff[0]);
if (pRef != NULL) {
// IDR lost, set new
pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
pCtx->iErrorCode |= dsDataErrorConcealed;
memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);

View File

@@ -85,6 +85,9 @@ virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* kpSrc,
const int kiSrcLen,
unsigned char** ppDst,
SBufferInfo* pDstInfo);
virtual DECODING_STATE EXTAPI DecodeParser (const unsigned char* kpSrc,
const int kiSrcLen,
SParserBsInfo* pDstInfo);
virtual DECODING_STATE EXTAPI DecodeFrameEx (const unsigned char* kpSrc,
const int kiSrcLen,
unsigned char* pDst,
@@ -101,7 +104,7 @@ virtual long EXTAPI GetOption (DECODER_OPTION eOptID, void* pOption);
PWelsDecoderContext m_pDecContext;
welsCodecTrace* m_pWelsTrace;
void InitDecoder (void);
int32_t InitDecoder (void);
void UninitDecoder (void);
#ifdef OUTPUT_BIT_STREAM

View File

@@ -51,6 +51,7 @@
//#include "macros.h"
#include "decoder.h"
#include "decoder_core.h"
#include "error_concealment.h"
extern "C" {
#include "decoder_core.h"
@@ -184,6 +185,7 @@ CWelsDecoder::~CWelsDecoder() {
}
long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
int iRet = ERR_NONE;
if (m_pWelsTrace == NULL) {
return cmMallocMemeError;
}
@@ -194,9 +196,13 @@ long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
}
// H.264 decoder initialization,including memory allocation,then open it ready to decode
InitDecoder();
iRet = InitDecoder();
if (iRet)
return iRet;
DecoderConfigParam (m_pDecContext, pParam);
iRet = DecoderConfigParam (m_pDecContext, pParam);
if (iRet)
return iRet;
return cmResultSuccess;
}
@@ -225,15 +231,16 @@ void CWelsDecoder::UninitDecoder (void) {
}
// the return value of this function is not suitable, it need report failure info to upper layer.
void CWelsDecoder::InitDecoder (void) {
int32_t CWelsDecoder::InitDecoder (void) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::init_decoder(), openh264 codec version = %s",
VERSION_NUMBER);
m_pDecContext = (PWelsDecoderContext)WelsMalloc (sizeof (SWelsDecoderContext), "m_pDecContext");
if (NULL == m_pDecContext)
return cmMallocMemeError;
WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
return WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
}
/*
@@ -263,11 +270,16 @@ long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
return cmResultSuccess;
} else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
if (pOption == NULL) //Default: SLICE_COPY, enable
iVal = ERROR_CON_SLICE_COPY;
else
iVal = * ((int*)pOption); //EC method
if (pOption == NULL)
return cmInitParaError;
iVal = * ((int*)pOption); // int value for error concealment idc
iVal = WELS_CLIP3 (iVal, (int32_t) ERROR_CON_DISABLE, (int32_t) ERROR_CON_SLICE_COPY);
m_pDecContext->eErrorConMethod = (ERROR_CON_IDC) iVal;
InitErrorCon (m_pDecContext);
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
return cmResultSuccess;
} else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
if (m_pWelsTrace) {
@@ -424,17 +436,24 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
m_pDecContext->iIgnoredErrorInfoPacketCount = 0;
}
}
return (DECODING_STATE)m_pDecContext->iErrorCode;
} else { //decoding correct, but may have ECed status
if (m_pDecContext->bDecErrorConedFlag) {
if ((m_pDecContext->eErrorConMethod != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
//TODO after dec status updated
m_pDecContext->iErrorCode |= dsDataErrorConcealed;
return dsDataErrorConcealed;
}
return (DECODING_STATE) m_pDecContext->iErrorCode;
}
// else Error free, the current codec works well
return dsErrorFree;
}
DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
const int kiSrcLen,
SParserBsInfo* pDstInfo) {
//TODO, add function here
return (DECODING_STATE) m_pDecContext->iErrorCode;
}
DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
const int kiSrcLen,
unsigned char** ppDst,

View File

@@ -23,31 +23,38 @@ DECODER_CPP_SRCS=\
DECODER_OBJS += $(DECODER_CPP_SRCS:.cpp=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
DECODER_ASM_SRCS=\
$(DECODER_SRCDIR)/core/x86/dct.asm\
$(DECODER_SRCDIR)/core/x86/intra_pred.asm\
DECODER_OBJS += $(DECODER_ASM_SRCS:.asm=.$(OBJ))
DECODER_OBJSASM += $(DECODER_ASM_SRCS:.asm=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
DECODER_OBJS += $(DECODER_OBJSASM)
endif
OBJS += $(DECODER_OBJSASM)
ifeq ($(ASM_ARCH), arm)
DECODER_ASM_ARM_SRCS=\
$(DECODER_SRCDIR)/core/arm/block_add_neon.S\
$(DECODER_SRCDIR)/core/arm/intra_pred_neon.S\
DECODER_OBJS += $(DECODER_ASM_ARM_SRCS:.S=.$(OBJ))
DECODER_OBJSARM += $(DECODER_ASM_ARM_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm)
DECODER_OBJS += $(DECODER_OBJSARM)
endif
OBJS += $(DECODER_OBJSARM)
ifeq ($(ASM_ARCH), arm64)
DECODER_ASM_ARM64_SRCS=\
$(DECODER_SRCDIR)/core/arm64/block_add_aarch64_neon.S\
$(DECODER_SRCDIR)/core/arm64/intra_pred_aarch64_neon.S\
DECODER_OBJS += $(DECODER_ASM_ARM64_SRCS:.S=.$(OBJ))
DECODER_OBJSARM64 += $(DECODER_ASM_ARM64_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm64)
DECODER_OBJS += $(DECODER_OBJSARM64)
endif
OBJS += $(DECODER_OBJSARM64)
OBJS += $(DECODER_OBJS)
$(DECODER_SRCDIR)/%.$(OBJ): $(DECODER_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(DECODER_CFLAGS) $(DECODER_INCLUDES) -c $(CXX_O) $<

View File

@@ -62,51 +62,6 @@
#endif
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredV_neon
//Get the top line data to 'q0'
sub r3, r1, r2
vldm r3, {d0, d1}
//mov r2, #16
mov r3, #4
//Set the top line to the each line of MB(16*16)
loop_0_get_i16x16_luma_pred_v:
vst1.8 {d0,d1}, [r0]!
vst1.8 {d0,d1}, [r0]!
vst1.8 {d0,d1}, [r0]!
vst1.8 {d0,d1}, [r0]!
subs r3, #1
bne loop_0_get_i16x16_luma_pred_v
WELS_ASM_FUNC_END
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredH_neon
//stmdb sp!, {r4, lr}
sub r1, r1, #1
mov r3, #4
loop_0_get_i16x16_luma_pred_h:
//Get one byte data from left side
vld1.8 {d0[],d1[]}, [r1], r2
vld1.8 {d2[],d3[]}, [r1], r2
vld1.8 {d4[],d5[]}, [r1], r2
vld1.8 {d6[],d7[]}, [r1], r2
//Set the line of MB using the left side byte data
vst1.8 {d0,d1}, [r0]!
//add r0, #16
vst1.8 {d2,d3}, [r0]!
//add r0, #16
vst1.8 {d4,d5}, [r0]!
//add r0, #16
vst1.8 {d6,d7}, [r0]!
//add r0, #16
subs r3, #1
bne loop_0_get_i16x16_luma_pred_h
WELS_ASM_FUNC_END
WELS_ASM_FUNC_BEGIN WelsI16x16LumaPredDc_neon
//stmdb sp!, { r2-r5, lr}
//Get the left vertical line data

View File

@@ -349,23 +349,6 @@ WELS_ASM_AARCH64_FUNC_BEGIN WelsIChromaPredPlane_AArch64_neon
.endr
WELS_ASM_AARCH64_FUNC_END
//for Luma 16x16
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredV_AArch64_neon
sub x3, x1, x2
ld1 {v0.16b}, [x3]
.rept 16
st1 {v0.16b}, [x0], 16
.endr
WELS_ASM_AARCH64_FUNC_END
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredH_AArch64_neon
sub x3, x1, #1
.rept 16
ld1r {v0.16b}, [x3], x2
st1 {v0.16b}, [x0], 16
.endr
WELS_ASM_AARCH64_FUNC_END
WELS_ASM_AARCH64_FUNC_BEGIN WelsI16x16LumaPredDc_AArch64_neon
sub x3, x1, x2
sub x4, x1, #1

View File

@@ -216,6 +216,12 @@ typedef struct TagWelsEncCtx {
SStatSliceInfo sPerInfo;
#endif//STAT_OUTPUT
//related to Statistics
int64_t uiStartTimestamp;
SEncoderStatistics sEncoderStatistics;
int32_t iStatisticsLogInterval;
int64_t iLastStatisticsLogTs;
int32_t iEncoderError;
WELS_MUTEX mutexEncoderError;
bool bDeliveryFlag;

View File

@@ -108,7 +108,7 @@ int32_t ForceCodingIDR (sWelsEncCtx* pCtx);
int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNew);
void WelsEncoderApplyFrameRate (SWelsSvcCodingParam* pParam);
void WelsEncoderApplyBitRate (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam, int32_t iLayer);
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue);
int32_t WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue);
int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRecoverRequest);
void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarkingFeedback);

View File

@@ -74,8 +74,6 @@ void WelsIChromaPredDcNA_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStrid
void WelsI16x16ChromaPredVer (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16ChromaPredHor (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredPlane_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredDc_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredDcLeft_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
@@ -94,8 +92,6 @@ void WelsFillingPred8x2to16_sse2 (uint8_t* pPred, uint8_t* pValue);
void WelsFillingPred1to16_sse2 (uint8_t* pPred, const uint8_t kuiValue);
//for intra-prediction ASM functions
void WelsI16x16LumaPredV_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredDc_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredPlane_sse2 (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
@@ -116,8 +112,6 @@ void WelsI4x4LumaPredHU_mmx (uint8_t* pPred, uint8_t* pRef, const int32_t kiStri
#endif//X86_ASM
#if defined(HAVE_NEON)
void WelsI16x16LumaPredV_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredDc_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredPlane_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
@@ -137,8 +131,6 @@ void WelsIChromaPredPlane_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiS
#endif//HAVE_NEON
#if defined(HAVE_NEON_AARCH64)
void WelsI16x16LumaPredV_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredH_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredDc_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredPlane_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
void WelsI16x16LumaPredDcTop_AArch64_neon (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);

View File

@@ -64,32 +64,32 @@ extern const uint8_t g_kuiTemporalIdListTable[MAX_TEMPORAL_LEVEL][MAX_GOP_SIZE
* \return 2 based scaling factor
*/
static inline uint32_t GetLogFactor (float base, float upper) {
const double dLog2factor = log10 (1.0 * upper / base) / log10 (2.0);
const double dEpsilon = 0.0001;
const double dRound = floor (dLog2factor + 0.5);
const double dLog2factor = log10 (1.0 * upper / base) / log10 (2.0);
const double dEpsilon = 0.0001;
const double dRound = floor (dLog2factor + 0.5);
if (dLog2factor < dRound + dEpsilon && dRound < dLog2factor + dEpsilon) {
return (uint32_t) (dRound);
}
return UINT_MAX;
if (dLog2factor < dRound + dEpsilon && dRound < dLog2factor + dEpsilon) {
return (uint32_t) (dRound);
}
return UINT_MAX;
}
/*
* Dependency Layer Parameter
*/
typedef struct TagDLayerParam {
int32_t iActualWidth; // input source picture actual width
int32_t iActualHeight; // input source picture actual height
int32_t iTemporalResolution;
int32_t iDecompositionStages;
uint8_t uiCodingIdx2TemporalId[ (1 << MAX_TEMPORAL_LEVEL) + 1];
int32_t iActualWidth; // input source picture actual width
int32_t iActualHeight; // input source picture actual height
int32_t iTemporalResolution;
int32_t iDecompositionStages;
uint8_t uiCodingIdx2TemporalId[ (1 << MAX_TEMPORAL_LEVEL) + 1];
int8_t iHighestTemporalId;
float fInputFrameRate; // input frame rate
float fOutputFrameRate; // output frame rate
int8_t iHighestTemporalId;
float fInputFrameRate; // input frame rate
float fOutputFrameRate; // output frame rate
#ifdef ENABLE_FRAME_DUMP
char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
#endif//ENABLE_FRAME_DUMP
} SSpatialLayerInternal;
@@ -97,419 +97,432 @@ char sRecFileName[MAX_FNAME_LEN]; // file to be constructed
* Cisco OpenH264 Encoder Parameter Configuration
*/
typedef struct TagWelsSvcCodingParam: SEncParamExt {
SSpatialLayerInternal sDependencyLayers[MAX_DEPENDENCY_LAYER];
SSpatialLayerInternal sDependencyLayers[MAX_DEPENDENCY_LAYER];
/* General */
uint32_t uiGopSize; // GOP size (at maximal frame rate: 16)
struct {
int32_t iLeft;
int32_t iTop;
int32_t iWidth;
int32_t iHeight;
} SUsedPicRect; // the rect in input picture that encoder actually used
/* General */
uint32_t uiGopSize; // GOP size (at maximal frame rate: 16)
struct {
int32_t iLeft;
int32_t iTop;
int32_t iWidth;
int32_t iHeight;
} SUsedPicRect; // the rect in input picture that encoder actually used
char* pCurPath; // record current lib path such as:/pData/pData/com.wels.enc/lib/
char* pCurPath; // record current lib path such as:/pData/pData/com.wels.enc/lib/
bool bDeblockingParallelFlag; // deblocking filter parallelization control flag
bool bDeblockingParallelFlag; // deblocking filter parallelization control flag
short
iCountThreadsNum; // # derived from disable_multiple_slice_idc (=0 or >1) means;
short
iCountThreadsNum; // # derived from disable_multiple_slice_idc (=0 or >1) means;
int8_t iDecompStages; // GOP size dependency
int32_t iMaxNumRefFrame;
int8_t iDecompStages; // GOP size dependency
int32_t iMaxNumRefFrame;
//setting this according to link type in use MAY invoke some algorithms targeting higher coding efficiency
bool bIsLosslessLink;
public:
TagWelsSvcCodingParam() {
FillDefault();
}
~TagWelsSvcCodingParam() {}
TagWelsSvcCodingParam() {
FillDefault();
}
~TagWelsSvcCodingParam() {}
static void FillDefault (SEncParamExt& param) {
memset (&param, 0, sizeof (param));
param.uiIntraPeriod = 0; // intra period (multiple of GOP size as desired)
param.iNumRefFrame = AUTO_REF_PIC_COUNT;// number of reference frame used
static void FillDefault (SEncParamExt& param) {
memset (&param, 0, sizeof (param));
param.uiIntraPeriod = 0; // intra period (multiple of GOP size as desired)
param.iNumRefFrame = AUTO_REF_PIC_COUNT;// number of reference frame used
param.iPicWidth = 0; // actual input picture width
param.iPicHeight = 0; // actual input picture height
param.iPicWidth = 0; // actual input picture width
param.iPicHeight = 0; // actual input picture height
param.fMaxFrameRate = MAX_FRAME_RATE; // maximal frame rate [Hz / fps]
param.fMaxFrameRate = MAX_FRAME_RATE; // maximal frame rate [Hz / fps]
param.iComplexityMode = MEDIUM_COMPLEXITY;
param.iTargetBitrate = 0; // overall target bitrate introduced in RC module
param.iMaxBitrate = MAX_BIT_RATE;
param.iMultipleThreadIdc = 1;
param.iComplexityMode = MEDIUM_COMPLEXITY;
param.iTargetBitrate = 0; // overall target bitrate introduced in RC module
param.iMaxBitrate = MAX_BIT_RATE;
param.iMultipleThreadIdc = 1;
param.iLTRRefNum = 0;
param.iLtrMarkPeriod = 30; //the min distance of two int32_t references
param.iLTRRefNum = 0;
param.iLtrMarkPeriod = 30; //the min distance of two int32_t references
param.bEnableSSEI = true;
param.bEnableFrameCroppingFlag = true; // enable frame cropping flag: true alwayse in application
// false: Streaming Video Sharing; true: Video Conferencing Meeting;
param.bEnableSSEI = true;
param.bEnableFrameCroppingFlag = true; // enable frame cropping flag: true alwayse in application
// false: Streaming Video Sharing; true: Video Conferencing Meeting;
/* Deblocking loop filter */
param.iLoopFilterDisableIdc = 0; // 0: on, 1: off, 2: on except for slice boundaries
param.iLoopFilterAlphaC0Offset = 0; // AlphaOffset: valid range [-6, 6], default 0
param.iLoopFilterBetaOffset = 0; // BetaOffset: valid range [-6, 6], default 0
/* Deblocking loop filter */
param.iLoopFilterDisableIdc = 0; // 0: on, 1: off, 2: on except for slice boundaries
param.iLoopFilterAlphaC0Offset = 0; // AlphaOffset: valid range [-6, 6], default 0
param.iLoopFilterBetaOffset = 0; // BetaOffset: valid range [-6, 6], default 0
/* Rate Control */
param.iRCMode = RC_QUALITY_MODE;
param.iPaddingFlag = 0;
/* Rate Control */
param.iRCMode = RC_QUALITY_MODE;
param.iPaddingFlag = 0;
param.bEnableDenoise = false; // denoise control
param.bEnableSceneChangeDetect = true; // scene change detection control
param.bEnableBackgroundDetection = true; // background detection control
param.bEnableAdaptiveQuant = true; // adaptive quantization control
param.bEnableFrameSkip = true; // frame skipping
param.bEnableLongTermReference = false; // long term reference control
param.bEnableSpsPpsIdAddition = true; // pSps pPps id addition control
param.bPrefixNalAddingCtrl = false; // prefix NAL adding control
param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded
param.iTemporalLayerNum = 1; // number of temporal layer specified
param.bEnableDenoise = false; // denoise control
param.bEnableSceneChangeDetect = true; // scene change detection control
param.bEnableBackgroundDetection = true; // background detection control
param.bEnableAdaptiveQuant = true; // adaptive quantization control
param.bEnableFrameSkip = true; // frame skipping
param.bEnableLongTermReference = false; // long term reference control
param.bEnableSpsPpsIdAddition = true; // pSps pPps id addition control
param.bPrefixNalAddingCtrl = false; // prefix NAL adding control
param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded
param.iTemporalLayerNum = 1; // number of temporal layer specified
param.iMaxQp = 51;
param.iMinQp = 0;
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
param.uiMaxNalSize = 0;
param.iMaxQp = 51;
param.iMinQp = 0;
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
param.uiMaxNalSize = 0;
for (int32_t iLayer = 0; iLayer < MAX_SPATIAL_LAYER_NUM; iLayer++) {
param.sSpatialLayers[iLayer].uiProfileIdc = PRO_BASELINE;
param.sSpatialLayers[iLayer].uiLevelIdc = LEVEL_5_0;
param.sSpatialLayers[iLayer].iDLayerQp = SVC_QUALITY_BASE_QP;
param.sSpatialLayers[iLayer].fFrameRate = param.fMaxFrameRate;
param.sSpatialLayers[iLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
for (int32_t iLayer = 0; iLayer < MAX_SPATIAL_LAYER_NUM; iLayer++) {
param.sSpatialLayers[iLayer].uiProfileIdc = PRO_BASELINE;
param.sSpatialLayers[iLayer].uiLevelIdc = LEVEL_5_0;
param.sSpatialLayers[iLayer].iDLayerQp = SVC_QUALITY_BASE_QP;
param.sSpatialLayers[iLayer].fFrameRate = param.fMaxFrameRate;
param.sSpatialLayers[iLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
}
}
void FillDefault() {
FillDefault (*this);
uiGopSize = 1; // GOP size (at maximal frame rate: 16)
iMaxNumRefFrame = 1;
SUsedPicRect.iLeft =
SUsedPicRect.iTop =
SUsedPicRect.iWidth =
SUsedPicRect.iHeight = 0; // the rect in input picture that encoder actually used
pCurPath = NULL; // record current lib path such as:/pData/pData/com.wels.enc/lib/
bDeblockingParallelFlag = false; // deblocking filter parallelization control flag
iCountThreadsNum = 1; // # derived from disable_multiple_slice_idc (=0 or >1) means;
iDecompStages = 0; // GOP size dependency, unknown here and be revised later
iComplexityMode = MEDIUM_COMPLEXITY;
memset (sDependencyLayers, 0, sizeof (SSpatialLayerInternal)*MAX_DEPENDENCY_LAYER);
memset (sSpatialLayers, 0 , sizeof (SSpatialLayerConfig)*MAX_SPATIAL_LAYER_NUM);
//init multi-slice
sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = 1;
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
param.sSpatialLayers[iLayer].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
}
}
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
sSpatialLayers[0].iDLayerQp = SVC_QUALITY_BASE_QP;
void FillDefault() {
FillDefault (*this);
uiGopSize = 1; // GOP size (at maximal frame rate: 16)
iMaxNumRefFrame = 1;
SUsedPicRect.iLeft =
SUsedPicRect.iTop =
SUsedPicRect.iWidth =
SUsedPicRect.iHeight = 0; // the rect in input picture that encoder actually used
pCurPath = NULL; // record current lib path such as:/pData/pData/com.wels.enc/lib/
bDeblockingParallelFlag = false; // deblocking filter parallelization control flag
iCountThreadsNum = 1; // # derived from disable_multiple_slice_idc (=0 or >1) means;
iDecompStages = 0; // GOP size dependency, unknown here and be revised later
iComplexityMode = MEDIUM_COMPLEXITY;
memset (sDependencyLayers, 0, sizeof (SSpatialLayerInternal)*MAX_DEPENDENCY_LAYER);
memset (sSpatialLayers, 0 , sizeof (SSpatialLayerConfig)*MAX_SPATIAL_LAYER_NUM);
//init multi-slice
sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1500;
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = 1;
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
for (int32_t idx = 0; idx < kiLesserSliceNum; idx++)
sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceMbNum[idx] = 960;
sSpatialLayers[0].iDLayerQp = SVC_QUALITY_BASE_QP;
}
int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam) {
fMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
iTargetBitrate = pCodingParam.iTargetBitrate;
iUsageType = pCodingParam.iUsageType;
iPicWidth = pCodingParam.iPicWidth;
iPicHeight = pCodingParam.iPicHeight;
SUsedPicRect.iLeft = 0;
SUsedPicRect.iTop = 0;
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
iRCMode = pCodingParam.iRCMode; // rc mode
int8_t iIdxSpatial = 0;
EProfileIdc uiProfileIdc = PRO_BASELINE;
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
while (iIdxSpatial < iSpatialLayerNum) {
sSpatialLayers->uiProfileIdc = uiProfileIdc;
sSpatialLayers[iIdxSpatial].fFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate,
MIN_FRAME_RATE, MAX_FRAME_RATE);
pDlp->fInputFrameRate =
pDlp->fOutputFrameRate = WELS_CLIP3 (sSpatialLayers[iIdxSpatial].fFrameRate, MIN_FRAME_RATE,
MAX_FRAME_RATE);
#ifdef ENABLE_FRAME_DUMP
pDlp->sRecFileName[0] = '\0'; // file to be constructed
#endif//ENABLE_FRAME_DUMP
pDlp->iActualWidth = sSpatialLayers[iIdxSpatial].iVideoWidth = iPicWidth;
pDlp->iActualHeight = sSpatialLayers[iIdxSpatial].iVideoHeight = iPicHeight;
sSpatialLayers->iSpatialBitrate =
sSpatialLayers[iIdxSpatial].iSpatialBitrate = pCodingParam.iTargetBitrate; // target bitrate for current spatial layer
sSpatialLayers->iDLayerQp = SVC_QUALITY_BASE_QP;
uiProfileIdc = PRO_SCALABLE_BASELINE;
++ pDlp;
++ iIdxSpatial;
}
SetActualPicResolution();
return 0;
}
void GetBaseParams (SEncParamBase* pCodingParam) {
pCodingParam->iUsageType = iUsageType;
pCodingParam->iPicWidth = iPicWidth;
pCodingParam->iPicHeight = iPicHeight;
pCodingParam->iTargetBitrate = iTargetBitrate;
pCodingParam->iRCMode = iRCMode;
pCodingParam->fMaxFrameRate = fMaxFrameRate;
}
int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
float fParamMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
iUsageType = pCodingParam.iUsageType;
iPicWidth = pCodingParam.iPicWidth;
iPicHeight = pCodingParam.iPicHeight;
iComplexityMode = pCodingParam.iComplexityMode;
SUsedPicRect.iLeft = 0;
SUsedPicRect.iTop = 0;
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
iMultipleThreadIdc = pCodingParam.iMultipleThreadIdc;
/* Deblocking loop filter */
iLoopFilterDisableIdc = pCodingParam.iLoopFilterDisableIdc; // 0: on, 1: off, 2: on except for slice boundaries,
iLoopFilterAlphaC0Offset = pCodingParam.iLoopFilterAlphaC0Offset; // AlphaOffset: valid range [-6, 6], default 0
iLoopFilterBetaOffset = pCodingParam.iLoopFilterBetaOffset; // BetaOffset: valid range [-6, 6], default 0
bEnableFrameCroppingFlag = pCodingParam.bEnableFrameCroppingFlag;
/* Rate Control */
iRCMode = pCodingParam.iRCMode; // rc mode
iPaddingFlag = pCodingParam.iPaddingFlag;
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
iMaxBitrate = pCodingParam.iMaxBitrate;
if (iMaxBitrate < iTargetBitrate) {
iMaxBitrate = iTargetBitrate;
bIsLosslessLink = false;
}
uiMaxNalSize = pCodingParam.uiMaxNalSize;
/* Denoise Control */
bEnableDenoise = pCodingParam.bEnableDenoise ? true : false; // Denoise Control // only support 0 or 1 now
int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam) {
/* Scene change detection control */
bEnableSceneChangeDetect = pCodingParam.bEnableSceneChangeDetect;
fMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
iTargetBitrate = pCodingParam.iTargetBitrate;
iUsageType = pCodingParam.iUsageType;
iPicWidth = pCodingParam.iPicWidth;
iPicHeight = pCodingParam.iPicHeight;
/* Background detection Control */
bEnableBackgroundDetection = pCodingParam.bEnableBackgroundDetection ? true : false;
SUsedPicRect.iLeft = 0;
SUsedPicRect.iTop = 0;
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
/* Adaptive quantization control */
bEnableAdaptiveQuant = pCodingParam.bEnableAdaptiveQuant ? true : false;
iRCMode = pCodingParam.iRCMode; // rc mode
/* Frame skipping */
bEnableFrameSkip = pCodingParam.bEnableFrameSkip ? true : false;
int8_t iIdxSpatial = 0;
EProfileIdc uiProfileIdc = PRO_BASELINE;
/* Enable int32_t term reference */
bEnableLongTermReference = pCodingParam.bEnableLongTermReference ? true : false;
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
/* For ssei information */
bEnableSSEI = pCodingParam.bEnableSSEI;
while (iIdxSpatial < iSpatialLayerNum) {
/* Layer definition */
iSpatialLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iSpatialLayerNum, 1,
MAX_DEPENDENCY_LAYER); // number of dependency(Spatial/CGS) layers used to be encoded
iTemporalLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iTemporalLayerNum, 1,
MAX_TEMPORAL_LEVEL); // number of temporal layer specified
uiGopSize = 1 << (iTemporalLayerNum - 1); // Override GOP size based temporal layer
iDecompStages = iTemporalLayerNum - 1; // WELS_LOG2( uiGopSize );// GOP size dependency
uiIntraPeriod = pCodingParam.uiIntraPeriod;// intra period (multiple of GOP size as desired)
if (uiIntraPeriod == (uint32_t) (-1))
uiIntraPeriod = 0;
else if (uiIntraPeriod & (uiGopSize - 1)) // none multiple of GOP size
uiIntraPeriod = ((uiIntraPeriod + uiGopSize - 1) / uiGopSize) * uiGopSize;
if (iUsageType == SCREEN_CONTENT_REAL_TIME) {
if (bEnableLongTermReference) {
iLTRRefNum = LONG_TERM_REF_NUM_SCREEN;
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
iNumRefFrame = WELS_MAX (1, WELS_LOG2 (uiGopSize)) + iLTRRefNum;
} else {
iLTRRefNum = 0;
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
iNumRefFrame = WELS_MAX (1, uiGopSize >> 1);
}
} else {
iLTRRefNum = bEnableLongTermReference ? LONG_TERM_REF_NUM : 0;
if (iNumRefFrame == AUTO_REF_PIC_COUNT) {
iNumRefFrame = ((uiGopSize >> 1) > 1) ? ((uiGopSize >> 1) + iLTRRefNum) : (MIN_REF_PIC_COUNT + iLTRRefNum);
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
}
}
if (iNumRefFrame > iMaxNumRefFrame)
iMaxNumRefFrame = iNumRefFrame;
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
bEnableSpsPpsIdAddition =
pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
//SHOULD enable this feature.
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
float fMaxFr = .0f;
EProfileIdc uiProfileIdc = PRO_BASELINE;
int8_t iIdxSpatial = 0;
while (iIdxSpatial < iSpatialLayerNum) {
pSpatialLayer->uiProfileIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc == PRO_UNKNOWN) ? uiProfileIdc :
pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc;
pSpatialLayer->uiLevelIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc == LEVEL_UNKNOWN) ? LEVEL_5_0 :
pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc;
float fLayerFrameRate = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
MIN_FRAME_RATE, fParamMaxFrameRate);
pSpatialLayer->fFrameRate =
sSpatialLayers->uiProfileIdc = uiProfileIdc;
sSpatialLayers[iIdxSpatial].fFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate,
MIN_FRAME_RATE, MAX_FRAME_RATE);
pDlp->fInputFrameRate =
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
if (pDlp->fInputFrameRate > fMaxFr + EPSN)
fMaxFr = pDlp->fInputFrameRate;
pDlp->fOutputFrameRate = WELS_CLIP3 (sSpatialLayers[iIdxSpatial].fFrameRate, MIN_FRAME_RATE,
MAX_FRAME_RATE);
#ifdef ENABLE_FRAME_DUMP
pDlp->sRecFileName[0] = '\0'; // file to be constructed
#endif//ENABLE_FRAME_DUMP
pDlp->iActualWidth = sSpatialLayers[iIdxSpatial].iVideoWidth = iPicWidth;
pDlp->iActualHeight = sSpatialLayers[iIdxSpatial].iVideoHeight = iPicHeight;
sSpatialLayers->iSpatialBitrate =
sSpatialLayers[iIdxSpatial].iSpatialBitrate = pCodingParam.iTargetBitrate; // target bitrate for current spatial layer
sSpatialLayers->iDLayerQp = SVC_QUALITY_BASE_QP;
uiProfileIdc = PRO_SCALABLE_BASELINE;
++ pDlp;
++ iIdxSpatial;
}
SetActualPicResolution();
return 0;
}
void GetBaseParams (SEncParamBase* pCodingParam) {
pCodingParam->iUsageType = iUsageType;
pCodingParam->iPicWidth = iPicWidth;
pCodingParam->iPicHeight = iPicHeight;
pCodingParam->iTargetBitrate = iTargetBitrate;
pCodingParam->iRCMode = iRCMode;
pCodingParam->fMaxFrameRate = fMaxFrameRate;
}
int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
float fParamMaxFrameRate = WELS_CLIP3 (pCodingParam.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
iUsageType = pCodingParam.iUsageType;
iPicWidth = pCodingParam.iPicWidth;
iPicHeight = pCodingParam.iPicHeight;
fMaxFrameRate = fParamMaxFrameRate;
iComplexityMode = pCodingParam.iComplexityMode;
SUsedPicRect.iLeft = 0;
SUsedPicRect.iTop = 0;
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
iMultipleThreadIdc = pCodingParam.iMultipleThreadIdc;
/* Deblocking loop filter */
iLoopFilterDisableIdc = pCodingParam.iLoopFilterDisableIdc; // 0: on, 1: off, 2: on except for slice boundaries,
iLoopFilterAlphaC0Offset = pCodingParam.iLoopFilterAlphaC0Offset; // AlphaOffset: valid range [-6, 6], default 0
iLoopFilterBetaOffset = pCodingParam.iLoopFilterBetaOffset; // BetaOffset: valid range [-6, 6], default 0
bEnableFrameCroppingFlag = pCodingParam.bEnableFrameCroppingFlag;
/* Rate Control */
iRCMode = pCodingParam.iRCMode; // rc mode
iPaddingFlag = pCodingParam.iPaddingFlag;
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
iMaxBitrate = pCodingParam.iMaxBitrate;
if (iMaxBitrate < iTargetBitrate) {
iMaxBitrate = iTargetBitrate;
}
uiMaxNalSize = pCodingParam.uiMaxNalSize;
/* Denoise Control */
bEnableDenoise = pCodingParam.bEnableDenoise ? true : false; // Denoise Control // only support 0 or 1 now
/* Scene change detection control */
bEnableSceneChangeDetect = pCodingParam.bEnableSceneChangeDetect;
/* Background detection Control */
bEnableBackgroundDetection = pCodingParam.bEnableBackgroundDetection ? true : false;
/* Adaptive quantization control */
bEnableAdaptiveQuant = pCodingParam.bEnableAdaptiveQuant ? true : false;
/* Frame skipping */
bEnableFrameSkip = pCodingParam.bEnableFrameSkip ? true : false;
/* Enable int32_t term reference */
bEnableLongTermReference = pCodingParam.bEnableLongTermReference ? true : false;
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
bIsLosslessLink = pCodingParam.bIsLosslessLink;
if (iUsageType == SCREEN_CONTENT_REAL_TIME && !bIsLosslessLink && bEnableLongTermReference) {
bEnableLongTermReference = false;
}
/* For ssei information */
bEnableSSEI = pCodingParam.bEnableSSEI;
/* Layer definition */
iSpatialLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iSpatialLayerNum, 1,
MAX_DEPENDENCY_LAYER); // number of dependency(Spatial/CGS) layers used to be encoded
iTemporalLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iTemporalLayerNum, 1,
MAX_TEMPORAL_LEVEL); // number of temporal layer specified
uiGopSize = 1 << (iTemporalLayerNum - 1); // Override GOP size based temporal layer
iDecompStages = iTemporalLayerNum - 1; // WELS_LOG2( uiGopSize );// GOP size dependency
uiIntraPeriod = pCodingParam.uiIntraPeriod;// intra period (multiple of GOP size as desired)
if (uiIntraPeriod == (uint32_t) (-1))
uiIntraPeriod = 0;
else if (uiIntraPeriod & (uiGopSize - 1)) // none multiple of GOP size
uiIntraPeriod = ((uiIntraPeriod + uiGopSize - 1) / uiGopSize) * uiGopSize;
if (iUsageType == SCREEN_CONTENT_REAL_TIME) {
if (bEnableLongTermReference) {
iLTRRefNum = LONG_TERM_REF_NUM_SCREEN;
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
iNumRefFrame = WELS_MAX (1, WELS_LOG2 (uiGopSize)) + iLTRRefNum;
} else {
iLTRRefNum = 0;
if (iNumRefFrame == AUTO_REF_PIC_COUNT)
iNumRefFrame = WELS_MAX (1, uiGopSize >> 1);
}
} else {
iLTRRefNum = bEnableLongTermReference ? LONG_TERM_REF_NUM : 0;
if (iNumRefFrame == AUTO_REF_PIC_COUNT) {
iNumRefFrame = ((uiGopSize >> 1) > 1) ? ((uiGopSize >> 1) + iLTRRefNum) : (MIN_REF_PIC_COUNT + iLTRRefNum);
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA);
}
}
if (iNumRefFrame > iMaxNumRefFrame)
iMaxNumRefFrame = iNumRefFrame;
iLtrMarkPeriod = pCodingParam.iLtrMarkPeriod;
bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
bEnableSpsPpsIdAddition =
pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
//SHOULD enable this feature.
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
EProfileIdc uiProfileIdc = PRO_BASELINE;
int8_t iIdxSpatial = 0;
while (iIdxSpatial < iSpatialLayerNum) {
pSpatialLayer->uiProfileIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc == PRO_UNKNOWN) ? uiProfileIdc :
pCodingParam.sSpatialLayers[iIdxSpatial].uiProfileIdc;
pSpatialLayer->uiLevelIdc = (pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc == LEVEL_UNKNOWN) ? LEVEL_5_0 :
pCodingParam.sSpatialLayers[iIdxSpatial].uiLevelIdc;
float fLayerFrameRate = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
MIN_FRAME_RATE, fParamMaxFrameRate);
pDlp->fInputFrameRate = fParamMaxFrameRate;
pSpatialLayer->fFrameRate =
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, fParamMaxFrameRate);
#ifdef ENABLE_FRAME_DUMP
pDlp->sRecFileName[0] = '\0'; // file to be constructed
pDlp->sRecFileName[0] = '\0'; // file to be constructed
#endif//ENABLE_FRAME_DUMP
pSpatialLayer->iVideoWidth = pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth; // frame width
pSpatialLayer->iVideoHeight = pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight;// frame height
pSpatialLayer->iSpatialBitrate =
pCodingParam.sSpatialLayers[iIdxSpatial].iSpatialBitrate; // target bitrate for current spatial layer
pSpatialLayer->iMaxSpatialBitrate =
pCodingParam.sSpatialLayers[iIdxSpatial].iMaxSpatialBitrate;
pSpatialLayer->iVideoWidth = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoWidth, 0,
iPicWidth); // frame width
pSpatialLayer->iVideoHeight = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].iVideoHeight, 0,
iPicHeight);// frame height
//multi slice
pSpatialLayer->sSliceCfg.uiSliceMode = pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.uiSliceMode;
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
= (uint32_t) (pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceSizeConstraint);
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum
= pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceNum;
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
memcpy (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum,
pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceMbNum, // confirmed_safe_unsafe_usage
kiLesserSliceNum * sizeof (uint32_t)) ;
pSpatialLayer->iSpatialBitrate =
pCodingParam.sSpatialLayers[iIdxSpatial].iSpatialBitrate; // target bitrate for current spatial layer
pSpatialLayer->iMaxSpatialBitrate =
pCodingParam.sSpatialLayers[iIdxSpatial].iMaxSpatialBitrate;
pSpatialLayer->iDLayerQp = pCodingParam.sSpatialLayers[iIdxSpatial].iDLayerQp;
//multi slice
pSpatialLayer->sSliceCfg.uiSliceMode = pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.uiSliceMode;
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
= (uint32_t) (pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceSizeConstraint);
pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum
= pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceNum;
const int32_t kiLesserSliceNum = ((MAX_SLICES_NUM < MAX_SLICES_NUM_TMP) ? MAX_SLICES_NUM : MAX_SLICES_NUM_TMP);
memcpy (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceMbNum,
pCodingParam.sSpatialLayers[iIdxSpatial].sSliceCfg.sSliceArgument.uiSliceMbNum, // confirmed_safe_unsafe_usage
kiLesserSliceNum * sizeof (uint32_t)) ;
uiProfileIdc = PRO_SCALABLE_BASELINE;
++ pDlp;
++ pSpatialLayer;
++ iIdxSpatial;
pSpatialLayer->iDLayerQp = pCodingParam.sSpatialLayers[iIdxSpatial].iDLayerQp;
uiProfileIdc = PRO_SCALABLE_BASELINE;
++ pDlp;
++ pSpatialLayer;
++ iIdxSpatial;
}
SetActualPicResolution();
return 0;
}
fMaxFrameRate = fMaxFr;
SetActualPicResolution();
return 0;
}
// assuming that the width/height ratio of all spatial layers are the same
void SetActualPicResolution() {
int32_t iSpatialIdx = iSpatialLayerNum - 1;
for (; iSpatialIdx >= 0; iSpatialIdx --) {
SSpatialLayerInternal* pDlayerInternal = &sDependencyLayers[iSpatialIdx];
SSpatialLayerConfig* pDlayer = &sSpatialLayers[iSpatialIdx];
void SetActualPicResolution() {
int32_t iSpatialIdx = iSpatialLayerNum - 1;
for (; iSpatialIdx >= 0; iSpatialIdx --) {
SSpatialLayerInternal* pDlayerInternal = &sDependencyLayers[iSpatialIdx];
SSpatialLayerConfig* pDlayer = &sSpatialLayers[iSpatialIdx];
pDlayerInternal->iActualWidth = pDlayer->iVideoWidth;
pDlayerInternal->iActualHeight = pDlayer->iVideoHeight;
pDlayer->iVideoWidth = WELS_ALIGN (pDlayerInternal->iActualWidth, MB_WIDTH_LUMA);
pDlayer->iVideoHeight = WELS_ALIGN (pDlayerInternal->iActualHeight, MB_HEIGHT_LUMA);
pDlayerInternal->iActualWidth = pDlayer->iVideoWidth;
pDlayerInternal->iActualHeight = pDlayer->iVideoHeight;
pDlayer->iVideoWidth = WELS_ALIGN (pDlayerInternal->iActualWidth, MB_WIDTH_LUMA);
pDlayer->iVideoHeight = WELS_ALIGN (pDlayerInternal->iActualHeight, MB_HEIGHT_LUMA);
}
}
}
/*!
* \brief determined key coding tables for temporal scalability, uiProfileIdc etc for each spatial layer settings
* \param SWelsSvcCodingParam, and carried with known GOP size, max, input and output frame rate of each spatial
* \return NONE (should ensure valid parameter before this procedure)
*/
void DetermineTemporalSettings() {
const int32_t iDecStages = WELS_LOG2 (
uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize); //log2(uiGopSize)
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
EProfileIdc uiProfileIdc = PRO_BASELINE;
int8_t i = 0;
/*!
* \brief determined key coding tables for temporal scalability, uiProfileIdc etc for each spatial layer settings
* \param SWelsSvcCodingParam, and carried with known GOP size, max, input and output frame rate of each spatial
* \return NONE (should ensure valid parameter before this procedure)
*/
int32_t DetermineTemporalSettings() {
const int32_t iDecStages = WELS_LOG2 (
uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize); //log2(uiGopSize)
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
EProfileIdc uiProfileIdc = PRO_BASELINE;
int8_t i = 0;
while (i < iSpatialLayerNum) {
const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
int32_t iNotCodedMask = 0;
int8_t iMaxTemporalId = 0;
while (i < iSpatialLayerNum) {
const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
if (UINT_MAX == kuiLogFactorInOutRate || UINT_MAX == kuiLogFactorMaxInRate) {
return ENC_RETURN_INVALIDINPUT;
}
int32_t iNotCodedMask = 0;
int8_t iMaxTemporalId = 0;
memset (pDlp->uiCodingIdx2TemporalId, INVALID_TEMPORAL_ID, sizeof (pDlp->uiCodingIdx2TemporalId));
pSpatialLayer->uiProfileIdc = uiProfileIdc; // PRO_BASELINE, PRO_SCALABLE_BASELINE;
memset (pDlp->uiCodingIdx2TemporalId, INVALID_TEMPORAL_ID, sizeof (pDlp->uiCodingIdx2TemporalId));
pSpatialLayer->uiProfileIdc = uiProfileIdc; // PRO_BASELINE, PRO_SCALABLE_BASELINE;
iNotCodedMask = (1 << (kuiLogFactorInOutRate + kuiLogFactorMaxInRate)) - 1;
for (uint32_t uiFrameIdx = 0; uiFrameIdx <= uiGopSize; ++ uiFrameIdx) {
if (0 == (uiFrameIdx & iNotCodedMask)) {
const int8_t kiTemporalId = pTemporalIdList[uiFrameIdx];
pDlp->uiCodingIdx2TemporalId[uiFrameIdx] = kiTemporalId;
if (kiTemporalId > iMaxTemporalId) {
iMaxTemporalId = kiTemporalId;
iNotCodedMask = (1 << (kuiLogFactorInOutRate + kuiLogFactorMaxInRate)) - 1;
for (uint32_t uiFrameIdx = 0; uiFrameIdx <= uiGopSize; ++ uiFrameIdx) {
if (0 == (uiFrameIdx & iNotCodedMask)) {
const int8_t kiTemporalId = pTemporalIdList[uiFrameIdx];
pDlp->uiCodingIdx2TemporalId[uiFrameIdx] = kiTemporalId;
if (kiTemporalId > iMaxTemporalId) {
iMaxTemporalId = kiTemporalId;
}
}
}
pDlp->iHighestTemporalId = iMaxTemporalId;
pDlp->iTemporalResolution = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
if (pDlp->iDecompositionStages < 0) {
return ENC_RETURN_INVALIDINPUT;
}
uiProfileIdc = PRO_SCALABLE_BASELINE;
++ pDlp;
++ pSpatialLayer;
++ i;
}
pDlp->iHighestTemporalId = iMaxTemporalId;
pDlp->iTemporalResolution = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
uiProfileIdc = PRO_SCALABLE_BASELINE;
++ pDlp;
++ pSpatialLayer;
++ i;
iDecompStages = (int8_t)iDecStages;
return ENC_RETURN_SUCCESS;
}
iDecompStages = (int8_t)iDecStages;
}
} SWelsSvcCodingParam;
static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
if (pParam == NULL || *pParam == NULL || pMa == NULL)
return 1;
pMa->WelsFree (*pParam, "SWelsSvcCodingParam");
*pParam = NULL;
return 0;
if (pParam == NULL || *pParam == NULL || pMa == NULL)
return 1;
pMa->WelsFree (*pParam, "SWelsSvcCodingParam");
*pParam = NULL;
return 0;
}
static inline int32_t AllocCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
if (pParam == NULL || pMa == NULL)
return 1;
if (*pParam != NULL) {
FreeCodingParam (pParam, pMa);
}
SWelsSvcCodingParam* pCodingParam = (SWelsSvcCodingParam*)pMa->WelsMalloc (sizeof (SWelsSvcCodingParam),
"SWelsSvcCodingParam");
if (NULL == pCodingParam)
return 1;
*pParam = pCodingParam;
return 0;
if (pParam == NULL || pMa == NULL)
return 1;
if (*pParam != NULL) {
FreeCodingParam (pParam, pMa);
}
SWelsSvcCodingParam* pCodingParam = (SWelsSvcCodingParam*)pMa->WelsMalloc (sizeof (SWelsSvcCodingParam),
"SWelsSvcCodingParam");
if (NULL == pCodingParam)
return 1;
*pParam = pCodingParam;
return 0;
}
}//end of namespace WelsEnc

View File

@@ -99,6 +99,25 @@ int32_t iFrameAverageQp;
/*******************************for screen reference frames****************************/
SScreenBlockFeatureStorage* pScreenBlockFeatureStorage;
/*
* set picture as unreferenced
*/
void SetUnref () {
iFramePoc = -1;
iFrameNum = -1;
uiTemporalId =
uiSpatialId =
iLongTermPicNum = -1;
bIsLongRef = false;
uiRecieveConfirmed = RECIEVE_FAILED;
iMarkFrameNum = -1;
bUsedAsRef = false;
if (NULL != pScreenBlockFeatureStorage)
pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = false;
}
} SPicture;
/*

View File

@@ -62,12 +62,5 @@ SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth, const int32_t
*/
void FreePicture (CMemoryAlign* pMa, SPicture** ppPic);
/*!
* \brief exchange two picture pData planes
* \param ppPic1 picture pointer to picture 1
* \param ppPic2 picture pointer to picture 2
* \return none
*/
void WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2);
}
#endif//WELS_ENCODER_PICTURE_HANDLE_H__

View File

@@ -54,55 +54,55 @@ namespace WelsEnc {
#define GOM_H_SCC 8
enum {
BITS_NORMAL,
BITS_LIMITED,
BITS_EXCEEDED,
BITS_NORMAL,
BITS_LIMITED,
BITS_EXCEEDED
};
enum {
//virtual gop size
VGOP_SIZE = 8,
VGOP_SIZE = 8,
//qp information
GOM_MIN_QP_MODE = 12,
GOM_MAX_QP_MODE = 36,
MAX_LOW_BR_QP = 42,
MIN_IDR_QP = 26,
MAX_IDR_QP = 32,
MIN_SCREEN_QP = 26,
MAX_SCREEN_QP = 32,
DELTA_QP = 2,
DELTA_QP_BGD_THD = 3,
GOM_MIN_QP_MODE = 12,
GOM_MAX_QP_MODE = 36,
MAX_LOW_BR_QP = 42,
MIN_IDR_QP = 26,
MAX_IDR_QP = 32,
MIN_SCREEN_QP = 26,
MAX_SCREEN_QP = 35,
DELTA_QP = 2,
DELTA_QP_BGD_THD = 3,
//frame skip constants
SKIP_QP_90P = 24,
SKIP_QP_180P = 24,
SKIP_QP_360P = 31,
SKIP_QP_720P = 31,
LAST_FRAME_QP_RANGE_UPPER_MODE0 = 3,
LAST_FRAME_QP_RANGE_LOWER_MODE0 = 2,
LAST_FRAME_QP_RANGE_UPPER_MODE1 = 5,
LAST_FRAME_QP_RANGE_LOWER_MODE1 = 3,
SKIP_QP_90P = 24,
SKIP_QP_180P = 24,
SKIP_QP_360P = 31,
SKIP_QP_720P = 31,
LAST_FRAME_QP_RANGE_UPPER_MODE0 = 3,
LAST_FRAME_QP_RANGE_LOWER_MODE0 = 2,
LAST_FRAME_QP_RANGE_UPPER_MODE1 = 5,
LAST_FRAME_QP_RANGE_LOWER_MODE1 = 3,
MB_WIDTH_THRESHOLD_90P = 15,
MB_WIDTH_THRESHOLD_180P = 30,
MB_WIDTH_THRESHOLD_360P = 60,
MB_WIDTH_THRESHOLD_90P = 15,
MB_WIDTH_THRESHOLD_180P = 30,
MB_WIDTH_THRESHOLD_360P = 60,
//Mode 0 parameter
GOM_ROW_MODE0_90P = 2,
GOM_ROW_MODE0_180P = 2,
GOM_ROW_MODE0_360P = 4,
GOM_ROW_MODE0_720P = 4,
QP_RANGE_MODE0 = 3,
GOM_ROW_MODE0_90P = 2,
GOM_ROW_MODE0_180P = 2,
GOM_ROW_MODE0_360P = 4,
GOM_ROW_MODE0_720P = 4,
QP_RANGE_MODE0 = 3,
//Mode 1 parameter
GOM_ROW_MODE1_90P = 1,
GOM_ROW_MODE1_180P = 1,
GOM_ROW_MODE1_360P = 2,
GOM_ROW_MODE1_720P = 2,
QP_RANGE_UPPER_MODE1 = 9,
QP_RANGE_LOWER_MODE1 = 4,
QP_RANGE_INTRA_MODE1 = 3,
GOM_ROW_MODE1_90P = 1,
GOM_ROW_MODE1_180P = 1,
GOM_ROW_MODE1_360P = 2,
GOM_ROW_MODE1_720P = 2,
QP_RANGE_UPPER_MODE1 = 9,
QP_RANGE_LOWER_MODE1 = 4,
QP_RANGE_INTRA_MODE1 = 3
};
//bits allocation
@@ -122,7 +122,7 @@ QP_RANGE_INTRA_MODE1 = 3,
#define SKIP_RATIO 50 // *INT_MULTIPLY
#define PADDING_BUFFER_RATIO 50 // *INT_MULTIPLY
#define PADDING_THRESHOLD 5 //*INT_MULTIPLY
typedef struct TagRCSlicing {
int32_t iComplexityIndexSlice;
int32_t iCalculatedQpSlice;
@@ -137,7 +137,7 @@ int32_t iGomBitsSlice;
int32_t iGomTargetBits;
//int32_t gom_coded_mb;
} SRCSlicing;
typedef struct TagRCTemporal {
int32_t iMinBitsTl;
int32_t iMaxBitsTl;
@@ -147,13 +147,13 @@ int32_t iGopBitsDq;
int64_t iLinearCmplx; // *INT_MULTIPLY
int32_t iPFrameNum;
int32_t iFrameCmplxMean;
} SRCTemporal;
typedef struct TagWelsRc {
int32_t iRcVaryPercentage;
int32_t iRcVaryRatio;
int32_t iInitialQp; //initial qp
int32_t iBitRate;
int32_t iPreviousBitrate;
@@ -161,31 +161,33 @@ int32_t iPreviousGopSize;
double fFrameRate;
int32_t iBitsPerFrame; // *INT_MULTIPLY
double dPreviousFps;
// bits allocation and status
int32_t iRemainingBits;
int32_t iTargetBits;
int32_t iCurrentBitsLevel;//0:normal; 1:limited; 2:exceeded.
int32_t iIdrNum;
int32_t iIntraComplexity;
int32_t iIntraMbCount;
int8_t iTlOfFrames[VGOP_SIZE];
int32_t iRemainingWeights;
int32_t iFrameDqBits;
double* pGomComplexity;
int32_t* pGomForegroundBlockNum;
int32_t* pCurrentFrameGomSad;
int32_t* pGomCost;
int32_t iAverageFrameQp;
int32_t iMinFrameQp;
int32_t iMaxFrameQp;
int32_t iNumberMbFrame;
int32_t iNumberMbGom;
int32_t iSliceNum;
int32_t iGomSize;
int32_t iSkipFrameNum;
int32_t iFrameCodedInVGop;
int32_t iSkipFrameInVGop;
@@ -213,17 +215,27 @@ int32_t iBufferFullnessPadding;
int32_t iPaddingSize;
int32_t iPaddingBitrateStat;
bool bSkipFlag;
SRCSlicing* pSlicingOverRc;
SRCTemporal* pTemporalOverRc;
//for scc
int64_t iAvgCost2Bits;
int64_t iCost2BitsIntra;
int32_t iBaseQp;
long long uiLastTimeStamp;
//for statistics and online adjustments
int32_t iActualBitRate; // TODO: to complete later
float fLatestFrameRate; // TODO: to complete later
} SWelsSvcRc;
typedef void (*PWelsRCPictureInitFunc) (void* pCtx);
typedef void (*PWelsRCPictureDelayJudgeFunc) (void* pCtx);
typedef void (*PWelsRCPictureDelayJudgeFunc) (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp);
typedef void (*PWelsRCPictureInfoUpdateFunc) (void* pCtx, int32_t iLayerSize);
typedef void (*PWelsRCMBInfoUpdateFunc) (void* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice* pSlice);
typedef void (*PWelsRCMBInitFunc) (void* pCtx, SMB* pCurMb, SSlice* pSlice);
typedef struct WelsRcFunc_s {
PWelsRCPictureInitFunc pfWelsRcPictureInit;
PWelsRCPictureDelayJudgeFunc pfWelsRcPicDelayJudge;
@@ -231,10 +243,10 @@ PWelsRCPictureInfoUpdateFunc pfWelsRcPictureInfoUpdate;
PWelsRCMBInitFunc pfWelsRcMbInit;
PWelsRCMBInfoUpdateFunc pfWelsRcMbInfoUpdate;
} SWelsRcFunc;
void WelsRcInitModule (void* pCtx,RC_MODES iRcMode);
void RcTraceFrameBits (void* pEncCtx, long long uiTimeStamp);
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode);
void WelsRcFreeMemory (void* pCtx);
}
#endif //RC_H

View File

@@ -47,22 +47,17 @@
#include "codec_app_def.h"
namespace WelsEnc {
typedef enum {
RECIEVE_UNKOWN = 0,
RECIEVE_SUCCESS = 1,
RECIEVE_FAILED = 2,
} LTR_MARKING_RECEIVE_STATE;
typedef enum {
LTR_DIRECT_MARK = 0,
LTR_DELAY_MARK = 1,
LTR_DELAY_MARK = 1
} LTR_MARKING_PROCESS_MODE;
typedef enum {
FRAME_NUM_EQUAL = 0x01,
FRAME_NUM_BIGGER = 0x02,
FRAME_NUM_SMALLER = 0x04,
FRAME_NUM_OVER_MAX = 0x08,
FRAME_NUM_OVER_MAX = 0x08
} COMPARE_FRAME_NUM;
/*
@@ -98,7 +93,7 @@ bool CheckCurMarkFrameNumUsed (sWelsEncCtx* pCtx);
*/
void WelsMarkPic (void* pCtx);
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, EUsageType eUsageType);
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bEnableLongTermReference, const bool bScreenContent);
#ifdef LONG_TERM_REF_DUMP
void DumpRef (sWelsEncCtx* ctx);

View File

@@ -168,7 +168,7 @@ SMVUnitXY sMvc[5];
uint8_t uiMvcNum;
uint8_t sScaleShift;
uint8_t uiSliceIdx;
uint32_t uiSliceIdx;
bool bSliceHeaderExtFlag; // Indicate which slice header is used, avc or ext?
uint8_t uiLastMbQp; // stored qp for last mb coded, maybe more efficient for mb skip detection etc.

View File

@@ -55,7 +55,7 @@ namespace WelsEnc {
typedef enum {
STATIC,
SCROLLED,
SCROLLED
} ESkipModes;
// NOILP ILFMD ENTRANCE

View File

@@ -62,7 +62,7 @@ ME_FULL = 0x10, // FULL
// derived ME methods combination
ME_DIA_CROSS = (ME_DIA | ME_CROSS), // DIA+CROSS
ME_DIA_CROSS_FME = (ME_DIA_CROSS | ME_FME), // DIA+CROSS+FME
ME_DIA_CROSS_FME = (ME_DIA_CROSS | ME_FME) // DIA+CROSS+FME
};
union SadPredISatdUnit {

View File

@@ -55,6 +55,8 @@
#define MAX_TRACE_LOG_SIZE (50 * (1<<20)) // max trace log size: 50 MB, overwrite occur if log file size exceeds this size
#endif//MAX_TRACE_LOG_SIZE
#define STATISTICS_LOG_INTERVAL_MS (5000) // output statistics log every 5s
/* MB width in pixels for specified colorspace I420 usually used in codec */
#define MB_WIDTH_LUMA 16
#define MB_WIDTH_CHROMA (MB_WIDTH_LUMA>>1)
@@ -149,7 +151,6 @@
#define MAX_SHORT_REF_COUNT (MAX_GOP_SIZE>>1) // 16 in standard, maximal count number of short reference pictures
#define LONG_TERM_REF_NUM 2
#define LONG_TERM_REF_NUM_SCREEN 4
#define MAX_LONG_REF_COUNT 2 // 16 in standard, maximal count number of long reference pictures
#define MAX_REF_PIC_COUNT 16 // 32 in standard, maximal Short + Long reference pictures
#define MIN_REF_PIC_COUNT 1 // minimal count number of reference pictures, 1 short + 2 key reference based?
#define MAX_MULTI_REF_PIC_COUNT 1 //maximum multi-reference number
@@ -159,7 +160,8 @@
// adjusted numbers reference picture functionality related definition
#define MAX_REFERENCE_MMCO_COUNT_NUM 4 // adjusted MAX_MMCO_COUNT(66 in standard) definition per encoder design
#define MAX_REFERENCE_REORDER_COUNT_NUM 2 // adjusted MAX_REF_PIC_COUNT(32 in standard) for reference reordering definition per encoder design
#define MAX_REFERENCE_PICTURE_COUNT_NUM (MAX_SHORT_REF_COUNT+MAX_LONG_REF_COUNT) // <= MAX_REF_PIC_COUNT, memory saved if <
#define MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA (MAX_SHORT_REF_COUNT+LONG_TERM_REF_NUM) // <= MAX_REF_PIC_COUNT, memory saved if <
#define MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN (MAX_SHORT_REF_COUNT+LONG_TERM_REF_NUM_SCREEN) // <= MAX_REF_PIC_COUNT, memory saved if <
#define BASE_QUALITY_ID 0
#define BASE_DEPENDENCY_ID 0
@@ -189,6 +191,12 @@ BLOCK_4x4 = 4,
BLOCK_SIZE_ALL = 5
};
typedef enum {
RECIEVE_UNKOWN = 0,
RECIEVE_SUCCESS = 1,
RECIEVE_FAILED = 2
} LTR_MARKING_RECEIVE_STATE;
enum {
CUR_AU_IDX = 0, // index symbol for current access unit
SUC_AU_IDX = 1 // index symbol for successive access unit

View File

@@ -195,6 +195,8 @@ typedef void (*PUpdateMbMvFunc) (SMVUnitXY* pMvUnit, const SMVUnitXY ksMv);
typedef bool (*PBuildRefListFunc) (void* pCtx, const int32_t iPOC, int32_t iBestLtrRefIdx);
typedef void (*PMarkPicFunc) (void* pCtx);
typedef bool (*PUpdateRefListFunc) (void* pCtx);
typedef void (*PEndofUpdateRefListFunc) (void* pCtx);
typedef void (*PAfterBuildRefListFunc) (void* pCtx);
typedef int32_t (*PCavlcParamCalFunc) (int16_t* pCoff, uint8_t* pRun, int16_t* pLevel, int32_t* pTotalCoeffs,
int32_t iEndIdx);
@@ -291,6 +293,8 @@ struct TagWelsFuncPointerList {
PBuildRefListFunc pBuildRefList;
PMarkPicFunc pMarkPic;
PUpdateRefListFunc pUpdateRefList;
PEndofUpdateRefListFunc pEndofUpdateRefList;
PAfterBuildRefListFunc pAfterBuildRefList;
PCavlcParamCalFunc pfCavlcParamCal;
};

View File

@@ -109,6 +109,7 @@ typedef struct SVAAFrameInfoExt_t: public SVAAFrameInfo {
SRefInfoParam sVaaStrBestRefCandidate[MAX_REF_PIC_COUNT]; //TOP3_BEST_REF_NO_TID
int32_t iNumOfAvailableRef;
int32_t iVaaBestRefFrameNum;
uint8_t* pVaaBestBlockStaticIdc;//pointer
uint8_t* pVaaBlockStaticIdc[16];//real memory,
} SVAAFrameInfoExt;
@@ -129,6 +130,15 @@ class CWelsPreProcess {
int32_t GetRefFrameInfo (int32_t iRefIdx, SPicture*& pRefOri);
void AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture,
const int32_t kiDependencyId, const bool kbCalculateBGD);
int32_t UpdateBlockIdcForScreen (uint8_t* pCurBlockStaticPointer, const SPicture* kpRefPic, const SPicture* kpSrcPic);
SPicture* GetCurrentFrameFromOrigList (int32_t iDIdx) {
return m_pSpatialPic[iDIdx][0];
}
void UpdateSrcList (SPicture* pCurPicture, const int32_t kiCurDid, SPicture** pShortRefList,
const uint32_t kuiShortRefCount);
void UpdateSrcListLosslessScreenRefSelectionWithLtr (SPicture* pCurPicture, const int32_t kiCurDid,
const int32_t kuiMarkLongTermPicIdx, SPicture** pLongRefList);
private:
int32_t WelsPreprocessCreate();
@@ -158,6 +168,9 @@ class CWelsPreProcess {
ESceneChangeIdc DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPicture* pCurPicture);
void InitPixMap (const SPicture* pPicture, SPixMap* pPixMap);
void GetAvailableRefListLosslessScreenRefSelection (SPicture** pSrcPicList, uint8_t iCurTid,
const int32_t iClosestLtrFrameNum,
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum);
void GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurTid, const int32_t iClosestLtrFrameNum,
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum);
void InitRefJudgement (SRefJudgement* pRefJudgement);
@@ -168,6 +181,14 @@ class CWelsPreProcess {
SRefInfoParam* pRefSaved);
void SaveBestRefToVaa (SRefInfoParam& sRefSaved, SRefInfoParam* pVaaBestRef);
/*!
* \brief exchange two picture pData planes
* \param ppPic1 picture pointer to picture 1
* \param ppPic2 picture pointer to picture 2
* \return none
*/
void WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2);
private:
Scaled_Picture m_sScaledPicture;
SPicture* m_pLastSpatialPicture[MAX_DEPENDENCY_LAYER][2];
@@ -178,8 +199,9 @@ class CWelsPreProcess {
uint8_t m_uiSpatialPicNum[MAX_DEPENDENCY_LAYER];
public:
/* For Downsampling & VAA I420 based source pictures */
SPicture* m_pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1 +
LONG_TERM_REF_NUM]; // need memory requirement with total number of (log2(uiGopSize)+1+1+long_term_ref_num)
SPicture* m_pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_REF_PIC_COUNT + 1];
// need memory requirement with total number of num_of_ref + 1, "+1" is for current frame
int32_t m_iAvaliableRefInSpatialPicList;
};

View File

@@ -218,7 +218,9 @@ int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam*
WelsBlockFuncInit (&pFuncList->pfSetNZCZero, uiCpuFlag);
InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection);
InitRefListMgrFunc (pFuncList, pParam->iUsageType);
InitRefListMgrFunc (pFuncList, pParam->bEnableLongTermReference, bScreenContent);
return iReturn;
}
@@ -363,11 +365,13 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum
* \brief Dump reconstruction for dependency layer
*/
extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend, SDqLayer* pDqLayer) {
extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend,
SDqLayer* pDqLayer) {
WelsFileHandle* pDumpRecFile = NULL;
int32_t iWrittenSize = 0;
const char* openMode = bAppend ? "ab" : "wb";
SWelsSPS* pSpsTmp = (kiDid> BASE_DEPENDENCY_ID)? &(pDqLayer->sLayerInfo.pSubsetSpsP->pSps) : pDqLayer->sLayerInfo.pSpsP;
SWelsSPS* pSpsTmp = (kiDid > BASE_DEPENDENCY_ID) ? & (pDqLayer->sLayerInfo.pSubsetSpsP->pSps) :
pDqLayer->sLayerInfo.pSpsP;
bool bFrameCroppingFlag = pSpsTmp->bFrameCroppingFlag;
SCropOffset* pFrameCrop = &pSpsTmp->sFrameCrop;
@@ -388,12 +392,15 @@ extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName
int32_t i = 0;
int32_t j = 0;
const int32_t kiStrideY = pCurPicture->iLineSize[0];
const int32_t kiLumaWidth = bFrameCroppingFlag?(pCurPicture->iWidthInPixel-(( pFrameCrop->iCropLeft + pFrameCrop->iCropRight ) << 1 )) : pCurPicture->iWidthInPixel;
const int32_t kiLumaHeight = bFrameCroppingFlag?(pCurPicture->iHeightInPixel-(( pFrameCrop->iCropTop + pFrameCrop->iCropBottom ) << 1 )) : pCurPicture->iHeightInPixel;
const int32_t kiLumaWidth = bFrameCroppingFlag ? (pCurPicture->iWidthInPixel - ((pFrameCrop->iCropLeft +
pFrameCrop->iCropRight) << 1)) : pCurPicture->iWidthInPixel;
const int32_t kiLumaHeight = bFrameCroppingFlag ? (pCurPicture->iHeightInPixel - ((pFrameCrop->iCropTop +
pFrameCrop->iCropBottom) << 1)) : pCurPicture->iHeightInPixel;
const int32_t kiChromaWidth = kiLumaWidth >> 1;
const int32_t kiChromaHeight = kiLumaHeight >> 1;
uint8_t* pSrc = NULL;
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * ( pFrameCrop->iCropTop << 1 ) + ( pFrameCrop->iCropLeft << 1 )) : pCurPicture->pData[0];
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * (pFrameCrop->iCropTop << 1) +
(pFrameCrop->iCropLeft << 1)) : pCurPicture->pData[0];
for (j = 0; j < kiLumaHeight; ++ j) {
iWrittenSize = WelsFwrite (pSrc + j * kiStrideY, 1, kiLumaWidth, pDumpRecFile);
assert (iWrittenSize == kiLumaWidth);
@@ -405,7 +412,8 @@ extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName
}
for (i = 1; i < I420_PLANES; ++ i) {
const int32_t kiStrideUV = pCurPicture->iLineSize[i];
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) : pCurPicture->pData[i];
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) :
pCurPicture->pData[i];
for (j = 0; j < kiChromaHeight; ++ j) {
iWrittenSize = WelsFwrite (pSrc + j * kiStrideUV, 1, kiChromaWidth, pDumpRecFile);
assert (iWrittenSize == kiChromaWidth);
@@ -425,9 +433,11 @@ extern "C" void DumpDependencyRec (SPicture* pCurPicture, const char* kpFileName
* \brief Dump the reconstruction pictures
*/
void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend, SDqLayer* pDqLayer) {
void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t kiDid, bool bAppend,
SDqLayer* pDqLayer) {
WelsFileHandle* pDumpRecFile = NULL;
SWelsSPS* pSpsTmp = (kiDid> BASE_DEPENDENCY_ID)? &(pDqLayer->sLayerInfo.pSubsetSpsP->pSps) : pDqLayer->sLayerInfo.pSpsP;
SWelsSPS* pSpsTmp = (kiDid > BASE_DEPENDENCY_ID) ? & (pDqLayer->sLayerInfo.pSubsetSpsP->pSps) :
pDqLayer->sLayerInfo.pSpsP;
bool bFrameCroppingFlag = pSpsTmp->bFrameCroppingFlag;
SCropOffset* pFrameCrop = &pSpsTmp->sFrameCrop;
@@ -449,12 +459,15 @@ void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t k
int32_t i = 0;
int32_t j = 0;
const int32_t kiStrideY = pCurPicture->iLineSize[0];
const int32_t kiLumaWidth = bFrameCroppingFlag ? (pCurPicture->iWidthInPixel-(( pFrameCrop->iCropLeft + pFrameCrop->iCropRight ) << 1 )) : pCurPicture->iWidthInPixel;
const int32_t kiLumaHeight = bFrameCroppingFlag ? (pCurPicture->iHeightInPixel-(( pFrameCrop->iCropTop + pFrameCrop->iCropBottom ) << 1 )) : pCurPicture->iHeightInPixel;
const int32_t kiLumaWidth = bFrameCroppingFlag ? (pCurPicture->iWidthInPixel - ((pFrameCrop->iCropLeft +
pFrameCrop->iCropRight) << 1)) : pCurPicture->iWidthInPixel;
const int32_t kiLumaHeight = bFrameCroppingFlag ? (pCurPicture->iHeightInPixel - ((pFrameCrop->iCropTop +
pFrameCrop->iCropBottom) << 1)) : pCurPicture->iHeightInPixel;
const int32_t kiChromaWidth = kiLumaWidth >> 1;
const int32_t kiChromaHeight = kiLumaHeight >> 1;
uint8_t* pSrc = NULL;
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * ( pFrameCrop->iCropTop << 1 ) + ( pFrameCrop->iCropLeft << 1 )) : pCurPicture->pData[0];
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[0] + kiStrideY * (pFrameCrop->iCropTop << 1) +
(pFrameCrop->iCropLeft << 1)) : pCurPicture->pData[0];
for (j = 0; j < kiLumaHeight; ++ j) {
iWrittenSize = WelsFwrite (pSrc + j * kiStrideY, 1, kiLumaWidth, pDumpRecFile);
assert (iWrittenSize == kiLumaWidth);
@@ -466,7 +479,8 @@ void DumpRecFrame (SPicture* pCurPicture, const char* kpFileName, const int8_t k
}
for (i = 1; i < I420_PLANES; ++ i) {
const int32_t kiStrideUV = pCurPicture->iLineSize[i];
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) : pCurPicture->pData[i];
pSrc = bFrameCroppingFlag ? (pCurPicture->pData[i] + kiStrideUV * pFrameCrop->iCropTop + pFrameCrop->iCropLeft) :
pCurPicture->pData[i];
for (j = 0; j < kiChromaHeight; ++ j) {
iWrittenSize = WelsFwrite (pSrc + j * kiStrideUV, 1, kiChromaWidth, pDumpRecFile);
assert (iWrittenSize == kiChromaWidth);

View File

@@ -75,7 +75,6 @@ int32_t WelsCodeOnePicPartition (sWelsEncCtx* pCtx,
* \return successful - 0; otherwise none 0 for failed
*/
int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
float fMaxFrameRate = 0.0f;
const float fEpsn = 0.000001f;
int32_t i = 0;
@@ -128,28 +127,15 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
return ENC_RETURN_INVALIDINPUT;
}
if (UINT_MAX == GetLogFactor (fDlp->fOutputFrameRate, fDlp->fInputFrameRate)) {
WelsLog (pLogCtx, WELS_LOG_ERROR,
"Invalid settings in input frame rate(%.6f) and output frame rate(%.6f) of layer #%d config file: iResult of output frame rate divided by input frame rate should be power of 2(i.e,in/pOut=2^n)..",
fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i);
return ENC_RETURN_INVALIDINPUT;
WelsLog (pLogCtx, WELS_LOG_WARNING,
"AUTO CORRECT: Invalid settings in input frame rate(%.6f) and output frame rate(%.6f) of layer #%d config file: iResult of output frame rate divided by input frame rate should be power of 2(i.e,in/pOut=2^n). \n Auto correcting Output Framerate to Input Framerate %f!\n",
fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i, fDlp->fInputFrameRate);
fDlp->fOutputFrameRate = fDlp->fInputFrameRate;
}
}
for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {
SSpatialLayerInternal* fDlp = &pCfg->sDependencyLayers[i];
if (fDlp->fInputFrameRate > fMaxFrameRate)
fMaxFrameRate = fDlp->fInputFrameRate;
}
if (fMaxFrameRate > fEpsn && (fMaxFrameRate - pCfg->fMaxFrameRate > fEpsn
|| fMaxFrameRate - pCfg->fMaxFrameRate < -fEpsn)) {
pCfg->fMaxFrameRate = fMaxFrameRate;
}
if ((pCfg->iRCMode != RC_OFF_MODE) && (pCfg->iRCMode != RC_QUALITY_MODE) && (pCfg->iRCMode != RC_BUFFERBASED_MODE)
&& (pCfg->iRCMode != RC_BITRATE_MODE)
&& (pCfg->iRCMode != RC_LOW_BW_MODE)) {
&& (pCfg->iRCMode != RC_BITRATE_MODE)) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidation(),Invalid iRCMode = %d", pCfg->iRCMode);
return ENC_RETURN_UNSUPPORTED_PARA;
}
@@ -168,6 +154,12 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
pSpatialLayer->iSpatialBitrate);
return ENC_RETURN_INVALIDINPUT;
}
if (pSpatialLayer->iMaxSpatialBitrate < pSpatialLayer->iSpatialBitrate * 1.1f) {
WelsLog (pLogCtx, WELS_LOG_WARNING,
"MaxSpatialBitrate (%d) should set be larger than 1.1 times of SpatialBitrate (%d)",
pSpatialLayer->iMaxSpatialBitrate, pSpatialLayer->iSpatialBitrate);
// pSpatialLayer->iSpatialBitrate = (int32_t) (pSpatialLayer->iMaxSpatialBitrate/1.1f);
}
}
if (iTotalBitrate > pCfg->iTargetBitrate) {
WelsLog (pLogCtx, WELS_LOG_ERROR,
@@ -197,6 +189,12 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(),Invalid usage type = %d", pCodingParam->iUsageType);
return ENC_RETURN_UNSUPPORTED_PARA;
}
if ((pCodingParam->iUsageType == SCREEN_CONTENT_REAL_TIME) && (!pCodingParam->bIsLosslessLink
&& pCodingParam->bEnableLongTermReference)) {
WelsLog (pLogCtx, WELS_LOG_WARNING,
"ParamValidationExt(), setting lossy link for LTR under screen, which is not supported yet! Auto disabled LTR!");
pCodingParam->bEnableLongTermReference = false;
}
if (pCodingParam->iSpatialLayerNum < 1 || pCodingParam->iSpatialLayerNum > MAX_DEPENDENCY_LAYER) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), monitor invalid pCodingParam->iSpatialLayerNum: %d!",
pCodingParam->iSpatialLayerNum);
@@ -358,7 +356,7 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa
return ENC_RETURN_UNSUPPORTED_PARA;
}
if (pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum == 1) {
WelsLog (pLogCtx, WELS_LOG_ERROR,
WelsLog (pLogCtx, WELS_LOG_WARNING,
"ParamValidationExt(), pSlice setting for SM_RASTER_SLICE now turn to SM_SINGLE_SLICE!");
pSpatialLayer->sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
break;
@@ -1255,7 +1253,7 @@ int32_t RequestMemoryVaaScreen (SVAAFrameInfo* pVaa, CMemoryAlign* pMa, const
void ReleaseMemoryVaaScreen (SVAAFrameInfo* pVaa, CMemoryAlign* pMa, const int32_t iNumRef) {
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pVaa);
if (pVaaExt && pMa && pVaaExt->pVaaBlockStaticIdc[0]) {
pMa->WelsFree (pVaaExt->pVaaBlockStaticIdc[0], "pVaa->pVaaBlockStaticIdc");
pMa->WelsFree (pVaaExt->pVaaBlockStaticIdc[0], "pVaa->pVaaBlockStaticIdc[0]");
for (int32_t idx = 0; idx < iNumRef; idx++) {
pVaaExt->pVaaBlockStaticIdc[idx] = NULL;
@@ -1359,7 +1357,9 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
iTargetSpatialBsSize = iLayerBsSize;
iCountBsLen = iNonVclLayersBsSizeCount + iVclLayersBsSizeCount;
pParam->iNumRefFrame = WELS_CLIP3 (pParam->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
pParam->iNumRefFrame = WELS_CLIP3 (pParam->iNumRefFrame, MIN_REF_PIC_COUNT,
(pParam->iUsageType == CAMERA_VIDEO_REAL_TIME ? MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA :
MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN));
// Output
(*ppCtx)->pOut = (SWelsEncoderOutput*)pMa->WelsMalloc (sizeof (SWelsEncoderOutput), "SWelsEncoderOutput");
@@ -1471,7 +1471,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
}
(*ppCtx)->pVaa->pVaaBackgroundMbFlag = (int8_t*)pMa->WelsMallocz (iCountMaxMbNum * sizeof (int8_t),
"pVaa->vaa_skip_mb_flag");
"pVaa->pVaaBackgroundMbFlag");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pVaa->pVaaBackgroundMbFlag), FreeMemorySvc (ppCtx))
(*ppCtx)->pVaa->sVaaCalcInfo.pSad8x8 = static_cast<int32_t (*)[4]>
@@ -1489,10 +1489,10 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
if ((*ppCtx)->pSvcParam->bEnableBackgroundDetection) { //BGD control
(*ppCtx)->pVaa->sVaaCalcInfo.pSumOfDiff8x8 = static_cast<int32_t (*)[4]>
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (int32_t), "pVaa->sVaaCalcInfo.sd_16x16"));
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (int32_t), "pVaa->sVaaCalcInfo.pSumOfDiff8x8"));
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pVaa->sVaaCalcInfo.pSumOfDiff8x8), FreeMemorySvc (ppCtx))
(*ppCtx)->pVaa->sVaaCalcInfo.pMad8x8 = static_cast<uint8_t (*)[4]>
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (uint8_t), "pVaa->sVaaCalcInfo.mad_16x16"));
(pMa->WelsMallocz (iCountMaxMbNum * 4 * sizeof (uint8_t), "pVaa->sVaaCalcInfo.pMad8x8"));
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pVaa->sVaaCalcInfo.pMad8x8), FreeMemorySvc (ppCtx))
}
@@ -2015,6 +2015,13 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), ParamValidationExt failed return %d.", iRet);
return iRet;
}
iRet = pCodingParam->DetermineTemporalSettings();
if (iRet != ENC_RETURN_SUCCESS) {
WelsLog (pLogCtx, WELS_LOG_ERROR,
"WelsInitEncoderExt(), DetermineTemporalSettings failed return %d (check in/out frame rate and temporal layer setting!)",
iRet);
return iRet;
}
iRet = GetMultipleThreadIdc (pLogCtx, pCodingParam, iSliceNum, iCacheLineSize, uiCpuFeatureFlags);
if (iRet != 0) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), GetMultipleThreadIdc failed return %d.", iRet);
@@ -2034,7 +2041,6 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
pCtx->pMemAlign = new CMemoryAlign (iCacheLineSize);
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pCtx->pMemAlign), FreeMemorySvc (&pCtx))
pCodingParam->DetermineTemporalSettings();
iRet = AllocCodingParam (&pCtx->pSvcParam, pCtx->pMemAlign);
if (iRet != 0) {
FreeMemorySvc (&pCtx);
@@ -2083,6 +2089,8 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
);
#endif//MEMORY_MONITOR
pCtx->iStatisticsLogInterval = STATISTICS_LOG_INTERVAL_MS;
*ppCtx = pCtx;
WelsLog (pLogCtx, WELS_LOG_DEBUG, "WelsInitEncoderExt(), pCtx= 0x%p.", (void*)pCtx);
@@ -2594,7 +2602,8 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
pFeatureSearchPreparation->pRefBlockFeature = pScreenBlockFeatureStorage;
if (pFeatureSearchPreparation->bFMESwitchFlag
&& !pScreenBlockFeatureStorage->bRefBlockFeatureCalculated) {
PerformFMEPreprocess (pFuncList, pCurLayer->pRefOri[0], pFeatureSearchPreparation->pFeatureOfBlock,
SPicture* pRef = (pCtx->pSvcParam->bEnableLongTermReference ? pCurLayer->pRefOri[0] : pCurLayer->pRefPic);
PerformFMEPreprocess (pFuncList, pRef, pFeatureSearchPreparation->pFeatureOfBlock,
pScreenBlockFeatureStorage);
}
@@ -2694,7 +2703,6 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
if (uiNextIdInBs >= kuiMaxIdInBs) {
uiNextIdInBs = 0;//ensure the SPS_ID wound not exceed MAX_SPS_COUNT
}
// update next_id
sParaSetOffsetVariable->uiNextParaSetIdToUseInBs = uiNextIdInBs;
}
@@ -2952,18 +2960,18 @@ int32_t GetSubSequenceId (sWelsEncCtx* pCtx, EVideoFrameType eFrameType) {
}
//loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pCtx, int32_t iSpatialNum) {
bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
const uint32_t uiTimeStamp) {
SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
bool bSkipMustFlag = false;
if (pCtx->pSvcParam->bEnableFrameSkip) {
if ((RC_QUALITY_MODE == pCtx->pSvcParam->iRCMode) || (RC_BITRATE_MODE == pCtx->pSvcParam->iRCMode)
|| (RC_LOW_BW_MODE == pCtx->pSvcParam->iRCMode)) {
if ((RC_QUALITY_MODE == pCtx->pSvcParam->iRCMode) || (RC_BITRATE_MODE == pCtx->pSvcParam->iRCMode)) {
for (int32_t i = 0; i < iSpatialNum; i++) {
if (0 == pCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
break;
}
pCtx->uiDependencyId = (uint8_t) (pSpatialIndexMap + i)->iDid;
pCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pCtx);
pCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pCtx, eFrameType, uiTimeStamp);
if (true == pCtx->pWelsSvcRc[pCtx->uiDependencyId].bSkipFlag) {
bSkipMustFlag = true;
break;
@@ -3027,18 +3035,24 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
if (iSpatialNum < 1) { // skip due to temporal layer settings (different frame rate)
++ pCtx->iCodingIndex;
pFbi->eFrameType = videoFrameTypeSkip;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %8" PRId64", skip one frame",
(int64_t)pSrcPic->uiTimeStamp);
return ENC_RETURN_SUCCESS;
}
eFrameType = DecideFrameType (pCtx, iSpatialNum);
if (eFrameType == videoFrameTypeSkip) {
pFbi->eFrameType = eFrameType;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %8" PRId64", skip one frame",
(int64_t)pSrcPic->uiTimeStamp);
return ENC_RETURN_SUCCESS;
}
//loop each layer to check if have skip frame when RC and frame skip enable
if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum)) {
if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType, (uint32_t)pSrcPic->uiTimeStamp)) {
pFbi->eFrameType = videoFrameTypeSkip;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %8" PRId64", skip one frame",
(int64_t)pSrcPic->uiTimeStamp);
return ENC_RETURN_SUCCESS;
}
@@ -3166,6 +3180,9 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
pCtx->iEncoderError = ENC_RETURN_CORRECTED;
return ENC_RETURN_CORRECTED;
}
if (pCtx->eSliceType != I_SLICE) {
pCtx->pFuncList->pAfterBuildRefList (pCtx);
}
#ifdef LONG_TERM_REF_DUMP
DumpRef (pCtx);
#endif
@@ -3419,6 +3436,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
}
pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
RcTraceFrameBits (pCtx, pSrcPic->uiTimeStamp);
pCtx->pDecPic->iFrameAverageQp = pCtx->pWelsSvcRc->iAverageFrameQp;
//update scc related
@@ -3438,7 +3456,14 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
}
iFrameSize += iLayerSize;
//check MinCr
{
int32_t iImageSize = (pParam->iVideoWidth * pParam->iVideoHeight * 3) >> 1;
int32_t iMinCr = g_ksLevelLimits[pParam->uiLevelIdc - 1].uiMinCR;
if (iFrameSize > (iImageSize / iMinCr))
WelsLog (pLogCtx, WELS_LOG_WARNING,
"WelsEncoderEncodeExt()MinCr Checking,codec bitstream size is larger than Level limitation");
}
#ifdef ENABLE_FRAME_DUMP
if (iCurDid + 1 < pSvcParam->iSpatialLayerNum) {
DumpDependencyRec (fsnr, &pSvcParam->sDependencyLayers[iCurDid].sRecFileName[0], iCurDid,
@@ -3720,6 +3745,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
uiTmpIdrPicId = (*ppCtx)->sPSOVector.uiIdrPicId;
SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;
WelsUninitEncoderExt (ppCtx);
/* Update new parameters */
@@ -3730,14 +3757,18 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
//if WelsInitEncoderExt succeed
//load back the needed structure
//for FLEXIBLE_PARASET_ID
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
(*ppCtx)->sPSOVector.uiIdrPicId = uiTmpIdrPicId;
//for sEncoderStatistics
(*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;
} else {
/* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,
MAX_REFERENCE_PICTURE_COUNT_NUM);
(pNewParam->iUsageType == CAMERA_VIDEO_REAL_TIME ? MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA :
MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN));
pNewParam->iLoopFilterDisableIdc = WELS_CLIP3 (pNewParam->iLoopFilterDisableIdc, 0, 6);
pNewParam->iLoopFilterAlphaC0Offset = WELS_CLIP3 (pNewParam->iLoopFilterAlphaC0Offset, -6, 6);
pNewParam->iLoopFilterBetaOffset = WELS_CLIP3 (pNewParam->iLoopFilterBetaOffset, -6, 6);
@@ -3819,16 +3850,17 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
return 0;
}
void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue) {
int32_t WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig* pLTRValue) {
SWelsSvcCodingParam sConfig;
int32_t iNumRefFrame = 1;
int32_t iRet = 0;
memcpy (&sConfig, (*ppCtx)->pSvcParam, sizeof (SWelsSvcCodingParam));
sConfig.bEnableLongTermReference = pLTRValue->bEnableLongTermReference;
sConfig.iLTRRefNum = pLTRValue->iLTRRefNum;
int32_t uiGopSize = 1 << (sConfig.iTemporalLayerNum - 1);
if (sConfig.iUsageType == SCREEN_CONTENT_REAL_TIME) {
if (sConfig.bEnableLongTermReference) {
sConfig.iLTRRefNum = WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM_SCREEN);
sConfig.iLTRRefNum = LONG_TERM_REF_NUM_SCREEN;//WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM_SCREEN);
iNumRefFrame = WELS_MAX (1, WELS_LOG2 (uiGopSize)) + sConfig.iLTRRefNum;
} else {
sConfig.iLTRRefNum = 0;
@@ -3836,13 +3868,13 @@ void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig*
}
} else {
if (sConfig.bEnableLongTermReference) {
sConfig.iLTRRefNum = WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM);
sConfig.iLTRRefNum = LONG_TERM_REF_NUM;//WELS_CLIP3 (sConfig.iLTRRefNum, 1, LONG_TERM_REF_NUM);
} else {
sConfig.iLTRRefNum = 0;
}
iNumRefFrame = ((uiGopSize >> 1) > 1) ? ((uiGopSize >> 1) + sConfig.iLTRRefNum) : (MIN_REF_PIC_COUNT +
sConfig.iLTRRefNum);
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
iNumRefFrame = WELS_CLIP3 (iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA);
}
if (sConfig.iNumRefFrame < iNumRefFrame)
@@ -3852,7 +3884,8 @@ void WelsEncoderApplyLTR (SLogContext* pLogCtx, sWelsEncCtx** ppCtx, SLTRConfig*
WelsLog (pLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable LTR = %d,ltrnum = %d",
sConfig.bEnableLongTermReference, sConfig.iLTRRefNum);
WelsEncoderParamAdjust (ppCtx, &sConfig);
iRet = WelsEncoderParamAdjust (ppCtx, &sConfig);
return iRet;
}
int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
SFrameBSInfo* pFrameBsInfo,

View File

@@ -41,6 +41,7 @@
*/
#include "ls_defines.h"
#include "cpu_core.h"
#include "intra_pred_common.h"
#include "get_intra_predictor.h"
namespace WelsEnc {
@@ -538,37 +539,6 @@ void WelsIChromaPredDcNA_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStrid
}
void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
uint8_t i = 15;
const int8_t* kpSrc = (int8_t*)&pRef[-kiStride];
const uint64_t kuiT1 = LD64 (kpSrc);
const uint64_t kuiT2 = LD64 (kpSrc + 8);
uint8_t* pDst = pPred;
do {
ST64 (pDst , kuiT1);
ST64 (pDst + 8, kuiT2);
pDst += 16;
} while (i-- > 0);
}
void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
int32_t iStridex15 = (kiStride << 4) - kiStride;
int32_t iPredStride = 16;
int32_t iPredStridex15 = 240; //(iPredStride<<4)-iPredStride;
uint8_t i = 15;
do {
const uint8_t kuiSrc8 = pRef[iStridex15 - 1];
const uint64_t kuiV64 = (uint64_t) (0x0101010101010101ULL * kuiSrc8);
ST64 (&pPred[iPredStridex15], kuiV64);
ST64 (&pPred[iPredStridex15 + 8], kuiV64);
iStridex15 -= kiStride;
iPredStridex15 -= iPredStride;
} while (i-- > 0);
}
void WelsI16x16LumaPredPlane_c (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride) {
int32_t iLTshift = 0, iTopshift = 0, iLeftshift = 0, iTopSum = 0, iLeftSum = 0;
int32_t i, j;

View File

@@ -98,7 +98,7 @@ SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth , const int32_t
pPic->uiRefMbType = (uint32_t*)pMa->WelsMallocz (kuiCountMbNum * sizeof (uint32_t), "pPic->uiRefMbType");
WELS_VERIFY_RETURN_PROC_IF (NULL, NULL == pPic->uiRefMbType, FreePicture (pMa, &pPic));
pPic->pRefMbQp = (uint8_t*)pMa->WelsMallocz (kuiCountMbNum * sizeof (uint8_t), "pPic->bgd_mb_qp");
pPic->pRefMbQp = (uint8_t*)pMa->WelsMallocz (kuiCountMbNum * sizeof (uint8_t), "pPic->pRefMbQp");
WELS_VERIFY_RETURN_PROC_IF (NULL, NULL == pPic->pRefMbQp, FreePicture (pMa, &pPic));
pPic->sMvList = static_cast<SMVUnitXY*> (pMa->WelsMallocz (kuiCountMbNum * sizeof (SMVUnitXY),
@@ -152,11 +152,11 @@ void FreePicture (CMemoryAlign* pMa, SPicture** ppPic) {
pPic->iMarkFrameNum = -1;
if (pPic->uiRefMbType) {
pMa->WelsFree (pPic->uiRefMbType, "pPic->bgd_mb_type");
pMa->WelsFree (pPic->uiRefMbType, "pPic->uiRefMbType");
pPic->uiRefMbType = NULL;
}
if (pPic->pRefMbQp) {
pMa->WelsFree (pPic->pRefMbQp, "pPic->bgd_mb_qp");
pMa->WelsFree (pPic->pRefMbQp, "pPic->pRefMbQp");
pPic->pRefMbQp = NULL;
}
@@ -179,20 +179,6 @@ void FreePicture (CMemoryAlign* pMa, SPicture** ppPic) {
*ppPic = NULL;
}
}
/*!
* \brief exchange two picture pData planes
* \param ppPic1 picture pointer to picture 1
* \param ppPic2 picture pointer to picture 2
* \return none
*/
void WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2) {
SPicture* tmp = *ppPic1;
assert (*ppPic1 != *ppPic2);
*ppPic1 = *ppPic2;
*ppPic2 = tmp;
}
} // namespace WelsEnc

View File

@@ -49,6 +49,10 @@
namespace WelsEnc {
#define VIRTUAL_BUFFER_LOW_TH 120 //*INT_MULTIPLY
#define VIRTUAL_BUFFER_HIGH_TH 180 //*INT_MULTIPLY
//#define _TEST_TEMP_RC_
#ifdef _TEST_TEMP_RC_
//#define _NOT_USE_AQ_FOR_TEST_
@@ -70,7 +74,7 @@ void RcInitLayerMemory (SWelsSvcRc* pWelsSvcRc, CMemoryAlign* pMA, const int32_t
const int32_t kiGomSizeD = kiGomSize * sizeof (double);
const int32_t kiGomSizeI = kiGomSize * sizeof (int32_t);
const int32_t kiLayerRcSize = kiGomSizeD + (kiGomSizeI * 3) + sizeof (SRCTemporal) * kiMaxTl;
uint8_t* pBaseMem = (uint8_t*)pMA->WelsMalloc (kiLayerRcSize, "rc_layer_memory");
uint8_t* pBaseMem = (uint8_t*)pMA->WelsMalloc (kiLayerRcSize, "pWelsSvcRc->pTemporalOverRc");
if (NULL == pBaseMem)
return;
@@ -94,7 +98,7 @@ void RcFreeLayerMemory (SWelsSvcRc* pWelsSvcRc, CMemoryAlign* pMA) {
pWelsSvcRc->pSlicingOverRc = NULL;
}
if (pWelsSvcRc != NULL && pWelsSvcRc->pTemporalOverRc != NULL) {
pMA->WelsFree (pWelsSvcRc->pTemporalOverRc, "rc_layer_memory");
pMA->WelsFree (pWelsSvcRc->pTemporalOverRc, "pWelsSvcRc->pTemporalOverRc");
pWelsSvcRc->pTemporalOverRc = NULL;
pWelsSvcRc->pGomComplexity = NULL;
pWelsSvcRc->pGomForegroundBlockNum = NULL;
@@ -512,7 +516,7 @@ void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {
iLumaQp = WELS_DIV_ROUND (iLumaQp * INT_MULTIPLY - pEncCtx->pVaa->sAdaptiveQuantParam.iAverMotionTextureIndexToDeltaQp,
INT_MULTIPLY);
if (pEncCtx->pSvcParam->iRCMode != RC_LOW_BW_MODE)
if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false)))
iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
}
@@ -554,10 +558,9 @@ void RcDecideTargetBits (sWelsEncCtx* pEncCtx) {
pWelsSvcRc->iRemainingWeights);
else //this case should be not hit. needs to more test case to verify this
pWelsSvcRc->iTargetBits = pWelsSvcRc->iRemainingBits;
if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) {
if ((pWelsSvcRc->iTargetBits <= 0) && ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE)
&& (pEncCtx->pSvcParam->bEnableFrameSkip == false))) {
pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED;
} else if ((pWelsSvcRc->iTargetBits <= pTOverRc->iMinBitsTl) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) {
pWelsSvcRc->iCurrentBitsLevel = BITS_LIMITED;
}
pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl);
}
@@ -572,6 +575,8 @@ void RcInitGomParameters (sWelsEncCtx* pEncCtx) {
const int32_t kiGlobalQp = pEncCtx->iGlobalQp;
pWelsSvcRc->iAverageFrameQp = 0;
pWelsSvcRc->iMinFrameQp = 51;;
pWelsSvcRc->iMaxFrameQp = 0;
for (int32_t i = 0; i < kiSliceNum; ++i) {
pSOverRc->iComplexityIndexSlice = 0;
pSOverRc->iCalculatedQpSlice = kiGlobalQp;
@@ -683,7 +688,7 @@ void RcCalculateGomQp (sWelsEncCtx* pEncCtx, SMB* pCurMb, int32_t iSliceId) {
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice,
pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame);
if (! (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE))
if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false)))
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
pSOverRc->iGomBitsSlice = 0;
@@ -696,6 +701,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
//condition 1: whole pBuffer fullness
pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
//condition 2: VGOP bits constraint
int32_t iVGopBitsPred = 0;
for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++)
@@ -709,20 +715,19 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|| (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
pEncCtx->iSkipFrameFlag = 1;
pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "skip one frame");
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
}
if (pWelsSvcRc->iBufferFullnessSkip < 0)
pWelsSvcRc->iBufferFullnessSkip = 0;
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
if (pEncCtx->iSkipFrameFlag == 1) {
pWelsSvcRc->iRemainingBits += WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
pWelsSvcRc->iRemainingBits += kiOutputBits;
pWelsSvcRc->iSkipFrameNum++;
pWelsSvcRc->iSkipFrameInVGop++;
}
}
void WelsRcFrameDelayJudge (void* pCtx) {
void WelsRcFrameDelayJudge (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
@@ -733,7 +738,10 @@ void WelsRcFrameDelayJudge (void* pCtx) {
pWelsSvcRc->bSkipFlag = false;
if (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip) {
pWelsSvcRc->bSkipFlag = true;
pWelsSvcRc->iSkipFrameNum++;
pWelsSvcRc->iSkipFrameInVGop++;
pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
}
}
@@ -754,14 +762,17 @@ void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
}
void RcTraceFrameBits (sWelsEncCtx* pEncCtx) {
void RcTraceFrameBits (void* pCtx, long long uiTimeStamp) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
"[Rc] encoding_qp%d, qp = %3d, index = %8d, iTid = %1d, used = %8d, target = %8d, remaingbits = %8d",
pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp, pEncCtx->iFrameIndex, pEncCtx->uiTemporalId,
pWelsSvcRc->iFrameDqBits,
pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits);
"[Rc] Frame timestamp = %8d, Frame type =%d, encoding_qp%d, average qp = %3d, max qp = %3d, min qp = %3d, index = %8d,\
iTid = %1d, used = %8d, bitsperframe = %8d, target = %8d, remaingbits = %8d, skipbuffersize = %8d",
(uint32_t)uiTimeStamp,pEncCtx->eSliceType, pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp,pWelsSvcRc->iMaxFrameQp,pWelsSvcRc->iMinFrameQp,
pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits,WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY),
pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits, pWelsSvcRc->iBufferSizeSkip);
}
void RcUpdatePictureQpBits (sWelsEncCtx* pEncCtx, int32_t iCodedBits) {
@@ -872,10 +883,10 @@ void WelsRcPictureInitGom (void* pCtx) {
void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t layer_size) {
void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t iLayerSize) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
int32_t iCodedBits = (layer_size << 3);
int32_t iCodedBits = (iLayerSize << 3);
RcUpdatePictureQpBits (pEncCtx, iCodedBits);
@@ -886,8 +897,6 @@ void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t layer_size) {
}
pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits;
RcTraceFrameBits (pEncCtx);
if (pEncCtx->pSvcParam->bEnableFrameSkip /*&&
pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1*/) {
RcVBufferCalculationSkip (pEncCtx);
@@ -940,13 +949,15 @@ void WelsRcMbInfoUpdateGom (void* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice*
SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[iSliceId];
const int32_t kiComplexityIndex = pSOverRc->iComplexityIndexSlice;
int32_t cur_mb_bits = BsGetBitsPos (bs) - pSOverRc->iBsPosSlice;
pSOverRc->iFrameBitsSlice += cur_mb_bits;
pSOverRc->iGomBitsSlice += cur_mb_bits;
int32_t iCurMbBits = BsGetBitsPos (bs) - pSOverRc->iBsPosSlice;
pSOverRc->iFrameBitsSlice += iCurMbBits;
pSOverRc->iGomBitsSlice += iCurMbBits;
pWelsSvcRc->pGomCost[kiComplexityIndex] += iCostLuma;
if (cur_mb_bits > 0) {
pWelsSvcRc->iMinFrameQp = WELS_MIN(pWelsSvcRc->iMinFrameQp,pCurMb->uiLumaQp);
pWelsSvcRc->iMaxFrameQp = WELS_MAX(pWelsSvcRc->iMaxFrameQp,pCurMb->uiLumaQp);
if (iCurMbBits > 0) {
pSOverRc->iTotalQpSlice += pCurMb->uiLumaQp;
pSOverRc->iTotalMbSlice++;
}
@@ -970,7 +981,7 @@ void WelsRcPictureInitDisable (void* pCtx) {
pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
}
void WelsRcPictureInfoUpdateDisable (void* pCtx, int32_t layer_size) {
void WelsRcPictureInfoUpdateDisable (void* pCtx, int32_t iLayerSize) {
}
void WelsRcMbInitDisable (void* pCtx, SMB* pCurMb, SSlice* pSlice) {
@@ -1011,6 +1022,147 @@ void WelRcPictureInitBufferBasedQp (void* pCtx) {
pEncCtx->iGlobalQp += 2;
pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, iMinQp, MAX_SCREEN_QP);
}
void InitRcModuleScc (void* pCtx) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
pWelsSvcRc->iBaseQp = 30;
pWelsSvcRc->iBufferFullnessSkip = 0;
pWelsSvcRc->uiLastTimeStamp = 0;
pWelsSvcRc->iCost2BitsIntra = INT_MULTIPLY;
pWelsSvcRc->iAvgCost2Bits = INT_MULTIPLY;
}
void WelRcPictureInitScc (void* pCtx) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa);
SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
int32_t iFrameCplx = pVaa->sComplexityScreenParam.iFrameComplexity;
int32_t iBitRate = pDLayerConfig->iSpatialBitrate;// pEncCtx->pSvcParam->target_bitrate;
int32_t iBaseQp = pWelsSvcRc->iBaseQp;
pEncCtx->iGlobalQp = iBaseQp;
int32_t iDeltaQp = 0;
if (pEncCtx->eSliceType == I_SLICE) {
int32_t iTargetBits = iBitRate * 2 - pWelsSvcRc->iBufferFullnessSkip;
iTargetBits = WELS_MAX (1, iTargetBits);
int32_t iQstep = WELS_DIV_ROUND ((((int64_t)iFrameCplx) * pWelsSvcRc->iCost2BitsIntra), iTargetBits);
int32_t iQp = RcConvertQStep2Qp (iQstep);
pEncCtx->iGlobalQp = WELS_CLIP3 (iQp, MIN_IDR_QP, MAX_IDR_QP);
} else {
int32_t iTargetBits = WELS_ROUND (((float)iBitRate / pDLayerConfig->fFrameRate)); //iBitRate / 10;
int32_t iQstep = (int32_t)(WELS_DIV_ROUND64 (iFrameCplx * pWelsSvcRc->iAvgCost2Bits, iTargetBits));
int32_t iQp = RcConvertQStep2Qp (iQstep);
iDeltaQp = iQp - iBaseQp;
if (pWelsSvcRc->iBufferFullnessSkip > iBitRate) {
if (iDeltaQp > 0) {
++iBaseQp;
}
} else if (pWelsSvcRc->iBufferFullnessSkip == 0) {
if (iDeltaQp < 0) {
--iBaseQp;
}
}
if (iDeltaQp >= 6) {
iBaseQp += 3;
} else if ((iDeltaQp <= -6)) {
--iBaseQp;
}
iBaseQp = WELS_CLIP3 (iBaseQp, MIN_IDR_QP, MAX_IDR_QP);
pEncCtx->iGlobalQp = iBaseQp;
if (iDeltaQp < -6) {
pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp - 6, MIN_SCREEN_QP, MAX_SCREEN_QP);
}
if (iDeltaQp > 5) {
if (LARGE_CHANGED_SCENE == pEncCtx->pVaa->eSceneChangeIdc || pWelsSvcRc->iBufferFullnessSkip > 2 * iBitRate
|| iDeltaQp > 10) {
pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp + iDeltaQp, MIN_SCREEN_QP, MAX_SCREEN_QP);
} else if (MEDIUM_CHANGED_SCENE == pEncCtx->pVaa->eSceneChangeIdc || pWelsSvcRc->iBufferFullnessSkip > iBitRate) {
pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp + 5, MIN_SCREEN_QP, MAX_SCREEN_QP);
}
}
pWelsSvcRc->iBaseQp = iBaseQp;
}
pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, "WelRcPictureInitScc iLumaQp = %d\n", pEncCtx->iGlobalQp);
}
void WelsRcFrameDelayJudgeScc (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
if (pDLayerConfig->iSpatialBitrate > pDLayerConfig->iMaxSpatialBitrate)
pDLayerConfig->iSpatialBitrate = pDLayerConfig->iMaxSpatialBitrate;
int32_t iBitRate = pDLayerConfig->iSpatialBitrate;
int32_t iEncTimeInv = (pWelsSvcRc->uiLastTimeStamp == 0) ? 0 : (int32_t) (uiTimeStamp - pWelsSvcRc->uiLastTimeStamp);
int32_t iSentBits = (int32_t) ((double)iBitRate * iEncTimeInv * (1.0E-3) + 0.5);
iSentBits = WELS_MAX (iSentBits, 0);
const int32_t iVbufferThRatio = (eFrameType == videoFrameTypeI
|| eFrameType == videoFrameTypeIDR) ? VIRTUAL_BUFFER_HIGH_TH : VIRTUAL_BUFFER_LOW_TH;
const int32_t iVbufferTh = WELS_DIV_ROUND ((((int64_t)iBitRate) * iVbufferThRatio), INT_MULTIPLY);
pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip);
pWelsSvcRc->bSkipFlag = true;
if (pWelsSvcRc->iBufferFullnessSkip < iVbufferTh) {
pWelsSvcRc->bSkipFlag = false;
}
if (pWelsSvcRc->bSkipFlag) {
pWelsSvcRc->iSkipFrameNum++;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "SCC iSkipFrameNum = %d,buffer = %d,threadhold = %d,bitrate = %d,timestamp=%lld\n", pWelsSvcRc->iSkipFrameNum,pWelsSvcRc->iBufferFullnessSkip,iVbufferTh,iBitRate,uiTimeStamp);
}
pWelsSvcRc->uiLastTimeStamp = uiTimeStamp;
}
void WelsRcDropFrameUpdate (void* pCtx, uint32_t iDropSize) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
pWelsSvcRc->iBufferFullnessSkip -= (int32_t)iDropSize;
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip);
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "[WelsRcDropFrameUpdate:\tdrop:%d\t%d\n", iDropSize,
pWelsSvcRc->iBufferFullnessSkip);
}
void WelsRcPictureInfoUpdateScc (void* pCtx, int32_t iNalSize) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
int32_t iFrameBits = (iNalSize << 3);
pWelsSvcRc->iBufferFullnessSkip += iFrameBits;
SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa);
int32_t iQstep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
int64_t iCost2Bits = WELS_DIV_ROUND64 ((((int64_t)iFrameBits * iQstep)), pVaa->sComplexityScreenParam.iFrameComplexity);
if (pEncCtx->eSliceType == P_SLICE) {
pWelsSvcRc->iAvgCost2Bits = WELS_DIV_ROUND64 ((95 * pWelsSvcRc->iAvgCost2Bits + 5 * iCost2Bits), INT_MULTIPLY);
} else {
pWelsSvcRc->iCost2BitsIntra = WELS_DIV_ROUND64 ((90 * pWelsSvcRc->iCost2BitsIntra + 10 * iCost2Bits), INT_MULTIPLY);
}
}
void WelsRcMbInitScc (void* pCtx, SMB* pCurMb, SSlice* pSlice) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
/* Get delta iQp of this MB */
pCurMb->uiLumaQp = pEncCtx->iGlobalQp;
pCurMb->uiChromaQp = g_kuiChromaQpTable[WELS_CLIP3 (pCurMb->uiLumaQp + pEncCtx->pPps->uiChromaQpIndexOffset, 0, 51)];
}
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsRcFunc* pRcf = &pEncCtx->pFuncList->pfRc;
@@ -1030,9 +1182,24 @@ void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) {
pRcf->pfWelsRcMbInit = WelsRcMbInitDisable;
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable;
break;
case RC_QUALITY_MODE:
case RC_BITRATE_MODE:
case RC_LOW_BW_MODE:
if (pEncCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
pRcf->pfWelsRcPictureInit = WelRcPictureInitScc;
pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudgeScc;
pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateScc;
pRcf->pfWelsRcMbInit = WelsRcMbInitScc;
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable;
InitRcModuleScc (pEncCtx);
} else {
pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom;
pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge;
pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateGom;
pRcf->pfWelsRcMbInit = WelsRcMbInitGom;
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateGom;
}
break;
case RC_QUALITY_MODE:
default:
pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom;
pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge;

View File

@@ -35,25 +35,6 @@
#include "utils.h"
#include "picture_handle.h"
namespace WelsEnc {
/*
* set picture as unreferenced
*/
void SetUnref (SPicture* pRef) {
if (NULL != pRef) {
pRef->iFramePoc = -1;
pRef->iFrameNum = -1;
pRef->uiTemporalId =
pRef->uiSpatialId =
pRef->iLongTermPicNum = -1;
pRef->bIsLongRef = false;
pRef->uiRecieveConfirmed = RECIEVE_FAILED;
pRef->iMarkFrameNum = -1;
pRef->bUsedAsRef = false;
if (NULL != pRef->pScreenBlockFeatureStorage)
pRef->pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = false;
}
}
/*
* reset LTR marking , recovery ,feedback state to default
@@ -87,10 +68,10 @@ void WelsResetRefList (sWelsEncCtx* pCtx) {
for (i = 0; i < MAX_SHORT_REF_COUNT + 1; i++)
pRefList->pShortRefList[i] = NULL;
for (i = 0; i < MAX_LONG_REF_COUNT + 1; i++)
for (i = 0; i < pCtx->pSvcParam->iLTRRefNum + 1; i++)
pRefList->pLongRefList[i] = NULL;
for (i = 0; i < pCtx->pSvcParam->iNumRefFrame + 1; i++)
SetUnref (pRefList->pRef[i]);
pRefList->pRef[i]->SetUnref();
pRefList->uiLongRefCount = 0;
pRefList->uiShortRefCount = 0;
@@ -125,7 +106,7 @@ static void DeleteNonSceneLTR (sWelsEncCtx* pCtx) {
SPicture* pRef = pRefList->pLongRefList[i];
if (pRef != NULL && pRef->bUsedAsRef && pRef->bIsLongRef && (!pRef->bIsSceneLTR) &&
(pCtx->uiTemporalId < pRef->uiTemporalId || pCtx->bCurFrameMarkedAsSceneLtr)) {
SetUnref (pRef);
pRef->SetUnref();
DeleteLTRFromLongList (pCtx, i);
i--;
}
@@ -181,7 +162,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
iMaxFrameNumPlus1) & (FRAME_NUM_EQUAL | FRAME_NUM_SMALLER))) {
WelsLog (pLogCtx, WELS_LOG_WARNING, "LTR ,invalid LTR delete ,long_term_idx = %d , iFrameNum =%d ",
pLongRefList[i]->iLongTermPicNum, pLongRefList[i]->iFrameNum);
SetUnref (pLongRefList[i]);
pLongRefList[i]->SetUnref();
DeleteLTRFromLongList (pCtx, i);
pLtr->bLTRMarkEnable = true;
if (pRefList->uiLongRefCount == 0) {
@@ -194,7 +175,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
&& pLtr->iLTRMarkMode == LTR_DELAY_MARK) {
WelsLog (pLogCtx, WELS_LOG_WARNING, "LTR ,iMarkFrameNum invalid LTR delete ,long_term_idx = %d , iFrameNum =%d ",
pLongRefList[i]->iLongTermPicNum, pLongRefList[i]->iFrameNum);
SetUnref (pLongRefList[i]);
pLongRefList[i]->SetUnref();
DeleteLTRFromLongList (pCtx, i);
pLtr->bLTRMarkEnable = true;
if (pRefList->uiLongRefCount == 0) {
@@ -230,7 +211,7 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
for (j = 0; j < pRefList->uiLongRefCount; j++) {
if (pLongRefList[j]->iLongTermPicNum != pLtr->iCurLtrIdx) {
SetUnref (pLongRefList[j]);
pLongRefList[j]->SetUnref();
DeleteLTRFromLongList (pCtx, j);
}
}
@@ -247,7 +228,7 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
} else if (pLtr->uiLtrMarkState == LTR_MARKING_FAILED) {
for (i = 0; i < pRefList->uiLongRefCount; i++) {
if (pLongRefList[i]->iFrameNum == pLtr->iLtrMarkFbFrameNum) {
SetUnref (pLongRefList[i]);
pLongRefList[i]->SetUnref();
DeleteLTRFromLongList (pCtx, i);
break;
}
@@ -316,7 +297,7 @@ static inline void LTRMarkProcess (sWelsEncCtx* pCtx) {
pLongRefList[0] = pShortRefList[i];
pRefList->uiLongRefCount++;
if (pRefList->uiLongRefCount > pCtx->pSvcParam->iLTRRefNum) {
SetUnref (pRefList->pLongRefList[pRefList->uiLongRefCount - 1]);
pRefList->pLongRefList[pRefList->uiLongRefCount - 1]->SetUnref();
DeleteLTRFromLongList (pCtx, pRefList->uiLongRefCount - 1);
}
DeleteSTRFromShortList (pCtx, i);
@@ -330,14 +311,15 @@ static inline void LTRMarkProcessScreen (sWelsEncCtx* pCtx) {
pCtx->pVaa->uiMarkLongTermPicIdx = pCtx->pDecPic->iLongTermPicNum;
if (pLongRefList[iLtrIdx] != NULL) {
SetUnref (pLongRefList[iLtrIdx]);
pLongRefList[iLtrIdx]->SetUnref();
DeleteLTRFromLongList (pCtx, iLtrIdx);
}
pLongRefList[iLtrIdx] = pCtx->pDecPic;
pRefList->uiLongRefCount++;
}
static inline void PrefetchNextBuffer (sWelsEncCtx* pCtx) {
static void PrefetchNextBuffer (void* pEncCtx) {
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId];
const int32_t kiNumRef = pCtx->pSvcParam->iNumRefFrame;
int32_t i;
@@ -352,7 +334,7 @@ static inline void PrefetchNextBuffer (sWelsEncCtx* pCtx) {
if (pRefList->pNextBuffer == NULL && pRefList->uiShortRefCount > 0) {
pRefList->pNextBuffer = pRefList->pShortRefList[pRefList->uiShortRefCount - 1];
SetUnref (pRefList->pNextBuffer);
pRefList->pNextBuffer->SetUnref();
}
pCtx->pDecPic = pRefList->pNextBuffer;
@@ -416,12 +398,12 @@ bool WelsUpdateRefList (void* pEncCtx) {
}
for (i = pRefList->uiShortRefCount - 1; i > 0; i--) {
SetUnref (pRefList->pShortRefList[i]);
pRefList->pShortRefList[i]->SetUnref();
DeleteSTRFromShortList (pCtx, i);
}
if (pRefList->uiShortRefCount > 0 && (pRefList->pShortRefList[0]->uiTemporalId > 0
|| pRefList->pShortRefList[0]->iFrameNum != pCtx->iFrameNum)) {
SetUnref (pRefList->pShortRefList[0]);
pRefList->pShortRefList[0]->SetUnref();
DeleteSTRFromShortList (pCtx, 0);
}
}
@@ -438,7 +420,7 @@ bool WelsUpdateRefList (void* pEncCtx) {
pCtx->pVaa->uiMarkLongTermPicIdx = 0;
}
}
PrefetchNextBuffer (pCtx);
pCtx->pFuncList->pEndofUpdateRefList (pCtx);
return true;
}
@@ -623,6 +605,21 @@ bool WelsBuildRefList (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx
return (pCtx->iNumRef0 > 0 || pCtx->eSliceType == I_SLICE) ? (true) : (false);
}
static void UpdateBlockStatic (void* pEncCtx) {
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
assert (pCtx->iNumRef0 == 1); //multi-ref is not support yet?
for (int32_t idx = 0; idx < pCtx->iNumRef0; idx++) {
//TODO: we need to re-factor the source picture storage first,
//and then use original frame of the ref to do this calculation for better vaa algo implementation
SPicture* pRef = pCtx->pRefList0[idx];
if (pVaaExt->iVaaBestRefFrameNum != pRef->iFrameNum) {
//re-do the calculation
pCtx->pVpp->UpdateBlockIdcForScreen (pVaaExt->pVaaBestBlockStaticIdc, pRef, pCtx->pEncPic);
}
}
}
/*
* update syntax for reference base related
*/
@@ -679,38 +676,40 @@ void WelsUpdateRefSyntax (sWelsEncCtx* pCtx, const int32_t iPOC, const int32_t u
}
}
static int32_t UpdateSrcPicList (sWelsEncCtx* pCtx) {
static inline void UpdateOriginalPicInfo (SPicture* pOrigPic, SPicture* pReconPic) {
if (!pOrigPic)
return;
pOrigPic->iPictureType = pReconPic->iPictureType;
pOrigPic->iFramePoc = pReconPic->iFramePoc;
pOrigPic->iFrameNum = pReconPic->iFrameNum;
pOrigPic->uiSpatialId = pReconPic->uiSpatialId;
pOrigPic->uiTemporalId = pReconPic->uiTemporalId;
pOrigPic->iLongTermPicNum = pReconPic->iLongTermPicNum;
pOrigPic->bUsedAsRef = pReconPic->bUsedAsRef;
pOrigPic->bIsLongRef = pReconPic->bIsLongRef;
pOrigPic->bIsSceneLTR = pReconPic->bIsSceneLTR;
pOrigPic->iFrameAverageQp = pReconPic->iFrameAverageQp;
}
static void UpdateSrcPicListLosslessScreenRefSelectionWithLtr (void* pEncCtx) {
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
int32_t iDIdx = pCtx->uiDependencyId;
SPicture** pLongRefList = pCtx->ppRefPicListExt[iDIdx]->pLongRefList;
SPicture** pLongRefSrcList = &pCtx->pVpp->m_pSpatialPic[iDIdx][0];
//update info in src list
if (pCtx->pEncPic) {
pCtx->pEncPic->iPictureType = pCtx->pDecPic->iPictureType;
pCtx->pEncPic->iFramePoc = pCtx->pDecPic->iFramePoc;
pCtx->pEncPic->iFrameNum = pCtx->pDecPic->iFrameNum;
pCtx->pEncPic->uiSpatialId = pCtx->pDecPic->uiSpatialId;
pCtx->pEncPic->uiTemporalId = pCtx->pDecPic->uiTemporalId;
pCtx->pEncPic->iLongTermPicNum = pCtx->pDecPic->iLongTermPicNum;
pCtx->pEncPic->bUsedAsRef = pCtx->pDecPic->bUsedAsRef;
pCtx->pEncPic->bIsLongRef = pCtx->pDecPic->bIsLongRef;
pCtx->pEncPic->bIsSceneLTR = pCtx->pDecPic->bIsSceneLTR;
pCtx->pEncPic->iFrameAverageQp = pCtx->pDecPic->iFrameAverageQp;
}
UpdateOriginalPicInfo (pCtx->pEncPic, pCtx->pDecPic);
PrefetchNextBuffer (pCtx);
for (int32_t i = 0; i < MAX_REF_PIC_COUNT; ++i) {
if (NULL == pLongRefSrcList[i + 1] || (NULL != pLongRefList[i] && pLongRefList[i]->bUsedAsRef
&& pLongRefList[i]->bIsLongRef)) {
continue;
} else {
SetUnref (pLongRefSrcList[i + 1]);
}
}
WelsExchangeSpatialPictures (&pCtx->pVpp->m_pSpatialPic[iDIdx][0],
&pCtx->pVpp->m_pSpatialPic[iDIdx][1 + pCtx->pVaa->uiMarkLongTermPicIdx]);
SetUnref (pCtx->pVpp->m_pSpatialPic[iDIdx][0]);
pCtx->pVpp->UpdateSrcListLosslessScreenRefSelectionWithLtr (pCtx->pEncPic, iDIdx, pCtx->pVaa->uiMarkLongTermPicIdx,
pCtx->ppRefPicListExt[iDIdx]->pLongRefList);
}
return 0;
static void UpdateSrcPicList (void* pEncCtx) {
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
int32_t iDIdx = pCtx->uiDependencyId;
//update info in src list
UpdateOriginalPicInfo (pCtx->pEncPic, pCtx->pDecPic);
PrefetchNextBuffer (pCtx);
pCtx->pVpp->UpdateSrcList (pCtx->pEncPic, iDIdx, pCtx->ppRefPicListExt[iDIdx]->pShortRefList,
pCtx->ppRefPicListExt[iDIdx]->uiShortRefCount);
}
bool WelsUpdateRefListScreen (void* pEncCtx) {
@@ -759,7 +758,7 @@ bool WelsUpdateRefListScreen (void* pEncCtx) {
pCtx->pVaa->uiValidLongTermPicIdx = 0;
}
UpdateSrcPicList (pCtx);
pCtx->pFuncList->pEndofUpdateRefList (pCtx);
return true;
}
bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx) {
@@ -805,8 +804,9 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
}
}
}
}
} // end of (int idx = 0; idx < pVaaExt->iNumOfAvailableRef; idx++)
} else {
// dealing with IDR
WelsResetRefList (pCtx); //for IDR, SHOULD reset pRef list.
ResetLtrState (&pCtx->pLtr[pCtx->uiDependencyId]); //SHOULD update it when IDR.
pCtx->pRefList0[0] = NULL;
@@ -814,7 +814,6 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
if (pCtx->iNumRef0 > iNumRef) {
pCtx->iNumRef0 = iNumRef;
}
//TBD info update for md &fme
return (pCtx->iNumRef0 > 0 || pCtx->eSliceType == I_SLICE) ? (true) : (false);
}
@@ -900,20 +899,38 @@ void WelsMarkPicScreen (void* pEncCtx) {
pRefPicMark->SMmcoRef[pRefPicMark->uiMmcoCount].iLongTermFrameIdx = pLtr->iCurLtrIdx;
pRefPicMark->SMmcoRef[pRefPicMark->uiMmcoCount++].iMmcoType = MMCO_LONG;
}
}
return;
}
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, EUsageType eUsageType) {
if (eUsageType == SCREEN_CONTENT_REAL_TIME) {
void DoNothing (void* pointer) {
}
void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bWithLtr, const bool bScreenContent) {
bool bLosslessScreenRefSelectionWithLtr = bWithLtr && bScreenContent;
if (bLosslessScreenRefSelectionWithLtr) {
pFuncList->pBuildRefList = WelsBuildRefListScreen;
pFuncList->pMarkPic = WelsMarkPicScreen;
pFuncList->pUpdateRefList = WelsUpdateRefListScreen;
pFuncList->pEndofUpdateRefList = UpdateSrcPicList;
} else {
pFuncList->pBuildRefList = WelsBuildRefList;
pFuncList->pMarkPic = WelsMarkPic;
pFuncList->pUpdateRefList = WelsUpdateRefList;
pFuncList->pEndofUpdateRefList = PrefetchNextBuffer;
}
pFuncList->pAfterBuildRefList = DoNothing;
if (bScreenContent) {
if (bLosslessScreenRefSelectionWithLtr) {
pFuncList->pEndofUpdateRefList = UpdateSrcPicListLosslessScreenRefSelectionWithLtr;
} else {
pFuncList->pEndofUpdateRefList = UpdateSrcPicList;
pFuncList->pAfterBuildRefList = UpdateBlockStatic;
}
} else {
pFuncList->pEndofUpdateRefList = PrefetchNextBuffer;
}
}
} // namespace WelsEnc

View File

@@ -40,7 +40,7 @@
#include "sample.h"
#include "sad_common.h"
#include "intra_pred_common.h"
#include "mc.h"
#include "cpu_core.h"
@@ -250,8 +250,8 @@ int32_t WelsSampleSadIntra8x8Combined3_c (uint8_t* pDecCb, int32_t iDecStride, u
}
extern void WelsI16x16LumaPredDc_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
extern void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
extern void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
//extern void WelsI16x16LumaPredH_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
//extern void WelsI16x16LumaPredV_c (uint8_t* pPred, uint8_t* pRef, const int32_t iStride);
int32_t WelsSampleSatdIntra16x16Combined3_c (uint8_t* pDec, int32_t iDecStride, uint8_t* pEnc, int32_t iEncStride,
int32_t* pBestMode, int32_t iLambda, uint8_t* pDst) {

View File

@@ -705,6 +705,8 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pExitEncodeEvent[iEventIdx];
pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pUpdateMbListEvent[iEventIdx];
WelsThreadSetName ("OpenH264Enc_CodingSliceThreadProc");
do {
MT_TRACE_LOG (pEncPEncCtx, WELS_LOG_INFO,
"[MT] CodingSliceThreadProc(), try to call WelsMultipleEventsWaitSingleBlocking(pEventsList= %p %p %p), pEncPEncCtx= %p!",

View File

@@ -716,7 +716,7 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const
==
SM_DYN_SLICE);
assert (kiSliceIdx == pCurSlice->uiSliceIdx);
assert (kiSliceIdx == (int) pCurSlice->uiSliceIdx);
if (I_SLICE == pEncCtx->eSliceType) {
pNalHeadExt->bIdrFlag = 1;
@@ -862,10 +862,6 @@ bool DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSli
const bool kbCurMbNotFirstMbOfCurSlice = (pSliceCtx->pOverallMbMap[iCurMbIdx] ==
pSliceCtx->pOverallMbMap[iCurMbIdx - 1]);
const bool kbCurMbNotLastMbOfCurPartition = iCurMbIdx < kiLastMbIdxInPartition;
const bool kbSliceNumNotExceedConstraint = pSliceCtx->iSliceNumInFrame <
pSliceCtx->iMaxSliceNumConstraint; /*tmp choice to avoid complex memory operation, 100520, to be modify*/
const bool kbSliceNumReachConstraint = (pSliceCtx->iSliceNumInFrame ==
pSliceCtx->iMaxSliceNumConstraint);
if (pCurSlice->bDynamicSlicingSliceSizeCtrlFlag)
return false;
@@ -876,45 +872,50 @@ bool DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSli
#endif
uiLen = ((iPosBitOffset >> 3) + ((iPosBitOffset & 0x07) ? 1 : 0));
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
WelsMutexLock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
if ((kbCurMbNotFirstMbOfCurSlice
&& JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx, pSliceCtx->uiSliceSizeConstraint)) /*jump_avoiding_pack_exceed*/
&& kbCurMbNotLastMbOfCurPartition) { //decide to add new pSlice
//DYNAMIC_SLICING_ONE_THREAD: judge jump_avoiding_pack_exceed
if (
((kbCurMbNotFirstMbOfCurSlice
&& JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx, pSliceCtx->uiSliceSizeConstraint)) /*jump_avoiding_pack_exceed*/
&& kbCurMbNotLastMbOfCurPartition) //decide to add new pSlice
&& (kbSliceNumNotExceedConstraint
&& ((pCurSlice->uiSliceIdx + kiActiveThreadsNum) < pSliceCtx->iMaxSliceNumConstraint)
)//able to add new pSlice
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1) {
WelsMutexLock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
//lock the acessing to this variable: pSliceCtx->iSliceNumInFrame
}
const bool kbSliceNumNotExceedConstraint = pSliceCtx->iSliceNumInFrame <
pSliceCtx->iMaxSliceNumConstraint; /*tmp choice to avoid complex memory operation, 100520, to be modify*/
const bool kbSliceIdxNotExceedConstraint = ((int) pCurSlice->uiSliceIdx + kiActiveThreadsNum) <
pSliceCtx->iMaxSliceNumConstraint;
const bool kbSliceNumReachConstraint = (pSliceCtx->iSliceNumInFrame ==
pSliceCtx->iMaxSliceNumConstraint);
) {
//DYNAMIC_SLICING_ONE_THREAD: judge jump_avoiding_pack_exceed
if (kbSliceNumNotExceedConstraint && kbSliceIdxNotExceedConstraint) {//able to add new pSlice
AddSliceBoundary (pEncCtx, pCurSlice, pSliceCtx, pCurMb, iCurMbIdx, kiLastMbIdxInPartition);
AddSliceBoundary (pEncCtx, pCurSlice, pSliceCtx, pCurMb, iCurMbIdx, kiLastMbIdxInPartition);
++ pSliceCtx->iSliceNumInFrame;
++ pSliceCtx->iSliceNumInFrame;
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1) {
WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
}
return true;
}
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1) {
WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
}
return true;
if ((kbSliceNumReachConstraint || !kbSliceIdxNotExceedConstraint)
&& kbCurMbNotLastMbOfCurPartition
&& JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx,
pSliceCtx->uiSliceSizeConstraint - ((kiLastMbIdxInPartition - iCurMbIdx) <<
(pCurSlice->uiAssumeLog2BytePerMb) //assume each MB consumes these byte under largest QP
))
) {
// to minimize the impact under the risk of exceeding the size constraint when pSlice num reaches constraint
pCurSlice->bDynamicSlicingSliceSizeCtrlFlag = true;
}
}
if (
(kbSliceNumReachConstraint
|| ((pCurSlice->uiSliceIdx + kiActiveThreadsNum) >= pSliceCtx->iMaxSliceNumConstraint)
)
&& ((JUMPPACKETSIZE_JUDGE (uiLen, iCurMbIdx,
pSliceCtx->uiSliceSizeConstraint - ((kiLastMbIdxInPartition - iCurMbIdx) <<
(pCurSlice->uiAssumeLog2BytePerMb) /* assume each MB consumes two byte under largest QP */)))
&& kbCurMbNotLastMbOfCurPartition) //risk of exceeding the size constraint when pSlice num reaches constraint
) {
pCurSlice->bDynamicSlicingSliceSizeCtrlFlag = true;
}
if (pEncCtx->pSvcParam->iMultipleThreadIdc > 1)
WelsMutexUnlock (&pEncCtx->pSliceThreading->mutexSliceNumUpdate);
return false;
}

View File

@@ -208,7 +208,7 @@ void WelsSpatialWriteSubMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurM
}
}
int32_t CheckBitstreamBuffer (const uint8_t kuiSliceIdx, sWelsEncCtx* pEncCtx, SBitStringAux* pBs) {
int32_t CheckBitstreamBuffer (const uint32_t kuiSliceIdx, sWelsEncCtx* pEncCtx, SBitStringAux* pBs) {
const intX_t iLeftLength = pBs->pBufEnd - pBs->pBufPtr - 1;
assert (iLeftLength > 0);

View File

@@ -38,7 +38,6 @@
namespace WelsEnc {
#define WelsSafeDelete(p) if(p){ delete (p); (p) = NULL; }
//***** entry API declaration ************************************************************************//
@@ -87,7 +86,7 @@ CWelsPreProcess::~CWelsPreProcess() {
int32_t CWelsPreProcess::WelsPreprocessCreate() {
if (m_pInterfaceVp == NULL) {
CreateVpInterface ((void**) &m_pInterfaceVp, WELSVP_INTERFACE_VERION);
WelsCreateVpInterface ((void**) &m_pInterfaceVp, WELSVP_INTERFACE_VERION);
if (!m_pInterfaceVp)
goto exit;
} else
@@ -101,7 +100,7 @@ exit:
}
int32_t CWelsPreProcess::WelsPreprocessDestroy() {
DestroyVpInterface (m_pInterfaceVp, WELSVP_INTERFACE_VERION);
WelsDestroyVpInterface (m_pInterfaceVp, WELSVP_INTERFACE_VERION);
m_pInterfaceVp = NULL;
return 0;
@@ -186,6 +185,8 @@ int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePi
if (WelsPreprocessReset (pCtx) != 0)
return -1;
m_iAvaliableRefInSpatialPicList = pSvcParam->iNumRefFrame;
m_bInitDone = true;
}
@@ -794,9 +795,9 @@ void CWelsPreProcess::AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCu
if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) {
iComplexityAnalysisMode = FRAME_SAD;
} else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
} else if (pSvcParam->iRCMode == RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
iComplexityAnalysisMode = GOM_SAD;
} else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
} else if (pSvcParam->iRCMode == RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
iComplexityAnalysisMode = GOM_VAR;
} else {
return;
@@ -859,10 +860,10 @@ void CWelsPreProcess::InitPixMap (const SPicture* pPicture, SPixMap* pPixMap) {
pPixMap->eFormat = VIDEO_FORMAT_I420;
}
void CWelsPreProcess::GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurTid, const int32_t iClosestLtrFrameNum,
void CWelsPreProcess::GetAvailableRefListLosslessScreenRefSelection (SPicture** pSrcPicList, uint8_t iCurTid,
const int32_t iClosestLtrFrameNum,
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum) {
SWelsSvcCodingParam* pSvcParam = m_pEncCtx->pSvcParam;
const int32_t iSourcePicNum = pSvcParam->iNumRefFrame;
const int32_t iSourcePicNum = m_iAvaliableRefInSpatialPicList;
if (0 >= iSourcePicNum) {
iAvailableRefNum = 0;
iAvailableSceneRefNum = 0;
@@ -908,6 +909,38 @@ void CWelsPreProcess::GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurT
}
void CWelsPreProcess::GetAvailableRefList (SPicture** pSrcPicList, uint8_t iCurTid, const int32_t iClosestLtrFrameNum,
SRefInfoParam* pAvailableRefList, int32_t& iAvailableRefNum, int32_t& iAvailableSceneRefNum) {
const int32_t iSourcePicNum = m_iAvaliableRefInSpatialPicList;
if (0 >= iSourcePicNum) {
iAvailableRefNum = 0;
iAvailableSceneRefNum = 0;
return ;
}
SPicture* pRefPic = NULL;
uint8_t uiRefTid = 0;
iAvailableRefNum = 0;
iAvailableSceneRefNum = 0;
//the saving order will be depend on pSrcPicList
//TODO: use a frame_idx to find the closer ref in time distance, and correctly sort the ref list
for (int32_t i = iSourcePicNum - 1; i >= 0; --i) {
pRefPic = pSrcPicList[i];
if (NULL == pRefPic || !pRefPic->bUsedAsRef) {
continue;
}
uiRefTid = pRefPic->uiTemporalId;
if (uiRefTid <= iCurTid) {
pAvailableRefList[iAvailableRefNum].pRefPicture = pRefPic;
pAvailableRefList[iAvailableRefNum].iSrcListIdx = i + 1; //in SrcList, the idx 0 is reserved for CurPic
iAvailableRefNum ++;
}
}
}
void CWelsPreProcess::InitRefJudgement (SRefJudgement* pRefJudgement) {
pRefJudgement->iMinFrameComplexity = INT_MAX;
pRefJudgement->iMinFrameComplexity08 = INT_MAX;
@@ -932,8 +965,7 @@ void CWelsPreProcess::SaveBestRefToJudgement (const int32_t iRefPictureAvQP, con
}
void CWelsPreProcess::SaveBestRefToLocal (SRefInfoParam* pRefPicInfo, const SSceneChangeResult& sSceneChangeResult,
SRefInfoParam* pRefSaved) {
pRefSaved->iSrcListIdx = pRefPicInfo->iSrcListIdx;
pRefSaved->bSceneLtrFlag = pRefPicInfo->bSceneLtrFlag;
memcpy (pRefSaved, pRefPicInfo, sizeof (SRefInfoParam));
pRefSaved->pBestBlockStaticIdc = sSceneChangeResult.pStaticBlockIdc;
}
@@ -988,8 +1020,14 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
const uint8_t iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[m_pEncCtx->sSpatialIndexMap[0].iDid],
m_pEncCtx->iCodingIndex, pSvcParam->uiGopSize);
const int32_t iClosestLtrFrameNum = pCtx->pLtr[iTargetDid].iLastLtrIdx[iCurTid];//TBD
GetAvailableRefList (pSrcPicList, iCurTid, iClosestLtrFrameNum, &sAvailableRefList[0], iAvailableRefNum,
iAvailableSceneRefNum);
if (pSvcParam->bEnableLongTermReference) {
GetAvailableRefListLosslessScreenRefSelection (pSrcPicList, iCurTid, iClosestLtrFrameNum, &sAvailableRefList[0],
iAvailableRefNum,
iAvailableSceneRefNum);
} else {
GetAvailableRefList (pSrcPicList, iCurTid, iClosestLtrFrameNum, &sAvailableRefList[0], iAvailableRefNum,
iAvailableSceneRefNum);
}
//after this build, pAvailableRefList[idx].iSrcListIdx is the idx of the ref in h->spatial_pic
if (0 == iAvailableRefNum) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "SceneChangeDetect() iAvailableRefNum=0 but not I.");
@@ -1038,12 +1076,12 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
const int32_t iSceneDetectIdc = sSceneChangeResult.eSceneChangeIdc;
const int32_t iMotionBlockNum = sSceneChangeResult.iMotionBlockNum;
const bool bCurRefIsLtr = pRefPic->bIsSceneLTR;
const bool bCurRefIsSceneLtr = pRefPic->bIsSceneLTR;
const int32_t iRefPicAvQP = pRefPic->iFrameAverageQp;
//for scene change detection
iNumOfLargeChange += (static_cast<int32_t> (LARGE_CHANGED_SCENE == iSceneDetectIdc));
iNumOfMediumChangeToLtr += (static_cast<int32_t> ((bCurRefIsLtr) && (iSceneDetectIdc != SIMILAR_SCENE)));
iNumOfMediumChangeToLtr += (static_cast<int32_t> ((bCurRefIsSceneLtr) && (iSceneDetectIdc != SIMILAR_SCENE)));
//for reference selection
//this judge can only be saved when iAvailableRefNum==1, which is very limit
@@ -1052,7 +1090,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sLtrJudgement);
SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sLtrSaved);
}
if (bCurRefIsLtr && JudgeBestRef (pRefPic, sSceneLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) {
if (bCurRefIsSceneLtr && JudgeBestRef (pRefPic, sSceneLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) {
SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sSceneLtrJudgement);
SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sSceneLtrSaved);
}
@@ -1075,6 +1113,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
pCtx->iCodingIndex);
SaveBestRefToVaa (sLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[0]));
pVaaExt->iVaaBestRefFrameNum = sLtrSaved.pRefPicture->iFrameNum;
pVaaExt->pVaaBestBlockStaticIdc = sLtrSaved.pBestBlockStaticIdc;
if (0 == iAvailableSceneRefNum) {
@@ -1120,6 +1159,83 @@ void CWelsPreProcess::Padding (uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV,
}
int32_t CWelsPreProcess::UpdateBlockIdcForScreen (uint8_t* pCurBlockStaticPointer, const SPicture* kpRefPic,
const SPicture* kpSrcPic) {
int32_t iSceneChangeMethodIdx = METHOD_SCENE_CHANGE_DETECTION_SCREEN;
SSceneChangeResult sSceneChangeResult = {SIMILAR_SCENE, 0, 0, NULL};
sSceneChangeResult.pStaticBlockIdc = pCurBlockStaticPointer;
sSceneChangeResult.sScrollResult.bScrollDetectFlag = false;
SPixMap sSrcMap = { { 0 } };
SPixMap sRefMap = { { 0 } };
InitPixMap (kpSrcPic, &sSrcMap);
InitPixMap (kpRefPic, &sRefMap);
m_pInterfaceVp->Set (iSceneChangeMethodIdx, (void*) (&sSceneChangeResult));
int32_t iRet = m_pInterfaceVp->Process (iSceneChangeMethodIdx, &sSrcMap, &sRefMap);
if (iRet == 0) {
m_pInterfaceVp->Get (iSceneChangeMethodIdx, (void*)&sSceneChangeResult);
return 0;
}
return iRet;
}
/*!
* \brief exchange two picture pData planes
* \param ppPic1 picture pointer to picture 1
* \param ppPic2 picture pointer to picture 2
* \return none
*/
void CWelsPreProcess::WelsExchangeSpatialPictures (SPicture** ppPic1, SPicture** ppPic2) {
SPicture* tmp = *ppPic1;
assert (*ppPic1 != *ppPic2);
*ppPic1 = *ppPic2;
*ppPic2 = tmp;
}
void CWelsPreProcess::UpdateSrcListLosslessScreenRefSelectionWithLtr (SPicture* pCurPicture, const int32_t kiCurDid,
const int32_t kuiMarkLongTermPicIdx, SPicture** pLongRefList) {
SPicture** pLongRefSrcList = &m_pSpatialPic[kiCurDid][0];
for (int32_t i = 0; i < MAX_REF_PIC_COUNT; ++i) {
if (NULL == pLongRefSrcList[i + 1] || (NULL != pLongRefList[i] && pLongRefList[i]->bUsedAsRef
&& pLongRefList[i]->bIsLongRef)) {
continue;
} else {
pLongRefSrcList[i + 1]->SetUnref();
}
}
WelsExchangeSpatialPictures (&m_pSpatialPic[kiCurDid][0],
&m_pSpatialPic[kiCurDid][1 + kuiMarkLongTermPicIdx]);
m_iAvaliableRefInSpatialPicList = MAX_REF_PIC_COUNT;
(GetCurrentFrameFromOrigList (kiCurDid))->SetUnref();
}
void CWelsPreProcess::UpdateSrcList (SPicture* pCurPicture, const int32_t kiCurDid, SPicture** pShortRefList,
const uint32_t kuiShortRefCount) {
SPicture** pRefSrcList = &m_pSpatialPic[kiCurDid][0];
//pRefSrcList[0] is for current frame
if (pCurPicture->bUsedAsRef || pCurPicture->bIsLongRef) {
if (pCurPicture->iPictureType == P_SLICE && pCurPicture->uiTemporalId != 0) {
for (int iRefIdx = kuiShortRefCount - 1; iRefIdx >= 0; --iRefIdx) {
WelsExchangeSpatialPictures (&pRefSrcList[iRefIdx + 1],
&pRefSrcList[iRefIdx]);
}
m_iAvaliableRefInSpatialPicList = kuiShortRefCount;
} else {
WelsExchangeSpatialPictures (&pRefSrcList[0], &pRefSrcList[1]);
for (int32_t i = MAX_SHORT_REF_COUNT - 1; i > 0 ; --i) {
if (pRefSrcList[i + 1] != NULL) {
pRefSrcList[i + 1]->SetUnref();
}
}
m_iAvaliableRefInSpatialPicList = 1;
}
}
(GetCurrentFrameFromOrigList (kiCurDid))->SetUnref();
}
//TODO: may opti later
//TODO: not use this func?
void* WelsMemcpy (void* dst, const void* kpSrc, uint32_t uiSize) {

View File

@@ -306,74 +306,6 @@ get_i16x16_luma_pred_plane_sse2_1:
pop r3
ret
;***********************************************************************
; void WelsI16x16LumaPredH_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
;***********************************************************************
%macro SSE2_PRED_H_16X16_ONE_LINE 0
add r0, 16
add r1, r2
movzx r3, byte [r1]
SSE2_Copy16Times xmm0, r3d
movdqa [r0], xmm0
%endmacro
WELS_EXTERN WelsI16x16LumaPredH_sse2
push r3
%assign push_num 1
LOAD_3_PARA
SIGN_EXTENSION r2, r2d
dec r1
movzx r3, byte [r1]
SSE2_Copy16Times xmm0, r3d
movdqa [r0], xmm0
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
SSE2_PRED_H_16X16_ONE_LINE
pop r3
ret
;***********************************************************************
; void WelsI16x16LumaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
;***********************************************************************
WELS_EXTERN WelsI16x16LumaPredV_sse2
%assign push_num 0
LOAD_3_PARA
SIGN_EXTENSION r2, r2d
sub r1, r2
movdqa xmm0, [r1]
movdqa [r0], xmm0
movdqa [r0+10h], xmm0
movdqa [r0+20h], xmm0
movdqa [r0+30h], xmm0
movdqa [r0+40h], xmm0
movdqa [r0+50h], xmm0
movdqa [r0+60h], xmm0
movdqa [r0+70h], xmm0
movdqa [r0+80h], xmm0
movdqa [r0+90h], xmm0
movdqa [r0+160], xmm0
movdqa [r0+176], xmm0
movdqa [r0+192], xmm0
movdqa [r0+208], xmm0
movdqa [r0+224], xmm0
movdqa [r0+240], xmm0
ret
;***********************************************************************
; void WelsIChromaPredPlane_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride);
;***********************************************************************

View File

@@ -102,6 +102,8 @@ class CWelsH264SVCEncoder : public ISVCEncoder {
void CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelIdc);
void CheckReferenceNumSetting (int32_t iNumRef);
void TraceParamInfo(SEncParamExt *pParam);
void UpdateStatistics(const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType, const int64_t kiCurrentFrameMs);
sWelsEncCtx* m_pEncContext;
welsCodecTrace* m_pWelsTrace;

View File

@@ -42,6 +42,7 @@
#include "ref_list_mgr_svc.h"
#include <time.h>
#include <measure_time.h>
#if defined(_WIN32) /*&& defined(_DEBUG)*/
#include <windows.h>
@@ -207,6 +208,7 @@ int CWelsH264SVCEncoder::Initialize (const SEncParamBase* argv) {
if (sConfig.ParamBaseTranscode (*argv)) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
"CWelsH264SVCEncoder::Initialize(), parameter_translation failed.");
TraceParamInfo (&sConfig);
Uninitialize();
return cmInitParaError;
}
@@ -230,6 +232,7 @@ int CWelsH264SVCEncoder::InitializeExt (const SEncParamExt* argv) {
if (sConfig.ParamTranscode (*argv)) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
"CWelsH264SVCEncoder::InitializeExt(), parameter_translation failed.");
TraceParamInfo (&sConfig);
Uninitialize();
return cmInitParaError;
}
@@ -325,7 +328,7 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
if (pCfg->iNumRefFrame == AUTO_REF_PIC_COUNT) {
pCfg->iNumRefFrame = ((pCfg->uiGopSize >> 1) > 1) ? ((pCfg->uiGopSize >> 1) + pCfg->iLTRRefNum) :
(MIN_REF_PIC_COUNT + pCfg->iLTRRefNum);
pCfg->iNumRefFrame = WELS_CLIP3 (pCfg->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
pCfg->iNumRefFrame = WELS_CLIP3 (pCfg->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA);
}
}
if (pCfg->iNumRefFrame > pCfg->iMaxNumRefFrame)
@@ -346,6 +349,10 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
TraceParamInfo (pCfg);
if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG,
"Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d",
pCfg->iUsageType, pCfg->iPicWidth, pCfg->iPicHeight, pCfg->fMaxFrameRate, pCfg->iTemporalLayerNum,
pCfg->iSpatialLayerNum);
Uninitialize();
return cmInitParaError;
}
@@ -410,8 +417,10 @@ int CWelsH264SVCEncoder::EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSIn
}
int CWelsH264SVCEncoder::EncodeFrameInternal (const SSourcePicture* pSrcPic, SFrameBSInfo* pBsInfo) {
int CWelsH264SVCEncoder ::EncodeFrameInternal (const SSourcePicture* pSrcPic, SFrameBSInfo* pBsInfo) {
const int64_t kiBeforeFrameUs = WelsTime();
const int32_t kiEncoderReturn = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPic);
const int64_t kiCurrentFrameMs = (WelsTime() - kiBeforeFrameUs) / 1000;
if (kiEncoderReturn == ENC_RETURN_MEMALLOCERR) {
WelsUninitEncoderExt (&m_pEncContext);
@@ -421,6 +430,9 @@ int CWelsH264SVCEncoder::EncodeFrameInternal (const SSourcePicture* pSrcPic, SF
kiEncoderReturn);
return cmUnkonwReason;
}
UpdateStatistics (pSrcPic->uiTimeStamp, pBsInfo->eFrameType, kiCurrentFrameMs);
///////////////////for test
#ifdef OUTPUT_BIT_STREAM
if (pBsInfo->eFrameType != videoFrameTypeInvalid && pBsInfo->eFrameType != videoFrameTypeSkip) {
@@ -519,8 +531,10 @@ void CWelsH264SVCEncoder::CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelId
}
}
void CWelsH264SVCEncoder::CheckReferenceNumSetting (int32_t iNumRef) {
int32_t iRefUpperBound = (m_pEncContext->pSvcParam->iUsageType == CAMERA_VIDEO_REAL_TIME) ?
MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA : MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN;
m_pEncContext->pSvcParam->iNumRefFrame = iNumRef;
if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > MAX_REFERENCE_PICTURE_COUNT_NUM)) {
if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > iRefUpperBound)) {
m_pEncContext->pSvcParam->iNumRefFrame = AUTO_REF_PIC_COUNT;
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
"doesn't support the number of reference frame(%d) change to auto select mode", iNumRef);
@@ -578,6 +592,64 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
++ i;
}
}
void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType,
const int64_t kiCurrentFrameMs) {
SEncoderStatistics* pStatistics = & (m_pEncContext->sEncoderStatistics);
int32_t iMaxDid = m_pEncContext->pSvcParam->iSpatialLayerNum - 1;
if ((0 != pStatistics->uiWidth && 0 != pStatistics->uiHeight)
&& (pStatistics->uiWidth != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth
|| pStatistics->uiHeight != (unsigned int) m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight)) {
pStatistics->uiResolutionChangeTimes ++;
}
pStatistics->uiWidth = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth;
pStatistics->uiHeight = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight;
int32_t iProcessedFrameCount = pStatistics->uiInputFrameCount - pStatistics->uiSkippedFrameCount;
const bool kbCurrentFrameSkipped = (videoFrameTypeSkip == eFrameType);
if (!kbCurrentFrameSkipped && (iProcessedFrameCount + 1) != 0) {
pStatistics->fAverageFrameSpeedInMs = (iProcessedFrameCount * pStatistics->fAverageFrameSpeedInMs +
kiCurrentFrameMs) / (iProcessedFrameCount + 1);
}
pStatistics->uiInputFrameCount ++;
pStatistics->uiSkippedFrameCount += (kbCurrentFrameSkipped ? 1 : 0);
// rate control related
if (0 != m_pEncContext->uiStartTimestamp && kiCurrentFrameTs > m_pEncContext->uiStartTimestamp + 800) {
pStatistics->fAverageFrameRate = pStatistics->uiInputFrameCount * 1000 /
(kiCurrentFrameTs - m_pEncContext->uiStartTimestamp);
} else {
m_pEncContext->uiStartTimestamp = kiCurrentFrameTs;
}
pStatistics->fLatestFrameRate = m_pEncContext->pWelsSvcRc->fLatestFrameRate; //TODO: finish the calculation in RC
pStatistics->uiBitRate = m_pEncContext->pWelsSvcRc->iActualBitRate; //TODO: finish the calculation in RC
if (videoFrameTypeIDR == eFrameType || videoFrameTypeI == eFrameType) {
pStatistics->uiIDRSentNum ++;
}
if (m_pEncContext->pLtr->bLTRMarkingFlag) {
pStatistics->uiLTRSentNum ++;
}
//TODO: update uiIDRReqNum in forceIDR
if (m_pEncContext->iStatisticsLogInterval > 0) {
if (WELS_ABS (kiCurrentFrameTs - m_pEncContext->iLastStatisticsLogTs) > m_pEncContext->iStatisticsLogInterval) {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
"EncoderStatistics: %dx%d, SpeedInMs: %f, AverFrameRate=%f, LastFrameRate=NA, LatestBitRate=NA, uiInputFrameCount=%d, uiSkippedFrameCount=%d, uiResolutionChangeTimes=%d, uIDRReqNum=%d, uIDRSentNum=%d, uLTRSentNum=NA",
pStatistics->uiWidth, pStatistics->uiHeight,
pStatistics->fAverageFrameSpeedInMs, pStatistics->fAverageFrameRate,
pStatistics->uiInputFrameCount, pStatistics->uiSkippedFrameCount,
pStatistics->uiResolutionChangeTimes, pStatistics->uiIDRSentNum, pStatistics->uiLTRSentNum);
//TODO: the following statistics will be calculated and added later
//pStatistics->fLatestFrameRate, pStatistics->uiBitRate,
//pStatistics->uiIDRReqNum,
m_pEncContext->iLastStatisticsLogTs = kiCurrentFrameTs;
}
}
}
/************************************************************************
* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
************************************************************************/
@@ -662,6 +734,11 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
if (sConfig.iSpatialLayerNum < 1) {
return cmInitParaError;
}
if (sConfig.DetermineTemporalSettings()) {
return cmInitParaError;
}
/* New configuration available here */
iTargetWidth = sConfig.iPicWidth;
iTargetHeight = sConfig.iPicHeight;
if (m_iMaxPicWidth != iTargetWidth
@@ -675,11 +752,10 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
m_uiCountFrameNum, m_iCspInternal);
#endif//REC_FRAME_COUNT
/* New configuration available here */
sConfig.DetermineTemporalSettings();
/* Check every field whether there is new request for memory block changed or else, Oct. 24, 2008 */
WelsEncoderParamAdjust (&m_pEncContext, &sConfig);
if (WelsEncoderParamAdjust (&m_pEncContext, &sConfig)) {
return cmInitParaError;
}
}
break;
case ENCODER_OPTION_FRAME_RATE: { // Maximal input frame rate
@@ -809,7 +885,9 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
break;
case ENCODER_OPTION_LTR: {
SLTRConfig* pLTRValue = ((SLTRConfig*) (pOption));
WelsEncoderApplyLTR (&m_pWelsTrace->m_sLogCtx, &m_pEncContext, pLTRValue);
if (WelsEncoderApplyLTR (&m_pWelsTrace->m_sLogCtx, &m_pEncContext, pLTRValue)) {
return cmInitParaError;
}
}
break;
case ENCODER_OPTION_ENABLE_SSEI: {
@@ -905,10 +983,25 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
}
break;
case ENCODER_OPTION_COMPLEXITY: {
int32_t iValue = * ((int32_t*)pOption);
int32_t iValue = * (static_cast<int32_t*> (pOption));
m_pEncContext->pSvcParam->iComplexityMode = (ECOMPLEXITY_MODE)iValue;
}
break;
case ENCODER_OPTION_GET_STATISTICS: {
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_GET_STATISTICS: this option is get-only!");
}
break;
case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: {
int32_t iValue = * (static_cast<int32_t*> (pOption));
m_pEncContext->iStatisticsLogInterval = iValue;
}
break;
case ENCODER_OPTION_IS_LOSSLESS_LINK: {
bool bValue = * (static_cast<bool*> (pOption));
m_pEncContext->pSvcParam->bIsLosslessLink = bValue;
}
break;
default:
return cmInitParaError;
}
@@ -1011,6 +1104,30 @@ int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) {
}
}
break;
case ENCODER_OPTION_GET_STATISTICS: {
SEncoderStatistics* pStatistics = (static_cast<SEncoderStatistics*> (pOption));
pStatistics->uiWidth = m_pEncContext->sEncoderStatistics.uiWidth;
pStatistics->uiHeight = m_pEncContext->sEncoderStatistics.uiHeight;
pStatistics->fAverageFrameSpeedInMs = m_pEncContext->sEncoderStatistics.fAverageFrameSpeedInMs;
// rate control related
pStatistics->fAverageFrameRate = m_pEncContext->sEncoderStatistics.fAverageFrameRate;
pStatistics->fLatestFrameRate = m_pEncContext->sEncoderStatistics.fLatestFrameRate;
pStatistics->uiBitRate = m_pEncContext->sEncoderStatistics.uiBitRate;
pStatistics->uiInputFrameCount = m_pEncContext->sEncoderStatistics.uiInputFrameCount;
pStatistics->uiSkippedFrameCount = m_pEncContext->sEncoderStatistics.uiSkippedFrameCount;
pStatistics->uiResolutionChangeTimes = m_pEncContext->sEncoderStatistics.uiResolutionChangeTimes;
pStatistics->uiIDRReqNum = m_pEncContext->sEncoderStatistics.uiIDRReqNum;
pStatistics->uiIDRSentNum = m_pEncContext->sEncoderStatistics.uiIDRSentNum;
pStatistics->uiLTRSentNum = m_pEncContext->sEncoderStatistics.uiLTRSentNum;
}
break;
case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: {
* ((int32_t*)pOption) = m_pEncContext->iStatisticsLogInterval;
}
break;
case ENCODER_OPTION_COMPLEXITY: {
* ((int32_t*)pOption) = m_pEncContext->pSvcParam->iComplexityMode;
}

View File

@@ -32,7 +32,6 @@ ENCODER_CPP_SRCS=\
ENCODER_OBJS += $(ENCODER_CPP_SRCS:.cpp=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
ENCODER_ASM_SRCS=\
$(ENCODER_SRCDIR)/core/x86/coeff.asm\
$(ENCODER_SRCDIR)/core/x86/dct.asm\
@@ -43,10 +42,12 @@ ENCODER_ASM_SRCS=\
$(ENCODER_SRCDIR)/core/x86/sample_sc.asm\
$(ENCODER_SRCDIR)/core/x86/score.asm\
ENCODER_OBJS += $(ENCODER_ASM_SRCS:.asm=.$(OBJ))
ENCODER_OBJSASM += $(ENCODER_ASM_SRCS:.asm=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
ENCODER_OBJS += $(ENCODER_OBJSASM)
endif
OBJS += $(ENCODER_OBJSASM)
ifeq ($(ASM_ARCH), arm)
ENCODER_ASM_ARM_SRCS=\
$(ENCODER_SRCDIR)/core/arm/intra_pred_neon.S\
$(ENCODER_SRCDIR)/core/arm/intra_pred_sad_3_opt_neon.S\
@@ -55,10 +56,12 @@ ENCODER_ASM_ARM_SRCS=\
$(ENCODER_SRCDIR)/core/arm/reconstruct_neon.S\
$(ENCODER_SRCDIR)/core/arm/svc_motion_estimation.S\
ENCODER_OBJS += $(ENCODER_ASM_ARM_SRCS:.S=.$(OBJ))
ENCODER_OBJSARM += $(ENCODER_ASM_ARM_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm)
ENCODER_OBJS += $(ENCODER_OBJSARM)
endif
OBJS += $(ENCODER_OBJSARM)
ifeq ($(ASM_ARCH), arm64)
ENCODER_ASM_ARM64_SRCS=\
$(ENCODER_SRCDIR)/core/arm64/intra_pred_aarch64_neon.S\
$(ENCODER_SRCDIR)/core/arm64/intra_pred_sad_3_opt_aarch64_neon.S\
@@ -67,10 +70,14 @@ ENCODER_ASM_ARM64_SRCS=\
$(ENCODER_SRCDIR)/core/arm64/reconstruct_aarch64_neon.S\
$(ENCODER_SRCDIR)/core/arm64/svc_motion_estimation_aarch64_neon.S\
ENCODER_OBJS += $(ENCODER_ASM_ARM64_SRCS:.S=.$(OBJ))
ENCODER_OBJSARM64 += $(ENCODER_ASM_ARM64_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm64)
ENCODER_OBJS += $(ENCODER_OBJSARM64)
endif
OBJS += $(ENCODER_OBJSARM64)
OBJS += $(ENCODER_OBJS)
$(ENCODER_SRCDIR)/%.$(OBJ): $(ENCODER_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(ENCODER_CFLAGS) $(ENCODER_INCLUDES) -c $(CXX_O) $<

View File

@@ -358,11 +358,11 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\..\src\common\common.cpp"
RelativePath="..\..\..\common\src\cpu.cpp"
>
</File>
<File
RelativePath="..\..\..\common\src\cpu.cpp"
RelativePath="..\..\..\common\src\intra_pred_common.cpp"
>
</File>
<File
@@ -425,6 +425,10 @@
RelativePath="..\..\..\common\inc\cpu.h"
>
</File>
<File
RelativePath="..\..\..\common\inc\intra_pred_common.h"
>
</File>
<File
RelativePath="..\..\src\common\memory.h"
>
@@ -461,7 +465,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -479,7 +483,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -501,7 +505,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -519,7 +523,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -574,14 +578,14 @@
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\common\x86\satd_sad.asm"
RelativePath="..\..\..\common\x86\intra_pred_com.asm"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
@@ -599,7 +603,47 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\common\x86\satd_sad.asm"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win64 -DWIN64 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="nasm -I$(InputDir) -I$(InputDir)/../../../common/x86/ -f win32 -DPREFIX -DX86_32 -o $(IntDir)\$(InputName).obj $(InputPath)&#x0D;&#x0A;"
Outputs="$(IntDir)\$(InputName).obj"
/>
</FileConfiguration>

View File

@@ -142,14 +142,14 @@ typedef enum {
typedef enum {
SIMILAR_SCENE, //similar scene
MEDIUM_CHANGED_SCENE, //medium changed scene
LARGE_CHANGED_SCENE, //large changed scene
LARGE_CHANGED_SCENE //large changed scene
} ESceneChangeIdc;
typedef enum {
NO_STATIC, // motion block
COLLOCATED_STATIC, // collocated static block
SCROLLED_STATIC, // scrolled static block
BLOCK_STATIC_IDC_ALL,
BLOCK_STATIC_IDC_ALL
} EStaticBlockIdc;
typedef struct {
@@ -195,7 +195,7 @@ typedef struct {
typedef enum {
AQ_QUALITY_MODE, //Quality mode
AQ_BITRATE_MODE, //Bitrate mode
AQ_BITRATE_MODE //Bitrate mode
} EAQModes;
typedef struct {
@@ -300,8 +300,8 @@ class IWelsVP {
#endif
WELSVP_EXTERNC_BEGIN
EResult CreateVpInterface (void** ppCtx, int iVersion /*= WELSVP_INTERFACE_VERION*/);
EResult DestroyVpInterface (void* pCtx , int iVersion /*= WELSVP_INTERFACE_VERION*/);
EResult WelsCreateVpInterface (void** ppCtx, int iVersion /*= WELSVP_INTERFACE_VERION*/);
EResult WelsDestroyVpInterface (void* pCtx , int iVersion /*= WELSVP_INTERFACE_VERION*/);
WELSVP_EXTERNC_END
//////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -57,7 +57,7 @@ CBackgroundDetection::CBackgroundDetection (int32_t iCpuFlag) {
}
CBackgroundDetection::~CBackgroundDetection() {
FreeOUArrayMemory();
WelsFree (m_BgdParam.pOU_array);
}
EResult CBackgroundDetection::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) {
@@ -80,7 +80,7 @@ EResult CBackgroundDetection::Process (int32_t iType, SPixMap* pSrcPixMap, SPixM
int32_t iCurFrameSize = m_BgdParam.iBgdWidth * m_BgdParam.iBgdHeight;
if (m_BgdParam.pOU_array == NULL || iCurFrameSize > m_iLargestFrameSize) {
FreeOUArrayMemory();
WelsFree (m_BgdParam.pOU_array);
m_BgdParam.pOU_array = AllocateOUArrayMemory (m_BgdParam.iBgdWidth, m_BgdParam.iBgdHeight);
m_iLargestFrameSize = iCurFrameSize;
}
@@ -112,10 +112,6 @@ inline SBackgroundOU* CBackgroundDetection::AllocateOUArrayMemory (int32_t iWidt
return (SBackgroundOU*)WelsMalloc (iMaxOUWidth * iMaxOUHeight * sizeof (SBackgroundOU));
}
inline void CBackgroundDetection::FreeOUArrayMemory() {
_SafeFree (m_BgdParam.pOU_array);
}
void CBackgroundDetection::GetOUParameters (SVAACalcResult* sVaaCalcInfo, int32_t iMbIndex, int32_t iMbWidth,
SBackgroundOU* pBgdOU) {
int32_t iSubSD[4];

View File

@@ -81,7 +81,6 @@ class CBackgroundDetection : public IStrategy {
private:
inline SBackgroundOU* AllocateOUArrayMemory (int32_t iWidth, int32_t iHeight);
inline void FreeOUArrayMemory();
inline int32_t CalculateAsdChromaEdge (uint8_t* pOriRef, uint8_t* pOriCur, int32_t iStride);
inline bool ForegroundDilation23Luma (SBackgroundOU* pBackgroundOU,
SBackgroundOU* pOUNeighbours[]); //Foreground_Dilation_2_3_Luma

View File

@@ -44,20 +44,20 @@
/* interface API implement */
EResult CreateVpInterface (void** ppCtx, int iVersion) {
EResult WelsCreateVpInterface (void** ppCtx, int iVersion) {
if (iVersion & 0x8000)
return nsWelsVP::CreateSpecificVpInterface ((IWelsVP**)ppCtx);
return WelsVP::CreateSpecificVpInterface ((IWelsVP**)ppCtx);
else if (iVersion & 0x7fff)
return nsWelsVP::CreateSpecificVpInterface ((IWelsVPc**)ppCtx);
return WelsVP::CreateSpecificVpInterface ((IWelsVPc**)ppCtx);
else
return RET_INVALIDPARAM;
}
EResult DestroyVpInterface (void* pCtx, int iVersion) {
EResult WelsDestroyVpInterface (void* pCtx, int iVersion) {
if (iVersion & 0x8000)
return nsWelsVP::DestroySpecificVpInterface ((IWelsVP*)pCtx);
return WelsVP::DestroySpecificVpInterface ((IWelsVP*)pCtx);
else if (iVersion & 0x7fff)
return nsWelsVP::DestroySpecificVpInterface ((IWelsVPc*)pCtx);
return WelsVP::DestroySpecificVpInterface ((IWelsVPc*)pCtx);
else
return RET_INVALIDPARAM;
}
@@ -79,7 +79,7 @@ EResult CreateSpecificVpInterface (IWelsVP** ppCtx) {
}
EResult DestroySpecificVpInterface (IWelsVP* pCtx) {
_SafeDelete (pCtx);
delete pCtx;
return RET_SUCCESS;
}
@@ -105,7 +105,7 @@ CVpFrameWork::~CVpFrameWork() {
for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++) {
if (m_pStgChain[i]) {
Uninit (m_pStgChain[i]->m_eMethod);
_SafeDelete (m_pStgChain[i]);
delete m_pStgChain[i];
}
}

View File

@@ -63,7 +63,7 @@ class IStrategy : public IWelsVP {
m_eFormat = VIDEO_FORMAT_I420;
m_iIndex = 0;
m_bInit = false;
};
}
virtual ~IStrategy() {}

View File

@@ -87,7 +87,7 @@ EResult CreateSpecificVpInterface (IWelsVPc** pCtx) {
EResult DestroySpecificVpInterface (IWelsVPc* pCtx) {
if (pCtx) {
DestroySpecificVpInterface (WelsStaticCast (IWelsVP*, pCtx->pCtx));
_SafeDelete (pCtx);
delete pCtx;
}
return RET_SUCCESS;

View File

@@ -32,5 +32,5 @@
LIBRARY welsvp.dll
EXPORTS
CreateVpInterface
DestroyVpInterface
WelsCreateVpInterface
WelsDestroyVpInterface

View File

@@ -38,14 +38,24 @@
*
*/
#ifndef WELSVP_SCENECHANGEDETECTIONCOMMON_H
#define WELSVP_SCENECHANGEDETECTIONCOMMON_H
#ifndef WELSVP_COMMON_H
#define WELSVP_COMMON_H
#include "util.h"
#include "memory.h"
#include "WelsFrameWork.h"
#include "IWelsVP.h"
#include "sad_common.h"
#include "intra_pred_common.h"
typedef void (GetIntraPred) (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
typedef GetIntraPred* GetIntraPredPtr;
GetIntraPred WelsI16x16LumaPredV_c;
GetIntraPred WelsI16x16LumaPredH_c;
WELSVP_NAMESPACE_BEGIN
@@ -56,12 +66,6 @@ typedef SadFunc* SadFuncPtr;
typedef int32_t (Sad16x16Func) (uint8_t* pSrcY, int32_t iSrcStrideY, uint8_t* pRefY, int32_t iRefStrideY);
typedef Sad16x16Func* PSad16x16Func;
typedef void (GetIntraPred) (uint8_t* pPred, uint8_t* pRef, const int32_t kiStride);
typedef GetIntraPred* GetIntraPredPtr;
GetIntraPred WelsI16x16LumaPredV_c;
GetIntraPred WelsI16x16LumaPredH_c;
#ifdef HAVE_NEON
WELSVP_EXTERN_C_BEGIN

View File

@@ -47,7 +47,7 @@
#define WELSVP_EXTERN_C_BEGIN extern "C" {
#define WELSVP_EXTERN_C_END }
#define WELSVP_NAMESPACE_BEGIN namespace nsWelsVP {
#define WELSVP_NAMESPACE_BEGIN namespace WelsVP {
#define WELSVP_NAMESPACE_END }
// Get the stdint type definitions from typedefs.h in the common lib

View File

@@ -102,9 +102,6 @@ inline EMethods WelsVpGetValidMethod (int32_t a) {
}
#define _SafeFree(p) if (p) { WelsFree(p); (p) = NULL; }
#define _SafeDelete(p) if (p) { delete (p); (p) = NULL; }
WELSVP_NAMESPACE_END

View File

@@ -33,10 +33,10 @@
#include "ComplexityAnalysis.h"
#include "cpu.h"
#include "macros.h"
#include "intra_pred_common.h"
WELSVP_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
CComplexityAnalysis::CComplexityAnalysis (int32_t iCpuFlag) {
@@ -280,8 +280,29 @@ CComplexityAnalysisScreen::CComplexityAnalysisScreen (int32_t iCpuFlag) {
#ifdef X86_ASM
if (iCpuFlag & WELS_CPU_SSE2) {
m_pSadFunc = WelsSampleSad16x16_sse2;
m_pIntraFunc[0] = WelsI16x16LumaPredV_sse2;
m_pIntraFunc[1] = WelsI16x16LumaPredH_sse2;
}
#endif
#if defined (HAVE_NEON)
if (iCpuFlag & WELS_CPU_NEON) {
m_pSadFunc = WelsSampleSad16x16_neon;
m_pIntraFunc[0] = WelsI16x16LumaPredV_neon;
m_pIntraFunc[1] = WelsI16x16LumaPredH_neon;
}
#endif
#if defined (HAVE_NEON_AARCH64)
if (iCpuFlag & WELS_CPU_NEON) {
m_pSadFunc = WelsSampleSad16x16_AArch64_neon;
m_pIntraFunc[0] = WelsI16x16LumaPredV_AArch64_neon;
m_pIntraFunc[1] = WelsI16x16LumaPredH_AArch64_neon;
}
#endif
}
CComplexityAnalysisScreen::~CComplexityAnalysisScreen() {

View File

@@ -112,4 +112,4 @@ void CScrollDetection::ScrollDetectionWithoutMask (SPixMap* pSrcPixMap, SPixMap*
}
}
WELSVP_NAMESPACE_END
WELSVP_NAMESPACE_END

View File

@@ -51,7 +51,7 @@ class CScrollDetection : public IStrategy {
CScrollDetection (int32_t iCpuFlag) {
m_eMethod = METHOD_SCROLL_DETECTION;
WelsMemset (&m_sScrollDetectionParam, 0, sizeof (m_sScrollDetectionParam));
};
}
~CScrollDetection() {
}
EResult Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap);

View File

@@ -58,4 +58,4 @@ int32_t CompareLine (uint8_t* pYSrc, uint8_t* pYRef, const int32_t kiWidth);
void ScrollDetectionCore (SPixMap* pSrcPixMap, SPixMap* pRefPixMap, int32_t iWidth, int32_t iHeight,
int32_t iOffsetX, int32_t iOffsetY, SScrollDetectionParam& sScrollDetectionParam);
WELSVP_NAMESPACE_END
WELSVP_NAMESPACE_END

View File

@@ -2,7 +2,6 @@ PROCESSING_SRCDIR=codec/processing
PROCESSING_CPP_SRCS=\
$(PROCESSING_SRCDIR)/src/adaptivequantization/AdaptiveQuantization.cpp\
$(PROCESSING_SRCDIR)/src/backgrounddetection/BackgroundDetection.cpp\
$(PROCESSING_SRCDIR)/src/common/common.cpp\
$(PROCESSING_SRCDIR)/src/common/memory.cpp\
$(PROCESSING_SRCDIR)/src/common/WelsFrameWork.cpp\
$(PROCESSING_SRCDIR)/src/common/WelsFrameWorkEx.cpp\
@@ -21,36 +20,43 @@ PROCESSING_CPP_SRCS=\
PROCESSING_OBJS += $(PROCESSING_CPP_SRCS:.cpp=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
PROCESSING_ASM_SRCS=\
$(PROCESSING_SRCDIR)/src/x86/denoisefilter.asm\
$(PROCESSING_SRCDIR)/src/x86/downsample_bilinear.asm\
$(PROCESSING_SRCDIR)/src/x86/vaa.asm\
PROCESSING_OBJS += $(PROCESSING_ASM_SRCS:.asm=.$(OBJ))
PROCESSING_OBJSASM += $(PROCESSING_ASM_SRCS:.asm=.$(OBJ))
ifeq ($(ASM_ARCH), x86)
PROCESSING_OBJS += $(PROCESSING_OBJSASM)
endif
OBJS += $(PROCESSING_OBJSASM)
ifeq ($(ASM_ARCH), arm)
PROCESSING_ASM_ARM_SRCS=\
$(PROCESSING_SRCDIR)/src/arm/adaptive_quantization.S\
$(PROCESSING_SRCDIR)/src/arm/down_sample_neon.S\
$(PROCESSING_SRCDIR)/src/arm/pixel_sad_neon.S\
$(PROCESSING_SRCDIR)/src/arm/vaa_calc_neon.S\
PROCESSING_OBJS += $(PROCESSING_ASM_ARM_SRCS:.S=.$(OBJ))
PROCESSING_OBJSARM += $(PROCESSING_ASM_ARM_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm)
PROCESSING_OBJS += $(PROCESSING_OBJSARM)
endif
OBJS += $(PROCESSING_OBJSARM)
ifeq ($(ASM_ARCH), arm64)
PROCESSING_ASM_ARM64_SRCS=\
$(PROCESSING_SRCDIR)/src/arm64/adaptive_quantization_aarch64_neon.S\
$(PROCESSING_SRCDIR)/src/arm64/down_sample_aarch64_neon.S\
$(PROCESSING_SRCDIR)/src/arm64/pixel_sad_aarch64_neon.S\
$(PROCESSING_SRCDIR)/src/arm64/vaa_calc_aarch64_neon.S\
PROCESSING_OBJS += $(PROCESSING_ASM_ARM64_SRCS:.S=.$(OBJ))
PROCESSING_OBJSARM64 += $(PROCESSING_ASM_ARM64_SRCS:.S=.$(OBJ))
ifeq ($(ASM_ARCH), arm64)
PROCESSING_OBJS += $(PROCESSING_OBJSARM64)
endif
OBJS += $(PROCESSING_OBJSARM64)
OBJS += $(PROCESSING_OBJS)
$(PROCESSING_SRCDIR)/%.$(OBJ): $(PROCESSING_SRCDIR)/%.cpp
$(QUIET_CXX)$(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) $(PROCESSING_CFLAGS) $(PROCESSING_INCLUDES) -c $(CXX_O) $<

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