diff --git a/README.md b/README.md index 2f912a11982cfe8c9c5e482c3c5c147a6d7d7994..d2853b793a91c0f9554b6f081da57508b242888e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,21 @@ -How to build VTM -================ +VTM reference software for VVC +============================== + +This software package is the reference software for Versatile Video Coding (VVC). The reference software includes both encoder and decoder functionality. + +Reference software is useful in aiding users of a video coding standard to establish and test conformance and interoperability, and to educate users and demonstrate the capabilities of the standard. For these purposes, this software is provided as an aid for the study and implementation of Versatile Video Coding. + +The software has been jointly developed by the ITU-T Video Coding Experts Group (VCEG, Question 6 of ITU-T Study Group 16) and the ISO/IEC Moving Picture Experts Group (MPEG, Working Group 11 of Subcommittee 29 of ISO/IEC Joint Technical Committee 1). + +A software manual, which contains usage instructions, can be found in the "doc" subdirectory of this software package. + +Build instructions +================== + +The CMake tool is used to create platform-specific build files. + +Although CMake may be able to generate 32-bit binaries, **it is generally suggested to build 64-bit binaries**. 32-bit binaries are not able to access more than 2GB of RAM, which will not be sufficient for coding larger image formats. Building in 32-bit environments is not tested and will not be supported. -The software uses CMake to create platform-specific build files. Build instructions for plain CMake (suggested) ---------------------------------------------- @@ -86,16 +100,21 @@ To use the default system compiler simply call: ```bash make all ``` -For MSYS2 and MinGW: Open an MSYS MinGW 64-Bit terminal and change into the root directory of this project. + + +**MSYS2 and MinGW (Windows)** + +**Note:** Build files for MSYS MinGW were added on request. The build platform is not regularily tested and can't be supported. + +Open an MSYS MinGW 64-Bit terminal and change into the root directory of this project. Call: ```bash make all toolset=gcc ``` +The following tools need to be installed for MSYS2 and MinGW: -Tool Installation on Windows ----------------------------- Download CMake: http://www.cmake.org/ and install it. Python and GnuWin32 are not mandatory, but they simplify the build process for the user. diff --git a/cfg/field/VTM_encoder_lowdelay_field_GOP16.cfg b/cfg/field/VTM_encoder_lowdelay_field_GOP16.cfg new file mode 100644 index 0000000000000000000000000000000000000000..596ee9fd0a681a032abc9932ce509ccda1eeca49 --- /dev/null +++ b/cfg/field/VTM_encoder_lowdelay_field_GOP16.cfg @@ -0,0 +1,26 @@ +FieldCoding : 1 # (0: Frame based coding, 1: Field based coding) +TopFieldFirst : 1 # Field parity order (1: Top field first, 0: Bottom field first) +ConformanceMode : 1 +VuiParametersPresent : 1 +SEIPictureTiming : 1 +SEIFrameFieldInfo : 1 +IntraPeriod : -1 # Period of I-Frame ( -1 = only first) +DecodingRefreshType : 0 # Random Accesss 0:none, 1:CRA, 2:IDR, 3:Recovery Point SEI +GOPSize : 16 # GOP Size (number of B slice = GOPSize-1) +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 2 5 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 9 10 17 18 25 26 8 8 1 2 9 10 17 18 25 26 +Frame2: B 3 5 -6.5 0.2590 0 0 1.0 0 0 0 8 9 1 2 3 10 11 18 19 26 27 8 9 1 2 3 10 11 18 19 26 27 +Frame3: B 4 4 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 3 4 11 12 19 20 8 8 1 2 3 4 11 12 19 20 +Frame4: B 5 4 -6.5 0.2590 0 0 1.0 0 0 0 8 9 1 2 3 4 5 12 13 20 21 8 9 1 2 3 4 5 12 13 20 21 +Frame5: B 6 5 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 5 6 13 14 21 22 8 8 1 2 5 6 13 14 21 22 +Frame6: B 7 5 -6.5 0.2590 0 0 1.0 0 0 0 8 9 1 2 3 6 7 14 15 22 23 8 9 1 2 3 6 7 14 15 22 23 +Frame7: B 8 4 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 7 8 15 16 23 24 8 8 1 2 7 8 15 16 23 24 +Frame8: B 9 4 -6.5 0.2590 0 0 1.0 0 0 0 8 9 1 2 3 8 9 16 17 24 25 8 9 1 2 3 8 9 16 17 24 25 +Frame9: B 10 5 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 9 10 17 18 25 26 8 8 1 2 9 10 17 18 25 26 +Frame10: B 11 5 -6.5 0.2590 0 0 1.0 0 0 0 8 9 1 2 3 10 11 18 19 26 27 8 9 1 2 3 10 11 18 19 26 27 +Frame11: B 12 4 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 3 4 11 12 19 20 8 8 1 2 3 4 11 12 19 20 +Frame12: B 13 4 -6.5 0.2590 0 0 1.0 0 0 0 8 9 1 2 3 4 5 12 13 20 21 8 9 1 2 3 4 5 12 13 20 21 +Frame13: B 14 5 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 5 6 13 14 21 22 8 8 1 2 5 6 13 14 21 22 +Frame14: B 15 5 -6.5 0.2590 0 0 1.0 0 0 0 8 9 1 2 3 6 7 14 15 22 23 8 9 1 2 3 6 7 14 15 22 23 +Frame15: B 16 1 0.0 0.0 0 0 1.0 0 0 0 8 8 1 2 7 8 15 16 23 24 8 8 1 2 7 8 15 16 23 24 +Frame16: B 17 1 0.0 0.0 0 0 1.0 0 0 0 8 9 1 2 3 8 9 16 17 24 25 8 9 1 2 3 8 9 16 17 24 25 diff --git a/cfg/field/VTM_encoder_lowdelay_field_GOP8.cfg b/cfg/field/VTM_encoder_lowdelay_field_GOP8.cfg new file mode 100644 index 0000000000000000000000000000000000000000..dc23e0a35af85ff1022c69bdd50f90743050e486 --- /dev/null +++ b/cfg/field/VTM_encoder_lowdelay_field_GOP8.cfg @@ -0,0 +1,18 @@ +FieldCoding : 1 # (0: Frame based coding, 1: Field based coding) +TopFieldFirst : 1 # Field parity order (1: Top field first, 0: Bottom field first) +ConformanceMode : 1 +VuiParametersPresent : 1 +SEIPictureTiming : 1 +SEIFrameFieldInfo : 1 +IntraPeriod : -1 # Period of I-Frame ( -1 = only first) +DecodingRefreshType : 0 # Random Accesss 0:none, 1:CRA, 2:IDR, 3:Recovery Point SEI +GOPSize : 8 # GOP Size (number of B slice = GOPSize-1) +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 2 5 -6.5 0.2590 0 0 1.0 0 0 0 5 5 1 2 9 10 17 5 5 1 2 9 10 17 +Frame2: B 3 5 -6.5 0.2590 0 0 1.0 0 0 0 6 6 1 2 3 10 11 18 6 6 1 2 3 10 11 18 +Frame3: B 4 4 -6.5 0.2590 0 0 1.0 0 0 0 7 7 1 2 3 4 11 12 19 7 7 1 2 3 4 11 12 19 +Frame4: B 5 4 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 3 4 5 12 13 20 8 8 1 2 3 4 5 12 13 20 +Frame5: B 6 5 -6.5 0.2590 0 0 1.0 0 0 0 7 7 1 2 5 6 13 14 21 7 7 1 2 5 6 13 14 21 +Frame6: B 7 5 -6.5 0.2590 0 0 1.0 0 0 0 8 8 1 2 3 6 7 14 15 22 8 8 1 2 3 6 7 14 15 22 +Frame7: B 8 1 0.0 0.0 0 0 1.0 0 0 0 7 7 1 2 7 8 15 16 23 7 7 1 2 7 8 15 16 23 +Frame8: B 9 1 0.0 0.0 0 0 1.0 0 0 0 8 8 1 2 3 8 9 16 17 24 8 8 1 2 3 8 9 16 17 24 diff --git a/cfg/field/VTM_encoder_randomaccess_field_GOP16.cfg b/cfg/field/VTM_encoder_randomaccess_field_GOP16.cfg new file mode 100644 index 0000000000000000000000000000000000000000..040922b18643bb2a18a3c6cf964f68980f923363 --- /dev/null +++ b/cfg/field/VTM_encoder_randomaccess_field_GOP16.cfg @@ -0,0 +1,26 @@ +FieldCoding : 1 # (0: Frame based coding, 1: Field based coding) +TopFieldFirst : 1 # Field parity order (1: Top field first, 0: Bottom field first) +ConformanceMode : 1 +VuiParametersPresent : 1 +SEIPictureTiming : 1 +SEIFrameFieldInfo : 1 +IntraPeriod : 32 # Period of I-Frame ( -1 = only first) +DecodingRefreshType : 1 # Random Accesss 0:none, 1:CRA, 2:IDR, 3:Recovery Point SEI +GOPSize : 16 # GOP Size (number of B slice = GOPSize-1) +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 17 1 0.0 0.0 0 0 0.442 0 0 0 4 4 16 17 20 21 4 4 16 17 20 21 +Frame2: B 16 1 0.0 0.0 0 0 0.442 0 0 0 3 3 15 16 -1 3 3 -1 15 16 +Frame3: B 8 2 0.0 0.0 0 0 0.3536 0 0 1 2 4 7 8 -8 -9 2 4 -8 -9 7 8 +Frame4: B 9 2 0.0 0.0 0 0 0.3536 0 0 1 2 5 1 8 9 -7 -8 2 5 -7 -8 1 8 9 +Frame5: B 4 3 0.0 0.0 0 0 0.3536 0 0 2 2 4 3 4 -4 -5 2 4 -4 -5 -12 -13 +Frame6: B 5 3 0.0 0.0 0 0 0.3536 0 0 2 2 5 1 4 5 -3 -4 2 4 -3 -4 -11 -12 +Frame7: B 2 4 0.0 0.0 0 0 0.68 0 0 3 2 4 1 2 -2 -3 2 6 -2 -3 -6 -7 -14 -15 +Frame8: B 3 4 0.0 0.0 0 0 0.68 0 0 3 2 4 1 2 -1 -2 2 6 -1 -2 -5 -6 -13 -14 +Frame9: B 6 4 0.0 0.0 0 0 0.68 0 0 3 2 4 1 2 -2 -3 2 4 -2 -3 -10 -11 +Frame10: B 7 4 0.0 0.0 0 0 0.68 0 0 3 2 5 1 2 3 -1 -2 2 4 -1 -2 -9 -10 +Frame11: B 12 3 0.0 0.0 0 0 0.3536 0 0 2 2 4 3 4 -4 -5 2 4 -4 -5 3 4 +Frame12: B 13 3 0.0 0.0 0 0 0.3536 0 0 2 2 5 1 4 5 -3 -4 2 5 -3 -4 1 4 5 +Frame13: B 10 4 0.0 0.0 0 0 0.68 0 0 3 2 4 1 2 -2 -3 2 4 -2 -3 -6 -7 +Frame14: B 11 4 0.0 0.0 0 0 0.68 0 0 3 2 5 1 2 3 -1 -2 2 4 -1 -2 -5 -6 +Frame15: B 14 4 0.0 0.0 0 0 0.68 0 0 3 2 5 1 2 5 -2 -3 2 4 -2 -3 1 2 +Frame16: B 15 4 0.0 0.0 0 0 0.68 0 0 3 2 4 1 2 3 6 2 4 -1 -2 1 2 diff --git a/cfg/field/VTM_encoder_randomaccess_field_GOP32.cfg b/cfg/field/VTM_encoder_randomaccess_field_GOP32.cfg new file mode 100644 index 0000000000000000000000000000000000000000..34435952483b8187452b7b4602392b34516d24dc --- /dev/null +++ b/cfg/field/VTM_encoder_randomaccess_field_GOP32.cfg @@ -0,0 +1,42 @@ +FieldCoding : 1 # (0: Frame based coding, 1: Field based coding) +TopFieldFirst : 1 # Field parity order (1: Top field first, 0: Bottom field first) +ConformanceMode : 1 +VuiParametersPresent : 1 +SEIPictureTiming : 1 +SEIFrameFieldInfo : 1 +IntraPeriod : 64 # Period of I-Frame ( -1 = only first) +DecodingRefreshType : 1 # Random Accesss 0:none, 1:CRA, 2:IDR, 3:Recovery Point SEI +GOPSize : 32 # GOP Size (number of B slice = GOPSize-1) +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 33 1 0.0 0.0 0 0 1.0 0 0 0 4 4 32 33 48 49 4 4 32 33 48 49 +Frame2: B 32 1 0.0 0.0 0 0 1.0 0 0 0 4 5 31 32 47 48 -1 4 5 -1 31 32 47 48 +Frame3: B 16 1 -4.8848 0.2061 0 0 1.0 0 0 1 4 4 15 16 31 32 4 4 -16 -17 15 16 +Frame4: B 17 1 -4.8848 0.2061 0 0 1.0 0 0 1 4 5 1 16 17 32 33 4 4 -15 -16 16 17 +Frame5: B 8 4 -5.7476 0.2286 0 0 1.0 0 0 2 4 4 7 8 23 24 4 4 -8 -9 -24 -25 +Frame6: B 9 4 -5.7476 0.2286 0 0 1.0 0 0 2 4 5 1 8 9 24 25 4 4 -7 -8 -23 -24 +Frame7: B 4 5 -5.90 0.2333 0 0 1.0 0 0 3 4 4 3 4 19 20 4 6 -4 -5 -12 -13 -28 -29 +Frame8: B 5 5 -5.90 0.2333 0 0 1.0 0 0 3 4 5 1 4 5 20 21 4 6 -3 -4 -11 -12 -27 -28 +Frame9: B 2 6 -7.1444 0.3 0 0 1.0 0 0 4 4 4 1 2 -2 -3 4 8 -2 -3 -6 -7 -14 -15 -30 -31 +Frame10: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 4 5 1 2 3 -1 -2 4 8 -1 -2 -5 -6 -13 -14 -29 -30 +Frame11: B 6 6 -7.1444 0.3 0 0 1.0 0 0 4 4 4 1 2 5 6 4 6 -2 -3 -10 -11 -26 -27 +Frame12: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 4 5 1 2 3 6 7 4 6 -1 -2 -9 -10 -25 -26 +Frame13: B 12 5 -5.90 0.2333 0 0 1.0 0 0 3 4 4 3 4 11 12 4 4 -4 -5 -20 -21 +Frame14: B 13 5 -5.90 0.2333 0 0 1.0 0 0 3 4 5 1 4 5 12 13 4 4 -3 -4 -19 -20 +Frame15: B 10 6 -7.1444 0.3 0 0 1.0 0 0 4 4 4 1 2 9 10 4 6 -2 -3 -6 -7 -22 -23 +Frame16: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 4 5 1 2 3 10 11 4 6 -1 -2 -5 -6 -21 -22 +Frame17: B 14 6 -7.1444 0.3 0 0 1.0 0 0 4 4 6 1 2 5 6 13 14 4 4 -2 -3 -18 -19 +Frame18: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 4 7 1 2 3 6 7 14 15 4 4 -1 -2 -17 -18 +Frame19: B 24 4 -5.7476 0.2286 0 0 1.0 0 0 2 4 4 7 8 23 24 4 4 -8 -9 7 8 +Frame20: B 25 4 -5.7476 0.2286 0 0 1.0 0 0 2 4 5 1 8 9 24 25 4 4 -7 -8 8 9 +Frame21: B 20 5 -5.90 0.2333 0 0 1.0 0 0 3 4 4 3 4 19 20 4 4 -4 -5 -12 -13 +Frame22: B 21 5 -5.90 0.2333 0 0 1.0 0 0 3 4 5 1 4 5 20 21 4 4 -3 -4 -11 -12 +Frame23: B 18 6 -7.1444 0.3 0 0 1.0 0 0 4 4 4 1 2 17 18 4 6 -2 -3 -6 -7 -14 -15 +Frame24: B 19 6 -7.1444 0.3 0 0 1.0 0 0 4 4 5 1 2 3 18 19 4 6 -1 -2 -5 -6 -13 -14 +Frame25: B 22 6 -7.1444 0.3 0 0 1.0 0 0 4 4 6 1 2 5 6 21 22 4 4 -2 -3 -10 -11 +Frame26: B 23 6 -7.1444 0.3 0 0 1.0 0 0 4 4 7 1 2 3 6 7 22 23 4 4 -1 -2 -9 -10 +Frame27: B 28 5 -5.90 0.2333 0 0 1.0 0 0 3 4 6 3 4 11 12 27 28 4 4 -4 -5 3 4 +Frame28: B 29 5 -5.90 0.2333 0 0 1.0 0 0 3 4 7 1 4 5 12 13 28 29 4 4 -3 -4 4 5 +Frame29: B 26 6 -7.1444 0.3 0 0 1.0 0 0 4 4 6 1 2 9 10 25 26 4 4 -2 -3 -6 -7 +Frame30: B 27 6 -7.1444 0.3 0 0 1.0 0 0 4 4 7 1 2 3 10 11 26 27 4 4 -1 -2 -5 -6 +Frame31: B 30 6 -7.1444 0.3 0 0 1.0 0 0 4 4 8 1 2 5 6 13 14 29 30 4 4 -2 -3 1 2 +Frame32: B 31 6 -7.1444 0.3 0 0 1.0 0 0 4 4 9 1 2 3 6 7 14 15 30 31 4 4 -1 -2 2 3 diff --git a/doc/jvetdoc.cls b/doc/jvetdoc.cls index bdc22890e30fb89bfc9ac4a60b0b17d920c2af7b..f766488489577b40d4f1401611e89fe51e994dcb 100644 --- a/doc/jvetdoc.cls +++ b/doc/jvetdoc.cls @@ -117,7 +117,7 @@ \@strutb \it Title: & \@title \\ \@strutb \it Status: & \@jvetdocstatus \\ \@strutb \it Purpose: & \@jvetdocpurpose \\ - \@strutb \it Author(s): & % + \@strutb \it Editors: & % \setcounter{jvet@author@column}{0} \let\@and\\ \renewcommand{\and}{\@and\setcounter{jvet@author@column}{0}} diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 447c9808e622d6348e8e8fcd70a81f184f72b55b..718b22377a0d3085ee02150dc9d4c4c9433a7cb0 100755 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -1405,6 +1405,12 @@ Specifies the base value of the quantization parameter. If it is non-integer, th Specifies a QP offset from the base QP value to be used for intra frames. \\ +\Option{DepQuant} & +%\ShortOption{\None} & +\Default{true} & +Enables or disables the usage of dependent quantization. +\\ + \Option{LambdaFromQpEnable} & %\ShortOption{\None} & \Default{false} & @@ -1643,10 +1649,10 @@ value delta for the picture with POC value $n$. \Option{PerceptQPA (-qpa)} & %\ShortOption{-qpa} & \Default{false} & -Enables or disables the perceptually optimized QP adaptation (QPA) method described in JVET-H0047, JVET-K0206, and JVET-M0091. Use this together with 'SliceChromaQPOffsetPeriodicity=1' and, in case of HDR input, 'LumaLevelToDeltaQPMode=1' for best subjective quality. Cannot be used together with 'SelectiveRDOQ' (see above) or 'AdaptiveQp' (see below). +Enables or disables the perceptually optimized QP adaptation (QPA) method described in JVET-H0047, JVET-K0206, and JVET-M0091. Use this together with 'SliceChromaQPOffsetPeriodicity=1' and, in case of HDR input, 'LumaLevelToDeltaQPMode=1' for best subjective quality. Cannot be used together with 'SelectiveRDOQ' (see above) or 'AdaptiveQP' (see below). \\ -\Option{AdaptiveQp (-aq)} & +\Option{AdaptiveQP (-aq)} & %\ShortOption{-aq} & \Default{false} & Enables or disables the legacy QP adaptation method based upon a psycho-visual model. @@ -2037,7 +2043,7 @@ Enables the use of weighted prediction in P slices. Enables the use of weighted prediction in B slices. \\ -\Option{WPMethod (-wpM)} & +\Option{WeightedPredMethod (-wpM)} & %\ShortOption{\-wpM} & \Default{0} & Sets the Weighted Prediction method to be used. @@ -2063,16 +2069,6 @@ bitstream, but may be inferred from the parity of the sum of all nonzero coefficients in the current coefficient group. \\ -\Option{StrongIntraSmoothing (-sis)} & -%\ShortOption{-sis} & -\Default{true} & -If enabled specifies that for 32x32 intra prediction block, the intra smoothing -when applied is either the 1:2:1 smoothing filter or a stronger bi-linear -interpolation filter. Key reference sample values are tested and if the criteria -is satisfied, the stronger intra smoothing filter is applied. -If disabled, the intra smoothing filter when applied is the 1:2:1 smoothing filter. -\\ - \Option{TMVPMode} & %\ShortOption{\None} & \Default{1} & @@ -2131,12 +2127,6 @@ Code deblocking filter parameters in slice headers rather than picture header. Code SAO parameters in slice headers rather than picture header. \\ -\Option{SliceLevelAlf} & -%\ShortOption{\None} & -\Default{true} & -Code ALF parameters in slice headers rather than picture header. -\\ - \Option{TransformSkip} & %\ShortOption{\None} & \Default{false} & @@ -2164,6 +2154,12 @@ chroma TUs. This option has no effect if TransformSkip is disabled. \\ +\Option{ALF} & +%\ShortOption{\None} & +\Default{true} & +Enables or disables adaptive loop filter. +\\ + \Option{UseNonLinearAlfLuma} & %\ShortOption{\None} & \Default{true} & @@ -2479,7 +2475,7 @@ Signals whether colour_primaries, transfer_characteristics and matrix_coefficien \Default{2} & Indicates chromaticity coordinates of the source primaries. \\ -\Option{TransferCharateristics} & +\Option{TransferCharacteristics} & \Default{2} & Indicates the opto-electronic transfer characteristics of the source. \\ @@ -2524,16 +2520,6 @@ input video from the conformance window in luma samples. Must be a multiple of the chroma resolution (e.g. a multiple of two for 4:2:0). \\ -\Option{FrameFieldInfoPresentFlag} & -\Default{false} & -Specificies the value of the VUI syntax element `frame_field_info_present_flag', which indicates that pic_struct and field coding related values are present in picture timing SEI messages. -\\ - -\Option{PocProportionalToTimingFlag} & -\Default{false} & -Specificies the value of the VUI syntax element `vui_poc_proportional_to_timing_flag', which indicates that the POC value is proportional to the output time with respect to the first picture in the CVS. -\\ - \Option{NumTicksPocDiffOneMinus} & \Default{0} & Specificies the value of the VUI syntax element `vui_num_ticks_poc_diff_one_minus1', which specifies the number of clock ticks corresponding to a difference of picture order count values equal to 1, and is used only when PocProportionalToTimingFlag is true. @@ -2702,6 +2688,7 @@ The table below lists the SEI messages defined for Version 1 and Range-Extension 154 & Sphere rotation & Table \ref{tab:sei-sphere-rotation} \\ 155 & Region-wise packing & Table \ref{tab:sei-rwp} \\ 156 & Omni viewport & Table \ref{tab:sei-omni-viewport} \\ + 168 & Frame-field information & Table \ref{tab:sei-frame-field} \\ 203 & Subpicture Level Information & Table \ref{tab:sei-subpic-level} \\ 204 & Sample Aspect Ratio Information & Table \ref{tab:sei-sari} \\ \end{SEIListTable} @@ -3495,15 +3482,15 @@ Indicates that the sphere rotation SEI message cancels the persistence (true) or \Default{false} & Specifies the persistence of the sphere rotation SEI message. \\ -\Option{SEISphereRotationYawRotation} & +\Option{SEISphereRotationYaw} & \Default{0} & Specifies the value of the yaw rotation angle. \\ -\Option{SEISphereRotationPitchRotation} & +\Option{SEISphereRotationPitch} & \Default{0} & Specifies the value of the pitch rotation angle. \\ -\Option{SEISphereRotationRollRotation} & +\Option{SEISphereRotationRoll} & \Default{0} & Specifies the value of the roll rotation angle. \\ @@ -3686,7 +3673,14 @@ Specifies the vertical size of the sample aspect ratio, if SEISARIAspectRatioIdc \\ \end{OptionTableNoShorthand} -\begin{OptionTableNoShorthand}{Sample Aspect Ratio Information SEI message encoder parameters}{tab:sei-subpic-level} +\begin{OptionTableNoShorthand}{Frame-Field Information SEI message encoder parameters}{tab:sei-frame-field} +\Option{SEIFrameFieldInfo} & +\Default{false} & +Enables (true) or disables (false) the insertion of Frame-Field Information SEI message. +\\ +\end{OptionTableNoShorthand} + +\begin{OptionTableNoShorthand}{Subpicture Level Information SEI message encoder parameters}{tab:sei-subpic-level} \Option{SEISubpictureLevelInfo} & \Default{false} & Enables (true) or disables (false) the insertion of Subpicture Level Information SEI message. diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index a0717b2fe9e77803b1e679c515b620e0e9f6c1bb..ee0ff305fe4e813d70e679c8eee677ceef10052d 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -360,7 +360,9 @@ uint32_t DecApp::decode() } } #if JVET_P1019_OUTPUT_LAYER_SET - if(((m_cDecLib.getVPS() != nullptr) && (m_cDecLib.getVPS()->getMaxLayers() > 1) && (isNaluWithinTargetOutputLayerIdSet(&nalu))) || (m_cDecLib.getVPS() == nullptr)) + if(((m_cDecLib.getVPS() != nullptr) && + ((m_cDecLib.getVPS()->getMaxLayers() == 1) || (isNaluWithinTargetOutputLayerIdSet(&nalu)))) || + (m_cDecLib.getVPS() == nullptr)) #endif m_cVideoIOYuvReconFile[nalu.m_nuhLayerId].open(reconFileName, true, m_outputBitDepth, m_outputBitDepth, bitDepths.recon); // write mode #else diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 29b978da51b60cc33d78bb7648898b8f012b3de6..baf182c6bae220d1c4627111fe1a071bd951f1a6 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -388,6 +388,35 @@ void EncApp::xInitLibCfg() #endif m_cEncLib.setRDpenalty ( m_rdPenalty ); m_cEncLib.setCTUSize ( m_uiCTUSize ); +#if JVET_P0171_SUBPICTURE_LAYOUT + m_cEncLib.setSubPicPresentFlag ( m_subPicPresentFlag ); + if(m_subPicPresentFlag) + { + m_cEncLib.setNumSubPics ( m_numSubPics ); + for (int i = 0; i < m_numSubPics; i++) + { + m_cEncLib.setSubPicCtuTopLeftX ( m_subPicCtuTopLeftX[i], i ); + m_cEncLib.setSubPicCtuTopLeftY ( m_subPicCtuTopLeftY[i], i ); + m_cEncLib.setSubPicWidth ( m_subPicWidth[i], i ); + m_cEncLib.setSubPicHeight ( m_subPicHeight[i], i ); + m_cEncLib.setSubPicTreatedAsPicFlag ( m_subPicTreatedAsPicFlag[i], i ); + m_cEncLib.setLoopFilterAcrossSubpicEnabledFlag ( m_loopFilterAcrossSubpicEnabledFlag[i], i ); + } + } + m_cEncLib.setSubPicIdPresentFlag ( m_subPicIdPresentFlag ); + if (m_subPicIdPresentFlag) + { + m_cEncLib.setSubPicIdSignallingPresentFlag ( m_subPicIdSignallingPresentFlag ); + if(m_subPicIdSignallingPresentFlag) + { + m_cEncLib.setSubPicIdLen ( m_subPicIdLen ); + for (int i = 0; i < m_numSubPics; i++) + { + m_cEncLib.setSubPicId ( m_subPicId[i], i ); + } + } + } +#endif m_cEncLib.setUseSplitConsOverride ( m_SplitConsOverrideEnabledFlag ); m_cEncLib.setMinQTSizes ( m_uiMinQT ); m_cEncLib.setMaxMTTHierarchyDepth ( m_uiMaxMTTHierarchyDepth, m_uiMaxMTTHierarchyDepthI, m_uiMaxMTTHierarchyDepthIChroma ); @@ -975,8 +1004,13 @@ void EncApp::xCreateLib( std::list<PelUnitBuf*>& recBufList ) m_cVideoIOYuvInputFile.open( m_inputFileName, false, m_inputBitDepth, m_MSBExtendedBitDepth, m_internalBitDepth ); // read mode #if EXTENSION_360_VIDEO m_cVideoIOYuvInputFile.skipFrames(m_FrameSkip, m_inputFileWidth, m_inputFileHeight, m_InputChromaFormatIDC); +#else +#if FIELD_CODING_FIX + const int sourceHeight = m_isField ? m_iSourceHeightOrg : m_iSourceHeight; + m_cVideoIOYuvInputFile.skipFrames(m_FrameSkip, m_iSourceWidth - m_aiPad[0], sourceHeight - m_aiPad[1], m_InputChromaFormatIDC); #else m_cVideoIOYuvInputFile.skipFrames(m_FrameSkip, m_iSourceWidth - m_aiPad[0], m_iSourceHeight - m_aiPad[1], m_InputChromaFormatIDC); +#endif #endif if (!m_reconFileName.empty()) { @@ -1207,8 +1241,13 @@ bool EncApp::encode() { #if EXTENSION_360_VIDEO m_cVideoIOYuvInputFile.skipFrames( m_temporalSubsampleRatio - 1, m_inputFileWidth, m_inputFileHeight, m_InputChromaFormatIDC ); +#else +#if FIELD_CODING_FIX + const int sourceHeight = m_isField ? m_iSourceHeightOrg : m_iSourceHeight; + m_cVideoIOYuvInputFile.skipFrames( m_temporalSubsampleRatio - 1, m_iSourceWidth - m_aiPad[0], sourceHeight - m_aiPad[1], m_InputChromaFormatIDC ); #else m_cVideoIOYuvInputFile.skipFrames( m_temporalSubsampleRatio - 1, m_iSourceWidth - m_aiPad[0], m_iSourceHeight - m_aiPad[1], m_InputChromaFormatIDC ); +#endif #endif } } diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 04ec7a90b2cab468d8650046c07779cd4a724497..0a9f80b9ad722c4b2af3803d980c2725fa292ce2 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -931,7 +931,15 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<unsigned> cfg_virtualBoundariesPosY (0, std::numeric_limits<uint32_t>::max(), 0, 3); SMultiValueInput<uint8_t> cfg_SubProfile(0, std::numeric_limits<uint8_t>::max(), 0, std::numeric_limits<uint8_t>::max()); - +#if JVET_P0171_SUBPICTURE_LAYOUT + SMultiValueInput<uint32_t> cfg_subPicCtuTopLeftX(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicCtuTopLeftY(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicWidth(1, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicHeight(1, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicTreatedAsPicFlag(0, 1, 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_loopFilterAcrossSubpicEnabledFlag(0, 1, 0, MAX_NUM_SUB_PICS); + SMultiValueInput<uint32_t> cfg_subPicId(0, std::numeric_limits<uint32_t>::max(), 0, MAX_NUM_SUB_PICS); +#endif int warnUnknowParameter = 0; #if ENABLE_TRACING @@ -1052,6 +1060,20 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("NonPackedSource", m_nonPackedConstraintFlag, false, "Indicate that source does not contain frame packing") ("FrameOnly", m_frameOnlyConstraintFlag, false, "Indicate that the bitstream contains only frames") ("CTUSize", m_uiCTUSize, 128u, "CTUSize (specifies the CTU size if QTBT is on) [default: 128]") +#if JVET_P0171_SUBPICTURE_LAYOUT + ("SubPicPresentFlag", m_subPicPresentFlag, false, "equal to 1 specifies that subpicture parameters are present in in the SPS RBSP syntax") + ("NumSubPics", m_numSubPics, 0u, "specifies the number of subpictures") + ("SubPicCtuTopLeftX", cfg_subPicCtuTopLeftX, cfg_subPicCtuTopLeftX, "specifies horizontal position of top left CTU of i-th subpicture in unit of CtbSizeY") + ("SubPicCtuTopLeftY", cfg_subPicCtuTopLeftY, cfg_subPicCtuTopLeftY, "specifies vertical position of top left CTU of i-th subpicture in unit of CtbSizeY") + ("SubPicWidth", cfg_subPicWidth, cfg_subPicWidth, "specifies the width of the i-th subpicture in units of CtbSizeY") + ("SubPicHeight", cfg_subPicHeight, cfg_subPicHeight, "specifies the height of the i-th subpicture in units of CtbSizeY") + ("SubPicTreatedAsPicFlag", cfg_subPicTreatedAsPicFlag, cfg_subPicTreatedAsPicFlag, "equal to 1 specifies that the i-th subpicture of each coded picture in the CLVS is treated as a picture in the decoding process excluding in-loop filtering operations") + ("LoopFilterAcrossSubpicEnabledFlag", cfg_loopFilterAcrossSubpicEnabledFlag, cfg_loopFilterAcrossSubpicEnabledFlag, "equal to 1 specifies that in-loop filtering operations may be performed across the boundaries of the i-th subpicture in each coded picture in the CLVS") + ("SubPicIdPresentFlag", m_subPicIdPresentFlag, false, "equal to 1 specifies that subpicture ID mapping is present in the SPS") + ("SubPicIdSignallingPresentFlag", m_subPicIdSignallingPresentFlag, false, "equal to 1 specifies that subpicture ID mapping is signalled in the SPS") + ("SubPicIdLen", m_subPicIdLen, 0u, "specifies the number of bits used to represent the syntax element sps_subpic_id[ i ]. ") + ("SubPicId", cfg_subPicId, cfg_subPicId, "specifies that subpicture ID of the i-th subpicture") +#endif ("EnablePartitionConstraintsOverride", m_SplitConsOverrideEnabledFlag, true, "Enable partition constraints override") ("MinQTISlice", m_uiMinQT[0], 8u, "MinQTISlice") ("MinQTLumaISlice", m_uiMinQT[0], 8u, "MinQTLumaISlice") @@ -1187,8 +1209,6 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("GOPSize,g", m_iGOPSize, 1, "GOP size of temporal structure") ("DRAPPeriod", m_drapPeriod, 0, "DRAP period in frames (0: disable Dependent RAP indication SEI messages)") ("ReWriteParamSets", m_rewriteParamSets, false, "Enable rewriting of Parameter sets before every (intra) random access point") - //Alias with same name as in HM - ("ReWriteParamSetsFlag", m_rewriteParamSets, false, "Alias for ReWriteParamSets") ("IDRRefParamList", m_idrRefParamList, false, "Enable indication of reference picture list syntax elements in slice headers of IDR pictures") // motion search options ("DisableIntraInInter", m_bDisableIntraPUsInInterSlices, false, "Flag to disable intra PUs in inter slices") @@ -1379,8 +1399,8 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #if JVET_P0365_SCALING_MATRIX_LFNST ("DisableScalingMatrixForLFNST", m_disableScalingMatrixForLfnstBlks, true, "Disable scaling matrices, when enabled, for LFNST-coded blocks") #endif - ("DepQuant", m_depQuantEnabledFlag, true ) - ("SignHideFlag,-SBH", m_signDataHidingEnabledFlag, false ) + ("DepQuant", m_depQuantEnabledFlag, true, "Enable dependent quantization (Default: 1)" ) + ("SignHideFlag,-SBH", m_signDataHidingEnabledFlag, false, "Enable sign hiding" ) ("MaxNumMergeCand", m_maxNumMergeCand, 5u, "Maximum number of merge candidates") ("MaxNumAffineMergeCand", m_maxNumAffineMergeCand, 5u, "Maximum number of affine merge candidates") ("MaxNumTriangleCand", m_maxNumTriangleCand, 5u, "Maximum number of triangle candidates") @@ -1918,7 +1938,31 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) //number of fields to encode m_framesToBeEncoded *= 2; } - +#if JVET_P0171_SUBPICTURE_LAYOUT + if ( m_subPicPresentFlag ) + { + CHECK( m_numSubPics > 255 || m_numSubPics < 1, "Number of subpicture must be within 1 to 255" ); + m_subPicCtuTopLeftX = cfg_subPicCtuTopLeftX.values; + m_subPicCtuTopLeftY = cfg_subPicCtuTopLeftY.values; + m_subPicWidth = cfg_subPicWidth.values; + m_subPicHeight = cfg_subPicHeight.values; + m_subPicTreatedAsPicFlag = cfg_subPicTreatedAsPicFlag.values; + m_loopFilterAcrossSubpicEnabledFlag = cfg_loopFilterAcrossSubpicEnabledFlag.values; + m_subPicId = cfg_subPicId.values; + for(int i = 0; i < m_numSubPics; i++) + { + CHECK(m_subPicCtuTopLeftX[i] + m_subPicWidth[i] > (m_iSourceWidth + m_uiCTUSize - 1) / m_uiCTUSize, "subpicture must not exceed picture boundary"); + CHECK(m_subPicCtuTopLeftY[i] + m_subPicHeight[i] > (m_iSourceHeight + m_uiCTUSize - 1) / m_uiCTUSize, "subpicture must not exceed picture boundary"); + } + if (m_subPicIdPresentFlag) + { + if (m_subPicIdSignallingPresentFlag) + { + CHECK( m_subPicIdLen > 16, "sibpic ID length must not exceed 16 bits" ); + } + } + } +#endif #if JVET_P1004_REMOVE_BRICKS if( m_picPartitionFlag ) { @@ -4407,6 +4451,32 @@ void EncAppCfg::xPrintParameter() msg( DETAILS, "Profile : %s\n", profileToString(m_profile) ); } msg( DETAILS, "CU size / depth / total-depth : %d / %d / %d\n", m_uiMaxCUWidth, m_uiMaxCUDepth, m_uiMaxCodingDepth ); +#if JVET_P0171_SUBPICTURE_LAYOUT + msg(DETAILS, "subpicture present flag : %d\n", m_subPicPresentFlag); + if (m_subPicPresentFlag) + { + msg(DETAILS, "number of subpictures : %d\n", m_numSubPics); + for (int i = 0; i < m_numSubPics; i++) + { + msg(DETAILS, "[%d]th subpictures location :[%d %d]\n", i, m_subPicCtuTopLeftX[i], m_subPicCtuTopLeftY[i]); + msg(DETAILS, "[%d]th subpictures size :[%d %d]\n", i, m_subPicWidth[i], m_subPicHeight[i]); + msg(DETAILS, "[%d]th subpictures treated as picture flag :%d\n", i, m_subPicTreatedAsPicFlag[i]); + msg(DETAILS, "loop filter cross [%d]th subpictures enabled flag :%d\n", i, m_loopFilterAcrossSubpicEnabledFlag[i]); + + } + } + msg(DETAILS, "subpicture ID present flag : %d\n", m_subPicIdPresentFlag); + if (m_subPicIdPresentFlag) + { + msg(DETAILS, "subpicture ID signalling present flag : %d\n", m_subPicIdSignallingPresentFlag); + for (int i = 0; i < m_numSubPics; i++) + { + msg(DETAILS, "[%d]th subpictures ID length :%d\n", i, m_subPicIdLen); + msg(DETAILS, "[%d]th subpictures ID :%d\n", i, m_subPicId[i]); + + } + } +#endif msg( DETAILS, "Max TB size : %d \n", 1 << m_log2MaxTbSize ); msg( DETAILS, "Motion search range : %d\n", m_iSearchRange ); msg( DETAILS, "Intra period : %d\n", m_iIntraPeriod ); @@ -4460,7 +4530,7 @@ void EncAppCfg::xPrintParameter() } msg( DETAILS, "RateControl : %d\n", m_RCEnableRateControl ); - msg( DETAILS, "WPMethod : %d\n", int(m_weightedPredictionMethod)); + msg( DETAILS, "WeightedPredMethod : %d\n", int(m_weightedPredictionMethod)); if(m_RCEnableRateControl) { diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index c62a12bf194b44e6e13a2f9fdf14f98d30826c3f..10c9ab465b4fd5c5d0ebe74f6c03b4272f413f4d 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -276,6 +276,20 @@ protected: // coding unit (CU) definition unsigned m_uiCTUSize; +#if JVET_P0171_SUBPICTURE_LAYOUT + bool m_subPicPresentFlag; + unsigned m_numSubPics; + std::vector<uint32_t> m_subPicCtuTopLeftX; + std::vector<uint32_t> m_subPicCtuTopLeftY; + std::vector<uint32_t> m_subPicWidth; + std::vector<uint32_t> m_subPicHeight; + std::vector<uint32_t> m_subPicTreatedAsPicFlag; + std::vector<uint32_t> m_loopFilterAcrossSubpicEnabledFlag; + bool m_subPicIdPresentFlag; + bool m_subPicIdSignallingPresentFlag; + unsigned m_subPicIdLen; + std::vector<uint32_t> m_subPicId; +#endif bool m_SplitConsOverrideEnabledFlag; unsigned m_uiMinQT[3]; // 0: I slice luma; 1: P/B slice; 2: I slice chroma unsigned m_uiMaxMTTHierarchyDepth; diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp index bd39a4649e9a3b14b8d42e7c1f9f758dcb80055f..47837fe03ddd216a398b0930cd95e0267b59a898 100644 --- a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp +++ b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp @@ -962,6 +962,8 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfParam& alfParam, ChannelType chann for( int classIdx = 0; classIdx < numClasses; classIdx++ ) { int filterIdx = alfParam.filterCoeffDeltaIdx[classIdx]; + + CHECK(!(filterIdx >= 0 && filterIdx < alfParam.numLumaFilters), "Bad coeff delta idx in ALF"); for (int coeffIdx = 0; coeffIdx < numCoeffMinus1; ++coeffIdx) { m_coeffFinal[classIdx * MAX_NUM_ALF_LUMA_COEFF + coeffIdx] = coeff[filterIdx * MAX_NUM_ALF_LUMA_COEFF + coeffIdx]; @@ -970,8 +972,9 @@ void AdaptiveLoopFilter::reconstructCoeff( AlfParam& alfParam, ChannelType chann m_clippFinal[classIdx* MAX_NUM_ALF_LUMA_COEFF + numCoeffMinus1] = isRdo ? 0 : m_alfClippingValues[channel][0]; for( int coeffIdx = 0; coeffIdx < numCoeffMinus1; ++coeffIdx ) { - int clipIdx = alfParam.nonLinearFlag[channel][altIdx] ? (clipp + filterIdx * MAX_NUM_ALF_LUMA_COEFF)[coeffIdx] : 0; - (m_clippFinal + classIdx * MAX_NUM_ALF_LUMA_COEFF)[coeffIdx] = isRdo ? clipIdx : m_alfClippingValues[channel][clipIdx]; + int clipIdx = alfParam.nonLinearFlag[channel][altIdx] ? clipp[filterIdx * MAX_NUM_ALF_LUMA_COEFF + coeffIdx] : 0; + CHECK(!(clipIdx >= 0 && clipIdx < MaxAlfNumClippingValues), "Bad clip idx in ALF"); + m_clippFinal[classIdx * MAX_NUM_ALF_LUMA_COEFF + coeffIdx] = isRdo ? clipIdx : m_alfClippingValues[channel][clipIdx]; } m_clippFinal[classIdx* MAX_NUM_ALF_LUMA_COEFF + numCoeffMinus1] = isRdo ? 0 : diff --git a/source/Lib/CommonLib/HRD.h b/source/Lib/CommonLib/HRD.h index 03b1cb81e66067852fa45273a09cfdbbe6e680ba..3a208e495ff6260678a0c4527343d8056e22cde0 100644 --- a/source/Lib/CommonLib/HRD.h +++ b/source/Lib/CommonLib/HRD.h @@ -44,7 +44,6 @@ protected: bool m_timingInfoPresentFlag; uint32_t m_numUnitsInTick; uint32_t m_timeScale; - bool m_pocProportionalToTimingFlag; int m_numTicksPocDiffOneMinus1; public: @@ -52,7 +51,6 @@ public: : m_timingInfoPresentFlag (false) , m_numUnitsInTick (1001) , m_timeScale (60000) - , m_pocProportionalToTimingFlag(false) , m_numTicksPocDiffOneMinus1 (0) {} @@ -64,9 +62,6 @@ public: void setTimeScale( uint32_t value ) { m_timeScale = value; } uint32_t getTimeScale( ) const { return m_timeScale; } - void setPocProportionalToTimingFlag(bool x) { m_pocProportionalToTimingFlag = x; } - bool getPocProportionalToTimingFlag( ) const { return m_pocProportionalToTimingFlag; } - void setNumTicksPocDiffOneMinus1(int x) { m_numTicksPocDiffOneMinus1 = x; } int getNumTicksPocDiffOneMinus1( ) const { return m_numTicksPocDiffOneMinus1; } }; diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp index 680fca6ab5c4b567c932d5cd9984b6cff38343fa..4eff8f058f0b24e909f81be2dba903e9f5b3447c 100644 --- a/source/Lib/CommonLib/LoopFilter.cpp +++ b/source/Lib/CommonLib/LoopFilter.cpp @@ -757,7 +757,7 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De } const TransformUnit& tuQ = *cuQ.cs->getTU(posQ, cuQ.chType); - const TransformUnit& tuP = *cuP.cs->getTU(posP, cuQ.chType); //based on chType of the current cu, because cuQ.chType and cuP.chType are not the same when local dual-tree is applied + const TransformUnit& tuP = *cuP.cs->getTU(posP, cuQ.chType); const PreCalcValues& pcv = *cu.cs->pcv; const unsigned rasterIdx = getRasterIdx( Position{ localPos.x, localPos.y }, pcv ); if (m_aapucBS[edgeDir][rasterIdx] && (cuP.firstPU->ciipFlag || cuQ.firstPU->ciipFlag)) @@ -1283,7 +1283,7 @@ void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir ed { const CodingUnit& cuQ = cu; CodingUnit& cuP1 = *cu.cs->getCU( recalcPosition( cu.chromaFormat, CHANNEL_TYPE_LUMA, cu.chType, pos.offset( xoffset - uiNumPelsLuma, yoffset - uiNumPelsLuma ) ), cu.chType ); - CodingUnit& cuP = *cu.cs->getCU( recalcPosition( cu.chromaFormat, CHANNEL_TYPE_LUMA, ((!cuP1.cs->pcv->ISingleTree && cuP1.slice->isIntra()) ? CHANNEL_TYPE_CHROMA : cu.chType), pos.offset( xoffset - uiNumPelsLuma, yoffset - uiNumPelsLuma ) ), ((!cuP1.cs->pcv->ISingleTree && cuP1.slice->isIntra()) ? CHANNEL_TYPE_CHROMA : cu.chType)); + CodingUnit& cuP = *cu.cs->getCU( recalcPosition( cu.chromaFormat, CHANNEL_TYPE_LUMA, (cuP1.isSepTree() ? CHANNEL_TYPE_CHROMA : cu.chType), pos.offset( xoffset - uiNumPelsLuma, yoffset - uiNumPelsLuma ) ), (cuP1.isSepTree() ? CHANNEL_TYPE_CHROMA : cu.chType)); if (edgeDir == EDGE_VER) { @@ -1365,13 +1365,16 @@ void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir ed Pel* piTmpSrcChroma = (chromaIdx == 0) ? piTmpSrcCb : piTmpSrcCr; #if JVET_P1001_DEBLOCKING_CHROMAQP_FIX - int shiftHor = cu.Y().valid() ? 0 : ::getComponentScaleX(COMPONENT_Cb, cu.firstPU->chromaFormat); - int shiftVer = cu.Y().valid() ? 0 : ::getComponentScaleY(COMPONENT_Cb, cu.firstPU->chromaFormat); - const Position& posQ = Position{ pos.x >> shiftHor, pos.y >> shiftVer }; - const Position posP = (edgeDir == EDGE_VER) ? posQ.offset(-1, 0) : posQ.offset(0, -1); + int shiftHorP = cuP.Y().valid() ? 0 : ::getComponentScaleX(COMPONENT_Cb, cuP.firstPU->chromaFormat); + int shiftVerP = cuP.Y().valid() ? 0 : ::getComponentScaleY(COMPONENT_Cb, cuP.firstPU->chromaFormat); + int shiftHorQ = cuQ.Y().valid() ? 0 : ::getComponentScaleX(COMPONENT_Cb, cuQ.firstPU->chromaFormat); + int shiftVerQ = cuQ.Y().valid() ? 0 : ::getComponentScaleY(COMPONENT_Cb, cuQ.firstPU->chromaFormat); + const Position& posQ = Position{ pos.x >> shiftHorQ, pos.y >> shiftVerQ }; + const Position& posP1 = Position{ pos.x >> shiftHorP, pos.y >> shiftVerP }; + const Position posP = (edgeDir == EDGE_VER) ? posP1.offset(-1, 0) : posP1.offset(0, -1); const TransformUnit& tuQ = *cuQ.cs->getTU(posQ, cuQ.chType); - const TransformUnit& tuP = *cuP.cs->getTU(posP, cuQ.chType); //based on chType of the current cu, because cuQ.chType and cuP.chType are not the same when local dual-tree is applied + const TransformUnit& tuP = *cuP.cs->getTU(posP, cuP.chType); const QpParam cQP(tuP, ComponentID(chromaIdx + 1)); const QpParam cQQ(tuQ, ComponentID(chromaIdx + 1)); diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index 4505f3b7a67a5e9a91467a175f00f49ee6b13a38..867294cdd793ae04d4a9f90f78f1b5723e7a9a1a 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -309,6 +309,10 @@ public: int* m_spliceIdx; int m_ctuNums; +#if JVET_P0184 + bool interLayerRefPicFlag; +#endif + #if ENABLE_SPLIT_PARALLELISM PelStorage m_bufs[PARL_SPLIT_MAX_NUM_JOBS][NUM_PIC_TYPES]; #else diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 6baa4e0837cc1e4933ab6e49234ef0b0f23f1953..7dccc3b23c4f745371add4ce66ff41721c28fa30 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -2313,14 +2313,22 @@ SPS::~SPS() void SPS::createRPLList0(int numRPL) { m_RPLList0.destroy(); +#if FIELD_CODING_FIX + m_RPLList0.create(numRPL); +#else m_RPLList0.create(numRPL + 1); +#endif m_numRPL0 = numRPL; m_rpl1IdxPresentFlag = (m_numRPL0 != m_numRPL1) ? true : false; } void SPS::createRPLList1(int numRPL) { m_RPLList1.destroy(); +#if FIELD_CODING_FIX + m_RPLList1.create(numRPL); +#else m_RPLList1.create(numRPL + 1); +#endif m_numRPL1 = numRPL; m_rpl1IdxPresentFlag = (m_numRPL0 != m_numRPL1) ? true : false; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 33deec4a0eb409be14d9970b5eef0bacd435871e..1936308a0b54d47bce1c126b0423fdc20239cf67 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,10 @@ #include <assert.h> #include <cassert> +#define FIELD_CODING_FIX 1 // Fix field coding + +#define JVET_P0135_VPS_DIRECT_DEPEN_FLAG_CONSRAINT 1 // JVET-P0135: add constraint on vps_direct_dependency_flag[ i ][ j ], when vps_independent_layer_flag[ i ] is equal to 0 + #define JVET_P1024_SINGLE_SLICE_PER_SUBPIC_FLAG 1 // JVET-P1024: single_slice_per_subpic_flag in the PPS #define JVET_P1038_ALF_PAD_RASTER_SLICE 1 // JVET-P1038, handle ALF padding in raster scan slice @@ -283,6 +287,10 @@ #define JVET_P0185 1 // Infer vps_max_layers_minus1 to be equal to 0 when not present and also signal vps_max_sub_layers_minus1 +#define JVET_P0182 1 // JVET-P0182: Check to verify if vps_independent_layer_flag[layer_id] is true, then inter_layer_pics_present_flag must be false + +#define JVET_P0184 1 //JVET-P0184: Decoding process for generating unavailable reference pictures + #define JVET_P0597_GCMP_SEI 1 // JVET-P0597: generalized cubemap projection SEI message #define HEVC_SEI 0 // SEI messages that are defined in HEVC, but not in VVC diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 7d9e41875f4903781003fcc39c2ec270bd7df661..e98ef17a2a34bc61afb7ac217cc2eaa3901130b1 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -837,10 +837,18 @@ void DecLib::xCreateLostPicture(int iLostPoc) } #if JVET_N0278_FIXES -void DecLib::xCreateUnavailablePicture( int iUnavailablePoc, bool longTermFlag, const int layerId ) +#if JVET_P0184 +void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const int layerId, const bool interLayerRefPicFlag) +#else +void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const int layerId) +#endif +#else +#if JVET_P0184 +void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const bool interLayerRefPicFlag) #else void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag) #endif +#endif { msg(INFO, "\ninserting unavailable poc : %d\n", iUnavailablePoc); #if JVET_N0278_FIXES @@ -861,6 +869,9 @@ void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag) // for(int ctuRsAddr=0; ctuRsAddr<cFillPic->getNumberOfCtusInFrame(); ctuRsAddr++) { cFillPic->getCtu(ctuRsAddr)->initCtu(cFillPic, ctuRsAddr); } cFillPic->referenced = true; +#if JVET_P0184 + cFillPic->interLayerRefPicFlag = interLayerRefPicFlag; +#endif cFillPic->longTerm = longTermFlag; cFillPic->slices[0]->setPOC(iUnavailablePoc); #if !JVET_P1006_PICTURE_HEADER @@ -1599,9 +1610,23 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl if ( ( (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) ) && m_apcSlicePilot->getNoIncorrectPicOutputFlag() ) { #if JVET_N0278_FIXES - xCreateUnavailablePicture( lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getPic()->layerId ); +#if JVET_P0184 + if (m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex) == 0) + { + xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex)); + } +#else + xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getPic()->layerId); +#endif +#else +#if JVET_P0184 + if (m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex) == 0) + { + xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getRPL0()->isInterLayerRefPic(refPicIndex)); + } #else xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL0()->isRefPicLongterm(refPicIndex)); +#endif #endif } else @@ -1618,9 +1643,23 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl if (((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) || (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)) && m_apcSlicePilot->getNoIncorrectPicOutputFlag()) { #if JVET_N0278_FIXES - xCreateUnavailablePicture( lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm( refPicIndex ), m_apcSlicePilot->getPic()->layerId ); +#if JVET_P0184 + if (m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex) == 0) + { + xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getPic()->layerId, m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex)); + } +#else + xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getPic()->layerId); +#endif +#else +#if JVET_P0184 + if (m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex) == 0) + { + xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm(refPicIndex), m_apcSlicePilot->getRPL1()->isInterLayerRefPic(refPicIndex)); + } #else xCreateUnavailablePicture(lostPoc - 1, m_apcSlicePilot->getRPL1()->isRefPicLongterm(refPicIndex)); +#endif #endif } else diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index 113d421847faa0a5c0dfeeddbad53a0d6818b8dd..1ddda78d6f7182e1f8a72e7cec81f50ce32c6e49 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -219,12 +219,20 @@ protected: #if JVET_N0278_FIXES Picture * xGetNewPicBuffer( const SPS &sps, const PPS &pps, const uint32_t temporalLayer, const int layerId ); void xCreateLostPicture( int iLostPOC, const int layerId ); - void xCreateUnavailablePicture( int iUnavailablePoc, bool longTermFlag, const int layerId ); +#if JVET_P0184 + void xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const int layerId, const bool interLayerRefPicFlag); +#else + void xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const int layerId); +#endif void xActivateParameterSets( const int layerId ); #else Picture * xGetNewPicBuffer(const SPS &sps, const PPS &pps, const uint32_t temporalLayer); void xCreateLostPicture (int iLostPOC); +#if JVET_P0184 + void xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag, const bool interLayerRefPicFlag); +#else void xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag); +#endif void xActivateParameterSets(); #endif #if JVET_P1006_PICTURE_HEADER diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 237656a419f4d09f15cdd4e18fb036b083ad0e62..fa19885d26d2f39f6ea88f5b3f5e956763289285 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -414,7 +414,7 @@ void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl) if (!rpl->getLtrpInSliceHeaderFlag()) READ_CODE(sps->getBitsForPOC(), code, "poc_lsb_lt[listIdx][rplsIdx][j]"); #if JVET_O1159_SCALABILITY - rpl->setRefPicIdentifier( ii, deltaValue, isLongTerm, false, 0 ); + rpl->setRefPicIdentifier( ii, code, isLongTerm, false, 0 ); #else rpl->setRefPicIdentifier(ii, code, isLongTerm); #endif @@ -1524,17 +1524,18 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) #if JVET_P1006_PICTURE_HEADER #if JVET_P0171_SUBPICTURE_LAYOUT - if (pcSPS->getSubPicPresentFlag()) { + if (pcSPS->getSubPicPresentFlag()) + { READ_CODE(8, uiCode, "sps_num_subpics_minus1"); pcSPS->setNumSubPics(uiCode + 1); for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++) { - READ_CODE(ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_ctu_top_left_x[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_ctu_top_left_x[ i ]"); pcSPS->setSubPicCtuTopLeftX(picIdx, uiCode); - READ_CODE(ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_ctu_top_left_y[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_ctu_top_left_y[ i ]"); pcSPS->setSubPicCtuTopLeftY(picIdx, uiCode); - READ_CODE(ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_width_minus1[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_width_minus1[ i ]"); pcSPS->setSubPicWidth(picIdx, uiCode + 1); - READ_CODE(ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize()))), uiCode, "subpic_height_minus1[ i ]"); + READ_CODE(std::max(1, ceilLog2(((pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2(pcSPS->getCTUSize())))), uiCode, "subpic_height_minus1[ i ]"); pcSPS->setSubPicHeight(picIdx, uiCode + 1); READ_FLAG(uiCode, "subpic_treated_as_pic_flag[ i ]"); pcSPS->setSubPicTreatedAsPicFlag(picIdx, uiCode); @@ -2244,6 +2245,9 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) READ_FLAG(uiCode, "vps_independent_layer_flag"); pcVPS->setIndependentLayerFlag(i, uiCode); if (!pcVPS->getIndependentLayerFlag(i)) { +#if JVET_P0135_VPS_DIRECT_DEPEN_FLAG_CONSRAINT + uint16_t sumUiCode = 0; +#endif for (int j = 0, k = 0; j < i; j++) { READ_FLAG(uiCode, "vps_direct_dependency_flag"); pcVPS->setDirectRefLayerFlag(i, j, uiCode); @@ -2251,8 +2255,14 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) { pcVPS->setInterLayerRefIdc( i, j, k ); pcVPS->setDirectRefLayerIdx( i, k++, j ); +#if JVET_P0135_VPS_DIRECT_DEPEN_FLAG_CONSRAINT + sumUiCode++; +#endif } } +#if JVET_P0135_VPS_DIRECT_DEPEN_FLAG_CONSRAINT + CHECK(sumUiCode == 0, "There has to be at least one value of j such that the value of vps_direct_dependency_flag[ i ][ j ] is equal to 1,when vps_independent_layer_flag[ i ] is equal to 0 "); +#endif } } } @@ -3473,7 +3483,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para { READ_CODE(sps->getBitsForPOC(), uiCode, "slice_poc_lsb_lt[i][j]"); #if JVET_O1159_SCALABILITY - pcSlice->getLocalRPL0()->setRefPicIdentifier( i, uiCode, true, false, 0 ); + pcSlice->getLocalRPL1()->setRefPicIdentifier( i, uiCode, true, false, 0 ); #else pcSlice->getLocalRPL1()->setRefPicIdentifier(i, uiCode, true); #endif @@ -4615,6 +4625,8 @@ void HLSyntaxReader::decodeScalingList(ScalingList *scalingList, uint32_t sizeId int PredListId = scalingList->getRefMatrixId(scalingListId); CHECK(isPredictor && PredListId > scalingListId, "Scaling List error predictor!"); const int *srcPred = (isPredictor) ? ((scalingListId == PredListId) ? scalingList->getScalingListDefaultAddress(scalingListId) : scalingList->getScalingListAddress(PredListId)) : NULL; + if(isPredictor && scalingListId == PredListId) + scalingList->setScalingListDC(PredListId, SCALING_LIST_DC); int predCoef = 0; if (scalingListId >= SCALING_LIST_1D_START_16x16) diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 20290948737ab93fc93c01a575032db0adff8c45..47f5b79d55cbe2fe09e1238b15114c082da25193 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -273,6 +273,20 @@ protected: int m_maxTempLayer; ///< Max temporal layer unsigned m_CTUSize; +#if JVET_P0171_SUBPICTURE_LAYOUT + bool m_subPicPresentFlag; + unsigned m_numSubPics; + uint32_t m_subPicCtuTopLeftX[MAX_NUM_SUB_PICS]; + uint32_t m_subPicCtuTopLeftY[MAX_NUM_SUB_PICS]; + uint32_t m_subPicWidth[MAX_NUM_SUB_PICS]; + uint32_t m_subPicHeight[MAX_NUM_SUB_PICS]; + uint32_t m_subPicTreatedAsPicFlag[MAX_NUM_SUB_PICS]; + uint32_t m_loopFilterAcrossSubpicEnabledFlag[MAX_NUM_SUB_PICS]; + bool m_subPicIdPresentFlag; + bool m_subPicIdSignallingPresentFlag; + unsigned m_subPicIdLen; + uint32_t m_subPicId[MAX_NUM_SUB_PICS]; +#endif bool m_useSplitConsOverride; unsigned m_uiMinQT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma unsigned m_uiMaxMTTHierarchyDepth; @@ -1024,7 +1038,11 @@ public: } const RPLEntry &getRPLEntry(int L01, int idx) const { return (L01 == 0) ? m_RPLList0[idx] : m_RPLList1[idx]; } int getRPLCandidateSize(int L01) const { return (L01 == 0) ? m_numRPLList0 : m_numRPLList1; } +#if FIELD_CODING_FIX + void setEncodedFlag(uint32_t i, bool value) { m_RPLList0[i].m_isEncoded = value; m_RPLList1[i].m_isEncoded = value; m_GOPList[i].m_isEncoded = value; } +#else void setEncodedFlag(uint32_t i, bool value) { m_RPLList0[i].m_isEncoded = value; m_RPLList1[i].m_isEncoded = value; } +#endif void setMaxDecPicBuffering ( uint32_t u, uint32_t tlayer ) { m_maxDecPicBuffering[tlayer] = u; } void setNumReorderPics ( int i, uint32_t tlayer ) { m_numReorderPics[tlayer] = i; } void setDrapPeriod (int drapPeriod) { m_drapPeriod = drapPeriod; } @@ -1056,7 +1074,33 @@ public: bool getUseSplitConsOverride () const { return m_useSplitConsOverride; } void setDualITree ( bool b ) { m_dualITree = b; } bool getDualITree () const { return m_dualITree; } - +#if JVET_P0171_SUBPICTURE_LAYOUT + void setSubPicPresentFlag (bool b) { m_subPicPresentFlag = b; } + void setNumSubPics (uint32_t u) { m_numSubPics = u; } + void setSubPicCtuTopLeftX (uint32_t u, int i) { m_subPicCtuTopLeftX[i] = u; } + void setSubPicCtuTopLeftY (uint32_t u, int i) { m_subPicCtuTopLeftY[i] = u; } + void setSubPicWidth (uint32_t u, int i) { m_subPicWidth[i] = u; } + void setSubPicHeight (uint32_t u, int i) { m_subPicHeight[i] = u; } + void setSubPicTreatedAsPicFlag (bool b, int i) { m_subPicTreatedAsPicFlag[i] = b; } + void setLoopFilterAcrossSubpicEnabledFlag (uint32_t u, int i) { m_loopFilterAcrossSubpicEnabledFlag[i] = u; } + void setSubPicIdPresentFlag (bool b) { m_subPicIdPresentFlag = b; } + void setSubPicIdSignallingPresentFlag (bool b) { m_subPicIdSignallingPresentFlag = b; } + void setSubPicIdLen (uint32_t u) { m_subPicIdLen = u; } + void setSubPicId (uint32_t b, int i) { m_subPicId[i] = b; } + + bool getSubPicPresentFlag () { return m_subPicPresentFlag; } + uint32_t getNumSubPics () { return m_numSubPics; } + uint32_t getSubPicCtuTopLeftX (int i) { return m_subPicCtuTopLeftX[i]; } + uint32_t getSubPicCtuTopLeftY (int i) { return m_subPicCtuTopLeftY[i]; } + uint32_t getSubPicWidth (int i) { return m_subPicWidth[i]; } + uint32_t getSubPicHeight (int i) { return m_subPicHeight[i]; } + bool getSubPicTreatedAsPicFlag (int i) { return m_subPicTreatedAsPicFlag[i]; } + uint32_t getLoopFilterAcrossSubpicEnabledFlag (int i) { return m_loopFilterAcrossSubpicEnabledFlag[i]; } + bool getSubPicIdPresentFlag () { return m_subPicIdPresentFlag; } + bool getSubPicIdSignallingPresentFlag () { return m_subPicIdSignallingPresentFlag; } + uint32_t getSubPicIdLen () { return m_subPicIdLen; } + uint32_t getSubPicId (int i) { return m_subPicId[i]; } +#endif void setLFNST ( bool b ) { m_LFNST = b; } bool getLFNST() const { return m_LFNST; } void setUseFastLFNST ( bool b ) { m_useFastLFNST = b; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index bfd9ac42e22847205b634de68dc2f116b45db51d..c33a5042eaac498e5d190ce3d2cdc2d5ceee1038 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -414,6 +414,32 @@ int EncGOP::xWriteParameterSets( AccessUnit &accessUnit, Slice *slice, const boo { actualTotalBits += xWritePPS( accessUnit, slice->getPPS(), slice->getSPS(), m_pcEncLib->getLayerId() ); } +#else + if (bSeqFirst) + { +#if JVET_P0205_VPS_ID_0 + if (slice->getSPS()->getVPSId() != 0) + { + actualTotalBits += xWriteVPS(accessUnit, m_pcEncLib->getVPS()); + } +#else + actualTotalBits += xWriteVPS(accessUnit, m_pcEncLib->getVPS()); +#endif + } + if (bSeqFirst) + { + actualTotalBits += xWriteDPS(accessUnit, m_pcEncLib->getDPS()); + } + + if (m_pcEncLib->SPSNeedsWriting(slice->getSPS()->getSPSId())) // Note this assumes that all changes to the SPS are made at the EncLib level prior to picture creation (EncLib::xGetNewPicBuffer). + { + CHECK(!(bSeqFirst), "Unspecified error"); // Implementations that use more than 1 SPS need to be aware of activation issues. + actualTotalBits += xWriteSPS(accessUnit, slice->getSPS()); + } + if (m_pcEncLib->PPSNeedsWriting(slice->getPPS()->getPPSId())) // Note this assumes that all changes to the PPS are made at the EncLib level prior to picture creation (EncLib::xGetNewPicBuffer). + { + actualTotalBits += xWritePPS(accessUnit, slice->getPPS(), slice->getSPS()); + } #endif return actualTotalBits; @@ -2198,6 +2224,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } #if JVET_N0278_FIXES +#if FIELD_CODING_FIX + if( isField && picIdInGOP == 0 ) + { + for( int iGOPid = 0; iGOPid < max(2, m_iGopSize); iGOPid++ ) + { + m_pcCfg->setEncodedFlag( iGOPid, false ); + } + } +#endif for( int iGOPid = picIdInGOP; iGOPid <= picIdInGOP; iGOPid++ ) { // reset flag indicating whether pictures have been encoded @@ -3892,7 +3927,11 @@ void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const boo m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits()); // prior to the above statement, the interlace analyser does not contain the correct total number of bits. +#if FIELD_CODING_FIX + msg( INFO,"\n\nSUMMARY INTERLACED ---------------------------------------------\n" ); +#else msg( DETAILS,"\n\nSUMMARY INTERLACED ---------------------------------------------\n" ); +#endif #if ENABLE_QPA m_gcAnalyzeAll_in.printOut( 'a', chFmt, printMSEBasedSNR, printSequenceMSE, printHexPsnr, printRprPSNR, bitDepths, useWPSNR ); #else @@ -4910,7 +4949,11 @@ void EncGOP::xCalculateInterlacedAddPSNR( Picture* pcPicOrgFirstField, Picture* *PSNR_Y = dPSNR[COMPONENT_Y]; - msg( DETAILS, "\n Interlaced frame %d: [Y %6.4lf dB U %6.4lf dB V %6.4lf dB]", pcPicOrgSecondField->getPOC()/2 , dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] ); +#if FIELD_CODING_FIX + msg( INFO, "\n Interlaced frame %d: [Y %6.4lf dB U %6.4lf dB V %6.4lf dB]", pcPicOrgSecondField->getPOC()/2, dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] ); +#else + msg( DETAILS, "\n Interlaced frame %d: [Y %6.4lf dB U %6.4lf dB V %6.4lf dB]", pcPicOrgSecondField->getPOC()/2, dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] ); +#endif if (printFrameMSE) { msg( DETAILS, " [Y MSE %6.4lf U MSE %6.4lf V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] ); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 53c734c219f9122192aea730515251e92bcffd54..3c4601098bc66291c5802ebd7110714029583c45 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1107,6 +1107,16 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicY compBuf.width, compBuf.height, isTopField ); +#if FIELD_CODING_FIX + // to get fields of true original buffer to avoid wrong PSNR calculation in summary + compBuf = pcPicYuvTrueOrg->get( compID ); + separateFields( compBuf.buf, + pcField->getTrueOrigBuf().get(compID).buf, + compBuf.stride, + compBuf.width, + compBuf.height, + isTopField); +#endif } } @@ -1139,12 +1149,23 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicY } } +#if !FIELD_CODING_FIX if( m_iNumPicRcvd && ( ( flush&&fieldNum == 1 ) || ( m_iPOCLast / 2 ) == 0 || m_iNumPicRcvd == m_iGOPSize ) ) { keepDoing = false; } +#endif } +#if FIELD_CODING_FIX + if( m_iNumPicRcvd && ( flush || m_iPOCLast == 1 || m_iNumPicRcvd == m_iGOPSize ) ) + { + m_picIdInGOP = 0; + m_iPOCLast -= 2; + keepDoing = false; + } +#endif + return keepDoing; } @@ -1152,6 +1173,32 @@ bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitB { iNumEncoded = 0; +#if FIELD_CODING_FIX + for( int fieldNum = 0; fieldNum < 2; fieldNum++ ) + { + m_iPOCLast = ( m_iNumPicRcvd == m_iGOPSize ) ? m_uiNumAllPicCoded + m_iNumPicRcvd - 1 : m_iPOCLast + 1; + + // compress GOP + m_cGOPEncoder.compressGOP( m_iPOCLast, m_iPOCLast < 2 ? m_iPOCLast + 1 : m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, true, isTff, snrCSC, m_printFrameMSE, false, m_picIdInGOP ); +#if JVET_O0756_CALCULATE_HDRMETRICS + m_metricTime = m_cGOPEncoder.getMetricTime(); +#endif + + m_picIdInGOP++; + } + + // go over all pictures in a GOP excluding first top field and first bottom field + if( m_picIdInGOP != m_iGOPSize && m_iPOCLast > 1 ) + { + return true; + } + + iNumEncoded += m_iNumPicRcvd; + m_uiNumAllPicCoded += m_iNumPicRcvd; + m_iNumPicRcvd = 0; + + return false; +#else for( int fieldNum = 0; fieldNum < 2; fieldNum++ ) { // compress GOP @@ -1174,6 +1221,7 @@ bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitB } return false; +#endif } #else void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, @@ -1202,6 +1250,16 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTr compBuf.width, compBuf.height, isTopField); +#if FIELD_CODING_FIX + // to get fields of true original buffer to avoid wrong PSNR calculation in summary + compBuf = pcPicYuvTrueOrg->get( compID ); + separateFields( compBuf.buf, + pcField->getTrueOrigBuf().get(compID).buf, + compBuf.stride, + compBuf.width, + compBuf.height, + isTopField); +#endif } } @@ -1261,7 +1319,7 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTr */ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Picture*& rpcPic, int ppsId ) { - // rotate he output buffer + // rotate the output buffer rcListPicYuvRecOut.push_back( rcListPicYuvRecOut.front() ); rcListPicYuvRecOut.pop_front(); rpcPic=0; @@ -1686,20 +1744,33 @@ void EncLib::xInitSPS(SPS &sps) #if JVET_P1006_PICTURE_HEADER #if JVET_P0171_SUBPICTURE_LAYOUT - for (int picIdx = 0; picIdx < MAX_NUM_SUB_PICS; picIdx++) { - sps.setSubPicCtuTopLeftX(picIdx, 0); - sps.setSubPicCtuTopLeftY(picIdx, 0); - sps.setSubPicWidth(picIdx, ((sps.getMaxPicWidthInLumaSamples() + sps.getCTUSize() - 1) >> floorLog2(sps.getCTUSize()))); - sps.setSubPicHeight(picIdx, ((sps.getMaxPicHeightInLumaSamples() + sps.getCTUSize() - 1) >> floorLog2(sps.getCTUSize()))); - sps.setSubPicTreatedAsPicFlag(picIdx, 0); - sps.setLoopFilterAcrossSubpicEnabledFlag(picIdx, 1); + sps.setSubPicPresentFlag(m_subPicPresentFlag); + if (m_subPicPresentFlag) + { + sps.setNumSubPics(m_numSubPics); + for (int i = 0; i < m_numSubPics; i++) + { + sps.setSubPicCtuTopLeftX(i, m_subPicCtuTopLeftX[i] ); + sps.setSubPicCtuTopLeftY(i, m_subPicCtuTopLeftY[i]); + sps.setSubPicWidth(i, m_subPicWidth[i]); + sps.setSubPicHeight(i, m_subPicHeight[i]); + sps.setSubPicTreatedAsPicFlag(i, m_subPicTreatedAsPicFlag[i]); + sps.setLoopFilterAcrossSubpicEnabledFlag(i, m_loopFilterAcrossSubpicEnabledFlag[i]); + } } #endif - sps.setSubPicIdSignallingPresentFlag(false); - sps.setSubPicIdLen(16); - for(int picIdx=0; picIdx<MAX_NUM_SUB_PICS; picIdx++) + sps.setSubPicIdPresentFlag(m_subPicIdPresentFlag); + if (m_subPicIdPresentFlag) + { + sps.setSubPicIdSignallingPresentFlag(m_subPicIdSignallingPresentFlag); + if (m_subPicIdSignallingPresentFlag) + { + sps.setSubPicIdLen(m_subPicIdLen); + for (int i = 0; i < m_numSubPics; i++) { - sps.setSubPicId(picIdx, picIdx); + sps.setSubPicId(i, m_subPicId[i]); + } + } } sps.setLoopFilterAcrossVirtualBoundariesDisabledFlag( m_loopFilterAcrossVirtualBoundariesDisabledFlag ); @@ -1717,6 +1788,13 @@ void EncLib::xInitSPS(SPS &sps) #if JVET_O1159_SCALABILITY sps.setInterLayerPresentFlag( vps.getMaxLayers() > 1 && !vps.getAllIndependentLayersFlag() ); +#if JVET_P0182 + for (unsigned int i = 0; i < vps.getMaxLayers(); ++i) + { + CHECK((vps.getIndependentLayerFlag(i) == 1) && (sps.getInterLayerPresentFlag() != 0), " When vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id ]] is equal to 1, the value of inter_layer_ref_pics_present_flag shall be equal to 0."); + } +#endif + sps.setRprEnabledFlag( m_rprEnabled || sps.getInterLayerPresentFlag() ); #elif JVET_P0590_SCALING_WINDOW sps.setRprEnabledFlag( m_rprEnabled ); @@ -2186,8 +2264,14 @@ void EncLib::xInitRPL(SPS &sps, bool isFieldCoding) ReferencePictureList* rpl; int numRPLCandidates = getRPLCandidateSize(0); +#if FIELD_CODING_FIX + // To allocate one additional memory for RPL of POC1 (first bottom field) which is not specified in cfg file + sps.createRPLList0(numRPLCandidates + (isFieldCoding ? 1 : 0)); + sps.createRPLList1(numRPLCandidates + (isFieldCoding ? 1 : 0)); +#else sps.createRPLList0(numRPLCandidates); sps.createRPLList1(numRPLCandidates); +#endif RPLList* rplList = 0; for (int i = 0; i < 2; i++) @@ -2218,6 +2302,28 @@ void EncLib::xInitRPL(SPS &sps, bool isFieldCoding) } } +#if FIELD_CODING_FIX + if (isFieldCoding) + { + // To set RPL of POC1 (first bottom field) which is not specified in cfg file + for (int i = 0; i < 2; i++) + { + rplList = (i == 0) ? sps.getRPLList0() : sps.getRPLList1(); + rpl = rplList->getReferencePictureList(numRPLCandidates); + rpl->setNumberOfShorttermPictures(1); + rpl->setNumberOfLongtermPictures(0); + rpl->setNumberOfActivePictures(1); + rpl->setLtrpInSliceHeaderFlag(0); +#if JVET_O1159_SCALABILITY + rpl->setRefPicIdentifier(0, 1, 0, false, 0); +#else + rpl->setRefPicIdentifier(0, 1, 0); +#endif + rpl->setPOC(0, 0); + } + } +#endif + //Check if all delta POC of STRP in each RPL has the same sign //Check RPLL0 first const RPLList* rplList0 = sps.getRPLList0(); @@ -2368,6 +2474,46 @@ void EncLib::selectReferencePictureList(Slice* slice, int POCCurr, int GOPid, in } } +#if FIELD_CODING_FIX + if (slice->getPic()->fieldPic) + { + // To set RPL index of POC1 (first bottom field) + if (POCCurr == 1) + { + slice->setRPL0idx(getRPLCandidateSize(0)); + slice->setRPL1idx(getRPLCandidateSize(0)); + } + else if (m_uiIntraPeriod < 0) + { + // To set RPL indexes for LD + int numRPLCandidates = getRPLCandidateSize(0); + if (POCCurr < numRPLCandidates - m_iGOPSize + 2) + { + slice->setRPL0idx(POCCurr + m_iGOPSize - 2); + slice->setRPL1idx(POCCurr + m_iGOPSize - 2); + } + else + { + if (POCCurr%m_iGOPSize == 0) + { + slice->setRPL0idx(m_iGOPSize - 2); + slice->setRPL1idx(m_iGOPSize - 2); + } + else if (POCCurr%m_iGOPSize == 1) + { + slice->setRPL0idx(m_iGOPSize - 1); + slice->setRPL1idx(m_iGOPSize - 1); + } + else + { + slice->setRPL0idx(POCCurr % m_iGOPSize - 2); + slice->setRPL1idx(POCCurr % m_iGOPSize - 2); + } + } + } + } +#endif + const ReferencePictureList *rpl0 = (slice->getSPS()->getRPLList0()->getReferencePictureList(slice->getRPL0idx())); const ReferencePictureList *rpl1 = (slice->getSPS()->getRPLList1()->getReferencePictureList(slice->getRPL1idx())); slice->setRPL0(rpl0); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 128572dec6bba59dbb1350506ce15c50eff55640..6bdb6490c240133c91f8f4af7543eb54a6743068 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -965,14 +965,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) #if JVET_P0126_SIGNALLING_SUBPICID WRITE_FLAG(pcSPS->getSubPicPresentFlag(), "subpics_present_flag"); #if JVET_P0171_SUBPICTURE_LAYOUT - if(pcSPS->getSubPicPresentFlag()){ + if(pcSPS->getSubPicPresentFlag()) + { WRITE_CODE(pcSPS->getNumSubPics() - 1, 8, "sps_num_subpics_minus1"); for (int picIdx = 0; picIdx < pcSPS->getNumSubPics(); picIdx++) { - WRITE_CODE( pcSPS->getSubPicCtuTopLeftX(picIdx), ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_ctu_top_left_x[ i ]" ); - WRITE_CODE( pcSPS->getSubPicCtuTopLeftY(picIdx), ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_ctu_top_left_y[ i ]" ); - WRITE_CODE( pcSPS->getSubPicWidth(picIdx) - 1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_width_minus1[ i ]" ); - WRITE_CODE( pcSPS->getSubPicHeight(picIdx) - 1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize()))), "subpic_height_minus1[ i ]" ); + WRITE_CODE( pcSPS->getSubPicCtuTopLeftX(picIdx), std::max(1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_ctu_top_left_x[ i ]" ); + WRITE_CODE( pcSPS->getSubPicCtuTopLeftY(picIdx), std::max(1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_ctu_top_left_y[ i ]" ); + WRITE_CODE( pcSPS->getSubPicWidth(picIdx) - 1, std::max(1, ceilLog2((( pcSPS->getMaxPicWidthInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_width_minus1[ i ]" ); + WRITE_CODE( pcSPS->getSubPicHeight(picIdx) - 1, std::max(1, ceilLog2((( pcSPS->getMaxPicHeightInLumaSamples() + pcSPS->getCTUSize() - 1) >> floorLog2( pcSPS->getCTUSize())))), "subpic_height_minus1[ i ]" ); WRITE_FLAG( pcSPS->getSubPicTreatedAsPicFlag(picIdx), "subpic_treated_as_pic_flag[ i ]" ); WRITE_FLAG( pcSPS->getLoopFilterAcrossSubpicEnabledFlag(picIdx), "loop_filter_across_subpic_enabled_flag[ i ]" ); }